From 952bb322c23a85b0adf6b370126ca4ffef287c77 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Wed, 8 Apr 2026 23:26:15 +0800 Subject: [PATCH] lkl: initialize mm constants before mem_init() max_mapnr is accessed through the following call chain: mem_init() -> memblock_free_all() -> free_low_memory_core_early() -> memmap_init_reserved_pages() -> reserve_bootmem_region() -> pfn_valid() -> (pfn - ARCH_PFN_OFFSET) < max_mapnr In lkl, max_mapnr is currently initialized in mem_init(), but only after memblock_free_all() runs. This means pfn_valid() can see an uninitialized max_mapnr and incorrectly return false for pfns that should be valid. For example, reserve_bootmem_region() should mark such pages as reserved, but due to this bug it does not. Other architectures, such as riscv, x86, and arm64, initialize mm constants before mem_init() from setup_arch(). Do the equivalent for lkl by initializing max_pfn, max_low_pfn, min_low_pfn, and max_mapnr in bootmem_init(). Signed-off-by: Ruihan Li --- arch/lkl/mm/bootmem.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/lkl/mm/bootmem.c b/arch/lkl/mm/bootmem.c index d912d7accfee92..79958137971b48 100644 --- a/arch/lkl/mm/bootmem.c +++ b/arch/lkl/mm/bootmem.c @@ -46,10 +46,12 @@ void __init bootmem_init(unsigned long mem_sz) * Give all the memory to the bootmap allocator, tell it to put the * boot mem_map at the start of memory. */ - max_low_pfn = virt_to_pfn((void *)memory_end); - min_low_pfn = virt_to_pfn((void *)memory_start); memblock_add(__pa(memory_start), mem_size); + max_pfn = max_low_pfn = virt_to_pfn((void *)memory_end); + min_low_pfn = virt_to_pfn((void *)memory_start); + set_max_mapnr(max_pfn - ARCH_PFN_OFFSET); + empty_zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE); memset(empty_zero_page, 0, PAGE_SIZE); @@ -60,9 +62,6 @@ void __init bootmem_init(unsigned long mem_sz) void __init mem_init(void) { memblock_free_all(); - max_mapnr = totalram_pages(); - max_low_pfn = max_mapnr + ARCH_PFN_OFFSET; - max_pfn = max_mapnr + ARCH_PFN_OFFSET; } /*