arch/tile: support signal "exception-trace" hook
[pandora-kernel.git] / arch / tile / mm / fault.c
index 24ca54a..25b7b90 100644 (file)
 
 #include <arch/interrupts.h>
 
-static noinline void force_sig_info_fault(int si_signo, int si_code,
-       unsigned long address, int fault_num, struct task_struct *tsk)
+static noinline void force_sig_info_fault(const char *type, int si_signo,
+                                         int si_code, unsigned long address,
+                                         int fault_num,
+                                         struct task_struct *tsk,
+                                         struct pt_regs *regs)
 {
        siginfo_t info;
 
@@ -59,6 +62,7 @@ static noinline void force_sig_info_fault(int si_signo, int si_code,
        info.si_code = si_code;
        info.si_addr = (void __user *)address;
        info.si_trapno = fault_num;
+       trace_unhandled_signal(type, regs, address, si_signo);
        force_sig_info(si_signo, &info, tsk);
 }
 
@@ -71,11 +75,12 @@ SYSCALL_DEFINE2(cmpxchg_badaddr, unsigned long, address,
                struct pt_regs *, regs)
 {
        if (address >= PAGE_OFFSET)
-               force_sig_info_fault(SIGSEGV, SEGV_MAPERR, address,
-                                    INT_DTLB_MISS, current);
+               force_sig_info_fault("atomic segfault", SIGSEGV, SEGV_MAPERR,
+                                    address, INT_DTLB_MISS, current, regs);
        else
-               force_sig_info_fault(SIGBUS, BUS_ADRALN, address,
-                                    INT_UNALIGN_DATA, current);
+               force_sig_info_fault("atomic alignment fault", SIGBUS,
+                                    BUS_ADRALN, address,
+                                    INT_UNALIGN_DATA, current, regs);
 
        /*
         * Adjust pc to point at the actual instruction, which is unusual
@@ -471,8 +476,8 @@ bad_area_nosemaphore:
                 */
                local_irq_enable();
 
-               force_sig_info_fault(SIGSEGV, si_code, address,
-                                    fault_num, tsk);
+               force_sig_info_fault("segfault", SIGSEGV, si_code, address,
+                                    fault_num, tsk, regs);
                return 0;
        }
 
@@ -547,7 +552,8 @@ do_sigbus:
        if (is_kernel_mode)
                goto no_context;
 
-       force_sig_info_fault(SIGBUS, BUS_ADRERR, address, fault_num, tsk);
+       force_sig_info_fault("bus error", SIGBUS, BUS_ADRERR, address,
+                            fault_num, tsk, regs);
        return 0;
 }