MIPS: Set trap_no field in thread_struct on exception.
[linux-drm-fsl-dcu.git] / arch / mips / mm / fault.c
index 36c0f26fac6b0780318958a59fc2665a444a10ea..4b88fa031891d474c715db30479218e8216aa948 100644 (file)
@@ -57,12 +57,10 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
 
 #ifdef CONFIG_KPROBES
        /*
-        * This is to notify the fault handler of the kprobes.  The
-        * exception code is redundant as it is also carried in REGS,
-        * but we pass it anyhow.
+        * This is to notify the fault handler of the kprobes.
         */
        if (notify_die(DIE_PAGE_FAULT, "page fault", regs, -1,
-                      (regs->cp0_cause >> 2) & 0x1f, SIGSEGV) == NOTIFY_STOP)
+                      current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP)
                return;
 #endif
 
@@ -133,7 +131,8 @@ good_area:
 #endif
                                goto bad_area;
                        }
-                       if (!(vma->vm_flags & VM_READ)) {
+                       if (!(vma->vm_flags & VM_READ) &&
+                           exception_epc(regs) != address) {
 #if 0
                                pr_notice("Cpu%d[%s:%d:%0*lx:%ld:%0*lx] RI violation\n",
                                          raw_smp_processor_id(),
@@ -223,6 +222,7 @@ bad_area_nosemaphore:
                        print_vma_addr(" ", regs->regs[31]);
                        pr_info("\n");
                }
+               current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
                info.si_signo = SIGSEGV;
                info.si_errno = 0;
                /* info.si_code has been set above */
@@ -281,6 +281,7 @@ do_sigbus:
                       field, (unsigned long) regs->cp0_epc,
                       field, (unsigned long) regs->regs[31]);
 #endif
+       current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
        tsk->thread.cp0_badvaddr = address;
        info.si_signo = SIGBUS;
        info.si_errno = 0;