diff mbox

[09/24] powerpc/mm: Overhaul handling of bad page faults

Message ID 20170719044946.22030-9-benh@kernel.crashing.org (mailing list archive)
State Accepted
Commit f3d96e698ed0f83d8faa35071ea9ca0a57e74c50
Headers show

Commit Message

Benjamin Herrenschmidt July 19, 2017, 4:49 a.m. UTC
A bad page fault is when the HW signals an error such as a bad
copy/paste, an AMO error, or some other type of error that will
not be fixed by updating the PTE.

Use a helper page_fault_is_bad() to check for bad page faults thus
removing the per-processor family open-coding in __do_page_fault()
and trigger a SIGBUS rather than a SIGSEGV which is more appropriate.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/mm/fault.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)
diff mbox

Patch

diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index e2f3144a48b9..4470500b4871 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -188,8 +188,16 @@  static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault)
  */
 #if (defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
 #define page_fault_is_write(__err)	((__err) & ESR_DST)
+#define page_fault_is_bad(__err)	(0)
 #else
 #define page_fault_is_write(__err)	((__err) & DSISR_ISSTORE)
+#if defined(CONFIG_8xx)
+#define page_fault_is_bad(__err)	((__err) & 0x10000000)
+#elif defined(CONFIG_PPC64)
+#define page_fault_is_bad(__err)	((__err) & DSISR_BAD_FAULT_64S)
+#else
+#define page_fault_is_bad(__err)	((__err) & DSISR_BAD_FAULT_32S)
+#endif
 #endif
 
 /*
@@ -237,25 +245,13 @@  static int __do_page_fault(struct pt_regs *regs, unsigned long address,
 	if (unlikely(debugger_fault_handler(regs)))
 		goto bail;
 
-#if defined(CONFIG_6xx)
-	if (error_code & 0x95700000) {
-		/* an error such as lwarx to I/O controller space,
-		   address matching DABR, eciwx, etc. */
-		code = SEGV_ACCERR;
-		goto bad_area_nosemaphore;
-	}
-#endif /* CONFIG_6xx */
-#if defined(CONFIG_8xx)
-        /* The MPC8xx seems to always set 0x80000000, which is
-         * "undefined".  Of those that can be set, this is the only
-         * one which seems bad.
-         */
-	if (error_code & 0x10000000) {
-                /* Guarded storage error. */
-		code = SEGV_ACCERR;
-		goto bad_area_nosemaphore;
+	if (unlikely(page_fault_is_bad(error_code))) {
+		if (is_user)
+			_exception(SIGBUS, regs, BUS_OBJERR, address);
+		else
+			rc = SIGBUS;
+		goto bail;
 	}
-#endif /* CONFIG_8xx */
 
 	/*
 	 * The kernel should never take an execute fault nor should it