platform_kernel-5.15/arch/powerpc/mm
Michael Ellerman 4a852ff9b7 powerpc/64s: Don't use DSISR for SLB faults
[ Upstream commit d4679ac8ea2e5078704aa1c026db36580cc1bf9a ]

Since commit 46ddcb3950 ("powerpc/mm: Show if a bad page fault on data
is read or write.") we use page_fault_is_write(regs->dsisr) in
__bad_page_fault() to determine if the fault is for a read or write, and
change the message printed accordingly.

But SLB faults, aka Data Segment Interrupts, don't set DSISR (Data
Storage Interrupt Status Register) to a useful value. All ISA versions
from v2.03 through v3.1 specify that the Data Segment Interrupt sets
DSISR "to an undefined value". As far as I can see there's no mention of
SLB faults setting DSISR in any BookIV content either.

This manifests as accesses that should be a read being incorrectly
reported as writes, for example, using the xmon "dump" command:

  0:mon> d 0x5deadbeef0000000
  5deadbeef0000000
  [359526.415354][    C6] BUG: Unable to handle kernel data access on write at 0x5deadbeef0000000
  [359526.415611][    C6] Faulting instruction address: 0xc00000000010a300
  cpu 0x6: Vector: 380 (Data SLB Access) at [c00000000ffbf400]
      pc: c00000000010a300: mread+0x90/0x190

If we disassemble the PC, we see a load instruction:

  0:mon> di c00000000010a300
  c00000000010a300 89490000      lbz     r10,0(r9)

We can also see in exceptions-64s.S that the data_access_slb block
doesn't set IDSISR=1, which means it doesn't load DSISR into pt_regs. So
the value we're using to determine if the fault is a read/write is some
stale value in pt_regs from a previous page fault.

Rework the printing logic to separate the SLB fault case out, and only
print read/write in the cases where we can determine it.

The result looks like eg:

  0:mon> d 0x5deadbeef0000000
  5deadbeef0000000
  [  721.779525][    C6] BUG: Unable to handle kernel data access at 0x5deadbeef0000000
  [  721.779697][    C6] Faulting instruction address: 0xc00000000014cbe0
  cpu 0x6: Vector: 380 (Data SLB Access) at [c00000000ffbf390]

  0:mon> d 0
  0000000000000000
  [  742.793242][    C6] BUG: Kernel NULL pointer dereference at 0x00000000
  [  742.793316][    C6] Faulting instruction address: 0xc00000000014cbe0
  cpu 0x6: Vector: 380 (Data SLB Access) at [c00000000ffbf390]

Fixes: 46ddcb3950 ("powerpc/mm: Show if a bad page fault on data is read or write.")
Reported-by: Nageswara R Sastry <rnsastry@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Link: https://lore.kernel.org/r/20220222113449.319193-1-mpe@ellerman.id.au
Signed-off-by: Sasha Levin <sashal@kernel.org>
2022-04-08 14:23:38 +02:00
..
book3s32 powerpc/32s: Fix kasan_init_region() for KASAN 2022-02-01 17:27:06 +01:00
book3s64 powerpc/64s/radix: Fix huge vmap false positive 2022-01-27 11:05:12 +01:00
kasan powerpc/32s: Fix kasan_init_region() for KASAN 2022-02-01 17:27:06 +01:00
nohash powerpc/book3e: Fix set_memory_x() and set_memory_nx() 2021-11-18 19:16:57 +01:00
ptdump powerpc/ptdump: Fix DEBUG_WX since generic ptdump conversion 2022-01-05 12:42:33 +01:00
Makefile powerpc/ptdump: Convert powerpc to GENERIC_PTDUMP 2021-08-25 13:35:48 +10:00
cacheflush.c powerpc/mem: Use kmap_local_page() in flushing functions 2021-04-14 23:04:19 +10:00
copro_fault.c mm: clean up the last pieces of page fault accountings 2020-08-12 10:58:04 -07:00
dma-noncoherent.c dma-mapping: merge <linux/dma-noncoherent.h> into <linux/dma-map-ops.h> 2020-10-06 07:07:06 +02:00
drmem.c pseries/drmem: update LMBs after LPM 2021-08-10 23:14:55 +10:00
fault.c powerpc/64s: Don't use DSISR for SLB faults 2022-04-08 14:23:38 +02:00
hugetlbpage.c hugetlb: pass vma into huge_pte_alloc() and huge_pmd_share() 2021-05-05 11:27:20 -07:00
init-common.c powerpc: Inline setup_kup() 2020-12-15 13:13:49 +11:00
init_32.c powerpc: Enable KFENCE for PPC32 2021-03-24 14:09:30 +11:00
init_64.c Merge branch 'fixes' into next 2020-09-14 22:57:18 +10:00
ioremap.c mm/vmalloc: remove unmap_kernel_range 2021-04-30 11:20:40 -07:00
ioremap_32.c powerpc/mm: Leave a gap between early allocated IO areas 2021-06-25 00:07:10 +10:00
ioremap_64.c powerpc/mm: Leave a gap between early allocated IO areas 2021-06-25 00:07:10 +10:00
maccess.c powerpc: Don't use 'struct ppc_inst' to reference instruction location 2021-06-17 00:09:00 +10:00
mem.c powerpc/mem: Fix arch/powerpc/mm/mem.c:53:12: error: no previous prototype for 'create_section_mapping' 2021-11-18 19:16:51 +01:00
mmap.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
mmu_context.c KVM: PPC: Book3S HV: Implement radix prefetch workaround by disabling MMU 2021-06-10 22:12:14 +10:00
mmu_decl.h powerpc/ptdump: Convert powerpc to GENERIC_PTDUMP 2021-08-25 13:35:48 +10:00
numa.c powerpc/mm/numa: skip NUMA_NO_NODE onlining in parse_numa_properties() 2022-04-08 14:23:36 +02:00
pageattr.c powerpc/mm: Fix set_memory_*() against concurrent accesses 2021-08-19 09:41:54 +10:00
pgtable-frag.c powerpc/mm/radix: Fix PTE/PMD fragment count for early page table mappings 2020-07-20 22:57:56 +10:00
pgtable.c powerpc/fixmap: Fix VM debug warning on unmap 2022-02-16 12:56:12 +01:00
pgtable_32.c powerpc: Don't provide __kernel_map_pages() without ARCH_SUPPORTS_DEBUG_PAGEALLOC 2021-11-18 19:16:57 +01:00
pgtable_64.c powerpc/64s/radix: Fix huge vmap false positive 2022-01-27 11:05:12 +01:00
slice.c powerpc: Replace _ALIGN_UP() by ALIGN() 2020-05-11 23:15:15 +10:00