linux-mainline/arch/powerpc/kernel
Michael Ellerman daa9ada209 powerpc/mm: Fix boot crash with FLATMEM
Erhard reported that his G5 was crashing with v6.6-rc kernels:

  mpic: Setting up HT PICs workarounds for U3/U4
  BUG: Unable to handle kernel data access at 0xfeffbb62ffec65fe
  Faulting instruction address: 0xc00000000005dc40
  Oops: Kernel access of bad area, sig: 11 [#1]
  BE PAGE_SIZE=4K MMU=Hash SMP NR_CPUS=2 PowerMac
  Modules linked in:
  CPU: 0 PID: 0 Comm: swapper/0 Tainted: G                T  6.6.0-rc3-PMacGS #1
  Hardware name: PowerMac11,2 PPC970MP 0x440101 PowerMac
  NIP:  c00000000005dc40 LR: c000000000066660 CTR: c000000000007730
  REGS: c0000000022bf510 TRAP: 0380   Tainted: G                T (6.6.0-rc3-PMacGS)
  MSR:  9000000000001032 <SF,HV,ME,IR,DR,RI>  CR: 44004242  XER: 00000000
  IRQMASK: 3
  GPR00: 0000000000000000 c0000000022bf7b0 c0000000010c0b00 00000000000001ac
  GPR04: 0000000003c80000 0000000000000300 c0000000f20001ae 0000000000000300
  GPR08: 0000000000000006 feffbb62ffec65ff 0000000000000001 0000000000000000
  GPR12: 9000000000001032 c000000002362000 c000000000f76b80 000000000349ecd8
  GPR16: 0000000002367ba8 0000000002367f08 0000000000000006 0000000000000000
  GPR20: 00000000000001ac c000000000f6f920 c0000000022cd985 000000000000000c
  GPR24: 0000000000000300 00000003b0a3691d c0003e008030000e 0000000000000000
  GPR28: c00000000000000c c0000000f20001ee feffbb62ffec65fe 00000000000001ac
  NIP hash_page_do_lazy_icache+0x50/0x100
  LR  __hash_page_4K+0x420/0x590
  Call Trace:
    hash_page_mm+0x364/0x6f0
    do_hash_fault+0x114/0x2b0
    data_access_common_virt+0x198/0x1f0
  --- interrupt: 300 at mpic_init+0x4bc/0x10c4
  NIP:  c000000002020a5c LR: c000000002020a04 CTR: 0000000000000000
  REGS: c0000000022bf9f0 TRAP: 0300   Tainted: G                T (6.6.0-rc3-PMacGS)
  MSR:  9000000000001032 <SF,HV,ME,IR,DR,RI>  CR: 24004248  XER: 00000000
  DAR: c0003e008030000e DSISR: 40000000 IRQMASK: 1
  ...
  NIP mpic_init+0x4bc/0x10c4
  LR  mpic_init+0x464/0x10c4
  --- interrupt: 300
    pmac_setup_one_mpic+0x258/0x2dc
    pmac_pic_init+0x28c/0x3d8
    init_IRQ+0x90/0x140
    start_kernel+0x57c/0x78c
    start_here_common+0x1c/0x20

A bisect pointed to the breakage beginning with commit 9fee28baa6 ("powerpc:
implement the new page table range API").

Analysis of the oops pointed to a struct page with a corrupted
compound_head being loaded via page_folio() -> _compound_head() in
hash_page_do_lazy_icache().

The access by the mpic code is to an MMIO address, so the expectation
is that the struct page for that address would be initialised by
init_unavailable_range(), as pointed out by Aneesh.

Instrumentation showed that was not the case, which eventually lead to
the realisation that pfn_valid() was returning false for that address,
causing the struct page to not be initialised.

Because the system is using FLATMEM, the version of pfn_valid() in
memory_model.h is used:

static inline int pfn_valid(unsigned long pfn)
{
	...
	return pfn >= pfn_offset && (pfn - pfn_offset) < max_mapnr;
}

Which relies on max_mapnr being initialised. Early in boot max_mapnr is
zero meaning no PFNs are valid.

max_mapnr is initialised in mem_init() called via:

  start_kernel()
    mm_core_init()  # init/main.c:928
      mem_init()

But that is too late for the usage in init_unavailable_range() called via:

  start_kernel()
    setup_arch()    # init/main.c:893
      paging_init()
        free_area_init()
          init_unavailable_range()

Although max_mapnr is currently set in mem_init(), the value is actually
already available much earlier, as soon as mem_topology_setup() has
completed, which is also before paging_init() is called. So move the
initialisation there, which causes paging_init() to correctly initialise
the struct page and fixes the bug.

This bug seems to have been lurking for years, but went unnoticed
because the pre-folio code was inspecting the uninitialised page->flags
but not dereferencing it.

Thanks to Erhard and Aneesh for help debugging.

Reported-by: Erhard Furtner <erhard_f@mailbox.org>
Closes: https://lore.kernel.org/all/20230929132750.3cd98452@yea/
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20231023112500.1550208-1-mpe@ellerman.id.au
2023-10-23 22:50:15 +11:00
..
ptrace powerpc/ptrace: Split gpr32_set_common 2023-08-16 23:54:50 +10:00
syscalls arch: Register fchmodat2, usually as syscall 452 2023-07-27 12:25:35 +02:00
trace powerpc updates for 6.6 2023-08-31 12:43:10 -07:00
vdso Kbuild updates for v6.5 2023-07-01 09:24:31 -07:00
.gitignore
85xx_entry_mapping.S
align.c
asm-offsets.c powerpc/64: vmlinux support building with PCREL addresing 2023-04-20 12:59:21 +10:00
audit_32.h powerpc: address missing-prototypes warnings 2023-08-02 22:22:19 +10:00
audit.c powerpc: address missing-prototypes warnings 2023-08-02 22:22:19 +10:00
btext.c powerpc: Use of_property_read_bool() for boolean properties 2023-03-30 23:36:35 +11:00
cacheinfo.c
cacheinfo.h
compat_audit.c powerpc: address missing-prototypes warnings 2023-08-02 22:22:19 +10:00
cpu_setup_6xx.S
cpu_setup_44x.S
cpu_setup_e500.S
cpu_setup_pa6t.S
cpu_setup_power.c powerpc/dexcr: Add initial Dynamic Execution Control Register (DEXCR) support 2023-06-19 17:36:25 +10:00
cpu_setup_ppc970.S
cpu_specs_8xx.h
cpu_specs_40x.h
cpu_specs_44x.h
cpu_specs_47x.h
cpu_specs_85xx.h
cpu_specs_book3s_32.h
cpu_specs_book3s_64.h
cpu_specs_e500mc.h
cpu_specs.h
cputable.c powerpc/kuap: Use MMU_FTR_KUAP on all and refactor disabling kuap 2023-08-02 22:22:18 +10:00
crash_dump.c
dawr.c
dbell.c powerpc/64: Fix perf profiling asynchronous interrupt handlers 2023-01-30 20:07:42 +11:00
dma-iommu.c powerpc/iommu: Incorrect DDW Table is referenced for SR-IOV device 2023-05-17 00:54:55 +10:00
dma-mask.c dma-mapping: move arch_dma_set_mask() declaration to header 2023-07-31 17:54:28 +02:00
dma-swiotlb.c
dt_cpu_ftrs.c
early_32.c
eeh_cache.c
eeh_driver.c powerpc/eeh: Set channel state after notifying the drivers 2023-02-15 22:41:11 +11:00
eeh_event.c
eeh_pe.c powerpc/eeh: Rely on dev->link_active_reporting 2023-06-14 17:58:12 -05:00
eeh_sysfs.c
eeh.c
entry_32.S powerpc/47x: Fix 47x syscall return crash 2023-10-11 09:31:26 +11:00
epapr_hcalls.S powerpc: replace #include <asm/export.h> with #include <linux/export.h> 2023-08-16 23:54:48 +10:00
epapr_paravirt.c
exceptions-64e.S powerpc/64e: Fix obtool warnings in exceptions-64e.S 2023-07-10 09:47:47 +10:00
exceptions-64s.S powerpc: add CFUNC assembly label annotation 2023-04-20 12:54:24 +10:00
fadump.c powerpc/fadump: reset dump area size if fadump memory reserve fails 2023-08-18 17:03:15 +10:00
firmware.c
fpu.S powerpc: replace #include <asm/export.h> with #include <linux/export.h> 2023-08-16 23:54:48 +10:00
head_8xx.S powerpc: remove unneeded #include <asm/export.h> 2023-08-16 23:54:48 +10:00
head_32.h
head_40x.S powerpc: remove unneeded #include <asm/export.h> 2023-08-16 23:54:48 +10:00
head_44x.S powerpc: remove unneeded #include <asm/export.h> 2023-08-16 23:54:48 +10:00
head_64.S powerpc updates for 6.6 2023-08-31 12:43:10 -07:00
head_85xx.S powerpc/85xx: Fix math emulation exception 2023-10-10 21:32:40 +11:00
head_book3s_32.S powerpc: remove unneeded #include <asm/export.h> 2023-08-16 23:54:48 +10:00
head_booke.h powerpc/32: Include thread_info.h in head_booke.h 2023-04-11 23:13:33 +10:00
hw_breakpoint_constraints.c powerpc/watchpoint: Disable pagefaults when getting user instruction 2023-09-18 12:23:47 +10:00
hw_breakpoint.c powerpc/watchpoints: Annotate atomic context in more places 2023-09-18 12:23:47 +10:00
idle_6xx.S
idle_64e.S
idle_85xx.S
idle_book3s.S
idle.c powerpc: Simplify sysctl registration for powersave_nap_ctl_table 2023-03-16 15:18:12 +11:00
ima_arch.c integrity: Always reference the blacklist keyring with appraisal 2023-08-01 08:17:25 -04:00
interrupt_64.S powerpc: Fix merge conflict between pcrel and copy_thread changes 2023-04-26 16:20:16 +10:00
interrupt.c powerpc: Mark [h]ssr_valid accesses in check_return_regs_valid 2023-06-21 15:13:57 +10:00
io-workarounds.c
io.c
iomap.c
iommu.c powerpc/iommu: Fix notifiers being shared by PCI and VIO buses 2023-08-25 23:44:35 +10:00
irq_64.c powerpc/64: Don't call trace_hardirqs_on() in prep_irq_for_idle() 2023-04-20 13:21:49 +10:00
irq.c powerpc/64: vmlinux support building with PCREL addresing 2023-04-20 12:59:21 +10:00
isa-bridge.c powerpc/isa-bridge: Fix ISA mapping when "ranges" is not present 2023-05-08 22:57:10 +10:00
jump_label.c powerpc: Don't use 'struct ppc_inst' to reference instruction location 2021-06-17 00:09:00 +10:00
kdebugfs.c
kgdb.c
kprobes-ftrace.c
kprobes.c powerpc updates for 6.2 2022-12-19 07:13:33 -06:00
kvm_emul.S
kvm.c
l2cr_6xx.S
legacy_serial.c powerpc: Explicitly include correct DT includes 2023-08-02 22:22:19 +10:00
Makefile powerpc/64: Rename entry_64.S to prom_entry_64.S 2023-06-15 14:04:19 +10:00
mce_power.c
mce.c powerpc/mce: log the error for all unrecoverable errors 2023-02-10 22:17:34 +11:00
misc_32.S powerpc: replace #include <asm/export.h> with #include <linux/export.h> 2023-08-16 23:54:48 +10:00
misc_64.S powerpc: replace #include <asm/export.h> with #include <linux/export.h> 2023-08-16 23:54:48 +10:00
misc.S powerpc: replace #include <asm/export.h> with #include <linux/export.h> 2023-08-16 23:54:48 +10:00
module_32.c module: replace module_layout with module_memory 2023-03-09 12:55:15 -08:00
module_64.c powerpc/ftrace: Add support for -fpatchable-function-entry 2023-08-22 00:09:06 +10:00
module.c
msi.c
note.S
nvram_64.c
of_platform.c powerpc: Explicitly include correct DT includes 2023-08-02 22:22:19 +10:00
optprobes_head.S
optprobes.c
paca.c powerpc/64: vmlinux support building with PCREL addresing 2023-04-20 12:59:21 +10:00
pci_32.c powerpc/pci: Add option for using pci_to_OF_bus_map 2023-02-07 20:15:23 +11:00
pci_64.c powerpc/pci_64: Init pcibios subsys a bit later 2023-03-14 23:36:27 +11:00
pci_dn.c
pci_of_scan.c
pci-common.c powerpc: Drop zalloc_maybe_bootmem() 2023-08-24 22:33:16 +10:00
pci-hotplug.c
pmc.c powerpc/85xx: Mark some functions static and add missing includes to fix no previous prototype error 2023-08-23 15:55:21 +10:00
ppc_save_regs.S powerpc: update ppc_save_regs to save current r1 in pt_regs 2023-06-19 17:37:14 +10:00
proc_powerpc.c
process.c powerpc/dexcr: Support userspace ROP protection 2023-06-19 17:36:26 +10:00
prom_entry_64.S powerpc/64: Rename entry_64.S to prom_entry_64.S 2023-06-15 14:04:19 +10:00
prom_init_check.sh kasan, powerpc: don't rename memintrinsics if compiler adds prefixes 2023-03-23 17:18:33 -07:00
prom_init.c
prom_parse.c
prom.c powerpc/dexcr: Add initial Dynamic Execution Control Register (DEXCR) support 2023-06-19 17:36:25 +10:00
reloc_32.S
reloc_64.S
rtas_entry.S
rtas_flash.c powerpc/rtas_flash: allow user copy to flash block cache objects 2023-08-17 09:46:14 +10:00
rtas_pci.c powerpc/rtas: arch-wide function token lookup conversions 2023-02-13 22:35:03 +11:00
rtas-proc.c powerpc/rtas: arch-wide function token lookup conversions 2023-02-13 22:35:03 +11:00
rtas-rtc.c powerpc/rtas: arch-wide function token lookup conversions 2023-02-13 22:35:03 +11:00
rtas.c powerpc/rtas: export rtas_error_rc() for reuse. 2023-08-18 23:28:57 +10:00
rtasd.c powerpc/rtas: arch-wide function token lookup conversions 2023-02-13 22:35:03 +11:00
secure_boot.c
security.c powerpc/security: Fix Speculation_Store_Bypass reporting on Power10 2023-07-10 09:47:47 +10:00
secvar-ops.c powerpc/secvar: Warn and error if multiple secvar ops are set 2023-02-12 22:12:36 +11:00
secvar-sysfs.c powerpc/secvar: Don't print error on ENOENT when reading variables 2023-02-12 22:12:37 +11:00
setup_32.c
setup_64.c cpu: Mark panic_smp_self_stop() __noreturn 2023-04-14 17:31:25 +02:00
setup-common.c powerpc/mm: Fix boot crash with FLATMEM 2023-10-23 22:50:15 +11:00
setup.h
signal_32.c powerpc/signal32: Force inlining of __unsafe_save_user_regs() and save_tm_user_regs_unsafe() 2023-06-09 23:29:51 +10:00
signal_64.c
signal.c
signal.h
smp-tbsync.c
smp.c Merge branch 'topic/cpu-smt' into next 2023-08-14 21:46:03 +10:00
stacktrace.c powerpc/stacktrace: Fix arch_stack_walk_reliable() 2023-09-22 20:29:27 +10:00
static_call.c
suspend.c
switch.S powerpc: merge 32-bit and 64-bit _switch implementation 2023-06-15 14:03:55 +10:00
swsusp_32.S
swsusp_64.c
swsusp_85xx.S
swsusp_asm64.S
swsusp.c
sys_ppc32.c
syscall.c powerpc/kuap: MMU_FTR_BOOK3S_KUAP becomes MMU_FTR_KUAP 2023-08-02 22:22:18 +10:00
syscalls.c
sysfs.c powerpc/sysfs: move to use bus_get_dev_root() 2023-03-17 15:29:34 +01:00
systbl.c
tau_6xx.c powerpc, workqueue: Use alloc_ordered_workqueue() to create ordered workqueues 2023-05-08 13:52:27 -10:00
time.c powerpc: Make generic_calibrate_decr() the default 2023-03-16 08:56:48 +11:00
tm.S powerpc: replace #include <asm/export.h> with #include <linux/export.h> 2023-08-16 23:54:48 +10:00
traps.c powerpc/dexcr: Move HASHCHK trap handler 2023-09-18 12:23:48 +10:00
ucall.S powerpc: replace #include <asm/export.h> with #include <linux/export.h> 2023-08-16 23:54:48 +10:00
udbg_16550.c
udbg.c
uprobes.c
vdso32_wrapper.S
vdso64_wrapper.S
vdso.c mm: remove zap_page_range and create zap_vma_pages 2023-01-18 17:12:55 -08:00
vecemu.c
vector.S powerpc: replace #include <asm/export.h> with #include <linux/export.h> 2023-08-16 23:54:48 +10:00
vmlinux.lds.S powerpc/ftrace: Extend ftrace support for large kernels to ppc32 2023-08-22 00:09:05 +10:00
watchdog.c nmi_backtrace: allow excluding an arbitrary CPU 2023-08-18 10:19:00 -07:00