diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c index e7451743b87e..5c35c11c273b 100644 --- a/kernel/liveupdate/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -512,19 +512,24 @@ static int __init kho_preserved_memory_reserve(unsigned long key) return 0; } -/* Returns physical address of the preserved memory map from FDT */ -static phys_addr_t __init kho_get_mem_map_phys(const void *fdt) +/* Returns virtual address of the preserved memory map from FDT */ +static __init void *kho_get_mem_map(const void *fdt) { const void *mem_ptr; + phys_addr_t mem_map_phys; int len; mem_ptr = fdt_getprop(fdt, 0, KHO_FDT_MEMORY_MAP_PROP_NAME, &len); if (!mem_ptr || len != sizeof(u64)) { pr_err("failed to get preserved memory map\n"); - return 0; + return NULL; } - return get_unaligned((const u64 *)mem_ptr); + mem_map_phys = get_unaligned((const u64 *)mem_ptr); + if (!mem_map_phys) + return NULL; + + return phys_to_virt(mem_map_phys); } /* @@ -1647,9 +1652,8 @@ void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len, { unsigned int scratch_cnt = scratch_len / sizeof(*kho_scratch); struct kho_scratch *scratch = NULL; - phys_addr_t mem_map_phys; - void *fdt = NULL; bool populated = false; + void *fdt = NULL; int err; /* Validate the input FDT */ @@ -1671,8 +1675,13 @@ void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len, goto unmap_fdt; } - mem_map_phys = kho_get_mem_map_phys(fdt); - if (!mem_map_phys) + /* + * At this point phys_to_virt() doesn't work properly and so + * kho_get_mem_map() can return a pre-KASLR virtual address. But here we + * only want to make sure the mem_map is valid so the actual value + * doesn't matter as long as it isn't NULL. + */ + if (!kho_get_mem_map(fdt)) goto unmap_fdt; scratch = early_memremap(scratch_phys, scratch_len);