Skip to content

Commit e1a9ae4

Browse files
fancertsbogend
authored andcommitted
mips: Fix max_mapnr being uninitialized on early stages
max_mapnr variable is utilized in the pfn_valid() method in order to determine the upper PFN space boundary. Having it uninitialized effectively makes any PFN passed to that method invalid. That in its turn causes the kernel mm-subsystem occasion malfunctions even after the max_mapnr variable is actually properly updated. For instance, pfn_valid() is called in the init_unavailable_range() method in the framework of the calls-chain on MIPS: setup_arch() +-> paging_init() +-> free_area_init() +-> memmap_init() +-> memmap_init_zone_range() +-> init_unavailable_range() Since pfn_valid() always returns "false" value before max_mapnr is initialized in the mem_init() method, any flatmem page-holes will be left in the poisoned/uninitialized state including the IO-memory pages. Thus any further attempts to map/remap the IO-memory by using MMU may fail. In particular it happened in my case on attempt to map the SRAM region. The kernel bootup procedure just crashed on the unhandled unaligned access bug raised in the __update_cache() method: > Unhandled kernel unaligned access[#1]: > CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.7.0-rc1-XXX-dirty #2056 > ... > Call Trace: > [<8011ef9c>] __update_cache+0x88/0x1bc > [<80385944>] ioremap_page_range+0x110/0x2a4 > [<80126948>] ioremap_prot+0x17c/0x1f4 > [<80711b80>] __devm_ioremap+0x8c/0x120 > [<80711e0c>] __devm_ioremap_resource+0xf4/0x218 > [<808bf244>] sram_probe+0x4f4/0x930 > [<80889d20>] platform_probe+0x68/0xec > ... Let's fix the problem by initializing the max_mapnr variable as soon as the required data is available. In particular it can be done right in the paging_init() method before free_area_init() is called since all the PFN zone boundaries have already been calculated by that time. Cc: [email protected] Signed-off-by: Serge Semin <[email protected]> Signed-off-by: Thomas Bogendoerfer <[email protected]>
1 parent 0f5cc24 commit e1a9ae4

File tree

1 file changed

+5
-7
lines changed

1 file changed

+5
-7
lines changed

arch/mips/mm/init.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,12 @@ void __init paging_init(void)
422422
(highend_pfn - max_low_pfn) << (PAGE_SHIFT - 10));
423423
max_zone_pfns[ZONE_HIGHMEM] = max_low_pfn;
424424
}
425+
426+
max_mapnr = highend_pfn ? highend_pfn : max_low_pfn;
427+
#else
428+
max_mapnr = max_low_pfn;
425429
#endif
430+
high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
426431

427432
free_area_init(max_zone_pfns);
428433
}
@@ -458,13 +463,6 @@ void __init mem_init(void)
458463
*/
459464
BUILD_BUG_ON(IS_ENABLED(CONFIG_32BIT) && (PFN_PTE_SHIFT > PAGE_SHIFT));
460465

461-
#ifdef CONFIG_HIGHMEM
462-
max_mapnr = highend_pfn ? highend_pfn : max_low_pfn;
463-
#else
464-
max_mapnr = max_low_pfn;
465-
#endif
466-
high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
467-
468466
maar_init();
469467
memblock_free_all();
470468
setup_zero_pages(); /* Setup zeroed pages. */

0 commit comments

Comments
 (0)