C Christophe Leroy #
Hi Maxime, Le 03/12/2021 à 01:44, Maxime Bizon a écrit :
Hello Christophe, I have a mpc8347 board booting 5.15 fine, but it does not boot with CONFIG_DEBUG_PAGEALLOC=y (and enabled) or "nobats". Those two options worked fine on my previous kernel (5.4) Nothing is output on serial console when I set those options, so I had to hack a bit: 1) to ease debugging, I used mem=256M, so only a few BATs are used 2) I hijacked BAT 7 and the vm space at b000xxxx (modules, unused for me) to set a constant mapping so my uart always works (patch attached in case) I got this: mmu_mapin_ram: base:0x0 top:0x10000000 border:0x600000 mmu_mapin_ram: updated base:0x0 top:0x600000 setbat index=0 virt=0xc0000000 phys=0x0 size=0x400000 setbat index=1 virt=0xc0400000 phys=0x400000 size=0x200000 [ 0.000000] kernel tried to execute exec-protected page (c0600944) - exploit attempt? (uid: 0) [ 0.000000] BUG: Unable to handle kernel instruction fetch [ 0.000000] Faulting instruction address: 0xc0600944 [ 0.000000] Thread overran stack, or stack corrupted [ 0.000000] Oops: Kernel access of bad area, sig: 11 [#1] [ 0.000000] BE PAGE_SIZE=4K DEBUG_PAGEALLOC [ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.15.0+ #237 [ 0.000000] NIP: c0600944 LR: 00003390 CTR: 00000000 [ 0.000000] REGS: c07bbf40 TRAP: 0400 Not tainted (5.15.0+) [ 0.000000] MSR: 20001032 <ME,IR,DR,RI> CR: 48222444 XER: 20000000 [ 0.000000] [ 0.000000] GPR00: c0003364 c07bbff0 c0707580 c0600944 00001032 00000000 c077dc8c 00000000 [ 0.000000] GPR08: c07d0000 00000001 c07d0000 ffffffff 88222444 00000000 3ff9c5f0 3fffd79c [ 0.000000] GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 0.000000] GPR24: 00000000 00000000 40000000 3ff9c5d8 03ffb000 00000000 3fffe4d4 03ffb000
Thanks for the report. This problem doesn't happen on powermac on QEMU. I was able to reproduce this problem on an mpc8321 board. It happens when CONFIG_MODULES is not defined, in that case the Instruction TLB miss exception handler doesn't expect such exception at all because all kernel text is expected to be mapped with IBATs. However, due to DEBUGPAGE_ALLOC, only main text is mapped with BATs, not inittext. That's a mistake. inittext should still be mapped with BATs. When CONFIG_MODULES is set it works. One way to fix it is to drop this CONFIG_MODULES #ifdefs in instruction TLB miss handler (In kernel/head_book3s_32.S), but that would kill performance for just the sake init. Another way to fix it is to set an IBAT coverring up to _einittext. This IBAT should be removed by mark_initmem_nx() at the end of init ... but ... it looks like we have a problem there as well: as we have not mapped _sinittext by DBATs, mmu_mark_initmem_nx() is not called. Also, as we are setting an IBAT, we shoudn't set the pages executable, at least X bit should be cleared. But the way it is done, if we call mark_initmem_nx() then mark_initmem_nx() would call set_memory_attr() to clear X bit from the pages. At the end it's not a problem because the kernel segments are marked NX, but it's not clean. So at the end it seems to be a mess around DEBUGPAGE_ALLOC and STRICT_KERNEL_RWX. All this being amplified by those 'nobats' and 'noltlbs' options that are pointless from a functionnal point of view. I need to think a bit more about it to find the cleanest solution that works for all platforms. Christophe