s390/vmem: split pages when debug pagealloc is enabled
authorSven Schnelle <svens@linux.ibm.com>
Wed, 26 Jul 2023 09:10:19 +0000 (11:10 +0200)
committerHeiko Carstens <hca@linux.ibm.com>
Thu, 27 Jul 2023 11:10:56 +0000 (13:10 +0200)
Since commit bb1520d581a3 ("s390/mm: start kernel with DAT enabled")
the kernel crashes early during boot when debug pagealloc is enabled:

mem auto-init: stack:off, heap alloc:off, heap free:off
addressing exception: 0005 ilc:2 [#1] SMP DEBUG_PAGEALLOC
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 6.5.0-rc3-09759-gc5666c912155 #630
[..]
Krnl Code: 00000000001325f6ec5600248064 cgrj %r5,%r6,8,000000000013263e
           00000000001325fceb880002000c srlg %r8,%r8,2
          #0000000000132602b2210051     ipte %r5,%r1,%r0,0
          >0000000000132606b90400d1     lgr %r13,%r1
           000000000013260a41605008     la %r6,8(%r5)
           000000000013260ea7db1000     aghi %r13,4096
           0000000000132612b221006d     ipte %r6,%r13,%r0,0
           0000000000132616e3d0d0000171 lay %r13,4096(%r13)

Call Trace:
 __kernel_map_pages+0x14e/0x320
 __free_pages_ok+0x23a/0x5a8)
 free_low_memory_core_early+0x214/0x2c8
 memblock_free_all+0x28/0x58
 mem_init+0xb6/0x228
 mm_core_init+0xb6/0x3b0
 start_kernel+0x1d2/0x5a8
 startup_continue+0x36/0x40
Kernel panic - not syncing: Fatal exception: panic_on_oops

This is caused by using large mappings on machines with EDAT1/EDAT2. Add
the code to split the mappings into 4k pages if debug pagealloc is enabled
by CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT or the debug_pagealloc kernel
command line option.

Fixes: bb1520d581a3 ("s390/mm: start kernel with DAT enabled")
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/mm/vmem.c

index b26649233d124984018633396fc7df6ea4adda74..24a66670f5c3a1b788787818b5a028ce860040d5 100644 (file)
@@ -763,6 +763,8 @@ void __init vmem_map_init(void)
        if (static_key_enabled(&cpu_has_bear))
                set_memory_nx(0, 1);
        set_memory_nx(PAGE_SIZE, 1);
+       if (debug_pagealloc_enabled())
+               set_memory_4k(0, ident_map_size >> PAGE_SHIFT);
 
        pr_info("Write protected kernel read-only data: %luk\n",
                (unsigned long)(__end_rodata - _stext) >> 10);