OSDN Git Service

powerpc/64s: Move and rename do_bad_slb_fault as it is not hash specific
authorNicholas Piggin <npiggin@gmail.com>
Wed, 1 Dec 2021 14:41:39 +0000 (00:41 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 2 Dec 2021 11:57:23 +0000 (22:57 +1100)
slb.c is hash-specific SLB management, but do_bad_slb_fault deals with
segment interrupts that occur with radix MMU as well.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20211201144153.2456614-5-npiggin@gmail.com
arch/powerpc/include/asm/interrupt.h
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/mm/book3s64/slb.c
arch/powerpc/mm/fault.c

index a1d2382..3487aab 100644 (file)
@@ -564,7 +564,7 @@ DECLARE_INTERRUPT_HANDLER(kernel_bad_stack);
 
 /* slb.c */
 DECLARE_INTERRUPT_HANDLER_RAW(do_slb_fault);
-DECLARE_INTERRUPT_HANDLER(do_bad_slb_fault);
+DECLARE_INTERRUPT_HANDLER(do_bad_segment_interrupt);
 
 /* hash_utils.c */
 DECLARE_INTERRUPT_HANDLER_RAW(do_hash_fault);
index 277eccf..2acd7e6 100644 (file)
@@ -1428,7 +1428,7 @@ MMU_FTR_SECTION_ELSE
 ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
        std     r3,RESULT(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      do_bad_slb_fault
+       bl      do_bad_segment_interrupt
        b       interrupt_return_srr
 
 
@@ -1508,7 +1508,7 @@ MMU_FTR_SECTION_ELSE
 ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
        std     r3,RESULT(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      do_bad_slb_fault
+       bl      do_bad_segment_interrupt
        b       interrupt_return_srr
 
 
index f0037bc..31f4cef 100644 (file)
@@ -868,19 +868,3 @@ DEFINE_INTERRUPT_HANDLER_RAW(do_slb_fault)
                return err;
        }
 }
-
-DEFINE_INTERRUPT_HANDLER(do_bad_slb_fault)
-{
-       int err = regs->result;
-
-       if (err == -EFAULT) {
-               if (user_mode(regs))
-                       _exception(SIGSEGV, regs, SEGV_BNDERR, regs->dar);
-               else
-                       bad_page_fault(regs, SIGSEGV);
-       } else if (err == -EINVAL) {
-               unrecoverable_exception(regs);
-       } else {
-               BUG();
-       }
-}
index a8d0ce8..2d4a411 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/kfence.h>
 #include <linux/pkeys.h>
 
+#include <asm/asm-prototypes.h>
 #include <asm/firmware.h>
 #include <asm/interrupt.h>
 #include <asm/page.h>
@@ -620,4 +621,27 @@ DEFINE_INTERRUPT_HANDLER(do_bad_page_fault_segv)
 {
        bad_page_fault(regs, SIGSEGV);
 }
+
+/*
+ * In radix, segment interrupts indicate the EA is not addressable by the
+ * page table geometry, so they are always sent here.
+ *
+ * In hash, this is called if do_slb_fault returns error. Typically it is
+ * because the EA was outside the region allowed by software.
+ */
+DEFINE_INTERRUPT_HANDLER(do_bad_segment_interrupt)
+{
+       int err = regs->result;
+
+       if (err == -EFAULT) {
+               if (user_mode(regs))
+                       _exception(SIGSEGV, regs, SEGV_BNDERR, regs->dar);
+               else
+                       bad_page_fault(regs, SIGSEGV);
+       } else if (err == -EINVAL) {
+               unrecoverable_exception(regs);
+       } else {
+               BUG();
+       }
+}
 #endif