Merge branch 'akpm' (patches from Andrew)
[linux-2.6-microblaze.git] / arch / powerpc / mm / fault.c
index a8d0ce8..eb8ecd7 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>
@@ -516,10 +517,8 @@ retry:
         * case.
         */
        if (unlikely(fault & VM_FAULT_RETRY)) {
-               if (flags & FAULT_FLAG_ALLOW_RETRY) {
-                       flags |= FAULT_FLAG_TRIED;
-                       goto retry;
-               }
+               flags |= FAULT_FLAG_TRIED;
+               goto retry;
        }
 
        mmap_read_unlock(current->mm);
@@ -620,4 +619,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