kho: store incoming radix tree in kho_in

This allows other functions to also use the radix tree.

While at it, add kho_get_mem_map() helper to get the virtual address of
the preserved memory map and use that helper instead of duplicating the
code to get the preserved memory map from the FDT.

Signed-off-by: Pratyush Yadav (Google) <pratyush@kernel.org>
Link: https://patch.msgid.link/20260801084833.1897543-6-pratyush@kernel.org
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
This commit is contained in:
Pratyush Yadav (Google) 2026-08-01 10:48:14 +02:00 committed by Mike Rapoport (Microsoft)
parent 955409ba57
commit e228b380cd

View File

@ -527,6 +527,13 @@ static phys_addr_t __init kho_get_mem_map_phys(const void *fdt)
return get_unaligned((const u64 *)mem_ptr);
}
static void __init *kho_get_mem_map(const void *fdt)
{
phys_addr_t phys = kho_get_mem_map_phys(fdt);
return phys ? phys_to_virt(phys) : NULL;
}
/*
* With KHO enabled, memory can become fragmented because KHO regions may
* be anywhere in physical address space. The scratch regions give us a
@ -1332,6 +1339,7 @@ struct kho_in {
char previous_release[__NEW_UTS_LEN + 1];
u32 kexec_count;
struct kho_debugfs dbg;
struct kho_radix_tree radix_tree;
};
static struct kho_in kho_in = {
@ -1411,24 +1419,20 @@ EXPORT_SYMBOL_GPL(kho_retrieve_subtree);
static int __init kho_mem_retrieve(const void *fdt)
{
struct kho_radix_tree tree;
const phys_addr_t *mem;
int len;
void *mem_map = kho_get_mem_map(fdt);
/* Retrieve the KHO radix tree from passed-in FDT. */
mem = fdt_getprop(fdt, 0, KHO_FDT_MEMORY_MAP_PROP_NAME, &len);
if (!mem || len != sizeof(*mem)) {
pr_err("failed to get preserved KHO memory tree\n");
return -ENOENT;
}
if (!*mem)
/*
* kho_get_mem_map() should always succeed. If it fails, kho_populate()
* catches that and never sets kho_in.scratch_phys, which stops memory
* retrieval.
*/
if (WARN_ON(!mem_map))
return -EINVAL;
tree.root = phys_to_virt(*mem);
mutex_init(&tree.lock);
return kho_radix_walk_tree(&tree, kho_preserved_memory_reserve);
kho_in.radix_tree.root = mem_map;
mutex_init(&kho_in.radix_tree.lock);
return kho_radix_walk_tree(&kho_in.radix_tree,
kho_preserved_memory_reserve);
}
static __init int kho_out_fdt_setup(void)
@ -1635,8 +1639,10 @@ void __init kho_memory_init(void)
if (kho_in.scratch_phys) {
kho_scratch = phys_to_virt(kho_in.scratch_phys);
if (kho_mem_retrieve(kho_get_fdt()))
if (kho_mem_retrieve(kho_get_fdt())) {
kho_in.fdt_phys = 0;
kho_in.radix_tree.root = NULL;
}
} else {
kho_reserve_scratch();
}