From: "Pratyush Yadav (Google)" <[email protected]> In a future patch, mm init will use kho_scratch_overlap() for deciding the migrate type of pageblocks it initializes. The earliest user currently is free_area_init(). kho_scratch_overlap() relies on kho_scratch pointer being initialized. Introduce kho_memory_init_early() to do this.
kho_populate() would normally be a good place to do this, but unfortunately, phys_to_virt() does not work at that point on ARM64. So we need yet another initialization function. Signed-off-by: Pratyush Yadav (Google) <[email protected]> --- include/linux/kexec_handover.h | 3 +++ kernel/liveupdate/kexec_handover.c | 12 ++++++++++-- mm/mm_init.c | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index 3740c14d970d..9e961032e06b 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -37,6 +37,7 @@ void kho_remove_subtree(void *blob); int kho_retrieve_subtree(const char *name, phys_addr_t *phys, size_t *size); void kho_memory_init(void); +void kho_memory_init_early(void); void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_phys, u64 scratch_len); @@ -114,6 +115,8 @@ static inline int kho_retrieve_subtree(const char *name, phys_addr_t *phys, static inline void kho_memory_init(void) { } +static inline void kho_memory_init_early(void) { } + static inline void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_phys, u64 scratch_len) { diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c index a66f23a35389..af22086ca2d6 100644 --- a/kernel/liveupdate/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -1535,8 +1535,6 @@ static void __init kho_mem_retrieve(void) const void *fdt = kho_get_fdt(); int err; - kho_scratch = phys_to_virt(kho_in.scratch_phys); - /* * kho_get_mem_map() should always succeed. If it fails, kho_populate() * catches that and never sets kho_in.scratch_phys, which stops memory @@ -1757,6 +1755,16 @@ static __init int kho_init(void) } fs_initcall(kho_init); +void __init kho_memory_init_early(void) +{ + /* + * kho_scratch_overlap() needs kho_scratch to be initialized. It is used + * by free_area_init() on KHO boots, so initialize it early. + */ + if (kho_in.scratch_phys) + kho_scratch = phys_to_virt(kho_in.scratch_phys); +} + void __init kho_memory_init(void) { if (kho_in.scratch_phys) diff --git a/mm/mm_init.c b/mm/mm_init.c index eddc0f03a779..0675837bbfc9 100644 --- a/mm/mm_init.c +++ b/mm/mm_init.c @@ -2688,6 +2688,7 @@ void __init __weak mem_init(void) void __init mm_core_init_early(void) { + kho_memory_init_early(); hugetlb_cma_reserve(); hugetlb_bootmem_alloc(); -- 2.54.0.1032.g2f8565e1d1-goog
