signal/ia64: Use force_sig_fault where appropriate
[linux-2.6-block.git] / arch / ia64 / kernel / traps.c
index c6f4932073a1857f496b08149dfacbe31b6778c0..85d8616ac4f6e1ae32ea6964a79a7323b55e7389 100644 (file)
@@ -100,16 +100,8 @@ die_if_kernel (char *str, struct pt_regs *regs, long err)
 void
 __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
 {
-       siginfo_t siginfo;
        int sig, code;
 
-       /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
-       clear_siginfo(&siginfo);
-       siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
-       siginfo.si_imm = break_num;
-       siginfo.si_flags = 0;           /* clear __ISR_VALID */
-       siginfo.si_isr = 0;
-
        switch (break_num) {
              case 0: /* unknown error (used by GCC for __builtin_abort()) */
                if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
@@ -182,10 +174,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
                        sig = SIGTRAP; code = TRAP_BRKPT;
                }
        }
-       siginfo.si_signo = sig;
-       siginfo.si_errno = 0;
-       siginfo.si_code = code;
-       force_sig_info(sig, &siginfo, current);
+       force_sig_fault(sig, code,
+                       (void __user *) (regs->cr_iip + ia64_psr(regs)->ri),
+                       break_num, 0 /* clear __ISR_VALID */, 0, current);
 }
 
 /*
@@ -344,30 +335,25 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
                        printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
                        return -1;
                } else {
-                       struct siginfo siginfo;
-
                        /* is next instruction a trap? */
+                       int si_code;
+
                        if (exception & 2) {
                                ia64_increment_ip(regs);
                        }
-                       clear_siginfo(&siginfo);
-                       siginfo.si_signo = SIGFPE;
-                       siginfo.si_errno = 0;
-                       siginfo.si_code = FPE_FLTUNK;   /* default code */
-                       siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
+                       si_code = FPE_FLTUNK;   /* default code */
                        if (isr & 0x11) {
-                               siginfo.si_code = FPE_FLTINV;
+                               si_code = FPE_FLTINV;
                        } else if (isr & 0x22) {
                                /* denormal operand gets the same si_code as underflow 
                                * see arch/i386/kernel/traps.c:math_error()  */
-                               siginfo.si_code = FPE_FLTUND;
+                               si_code = FPE_FLTUND;
                        } else if (isr & 0x44) {
-                               siginfo.si_code = FPE_FLTDIV;
+                               si_code = FPE_FLTDIV;
                        }
-                       siginfo.si_isr = isr;
-                       siginfo.si_flags = __ISR_VALID;
-                       siginfo.si_imm = 0;
-                       force_sig_info(SIGFPE, &siginfo, current);
+                       force_sig_fault(SIGFPE, si_code,
+                                       (void __user *) (regs->cr_iip + ia64_psr(regs)->ri),
+                                       0, __ISR_VALID, isr, current);
                }
        } else {
                if (exception == -1) {
@@ -375,24 +361,19 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
                        return -1;
                } else if (exception != 0) {
                        /* raise exception */
-                       struct siginfo siginfo;
+                       int si_code;
 
-                       clear_siginfo(&siginfo);
-                       siginfo.si_signo = SIGFPE;
-                       siginfo.si_errno = 0;
-                       siginfo.si_code = FPE_FLTUNK;   /* default code */
-                       siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
+                       si_code = FPE_FLTUNK;   /* default code */
                        if (isr & 0x880) {
-                               siginfo.si_code = FPE_FLTOVF;
+                               si_code = FPE_FLTOVF;
                        } else if (isr & 0x1100) {
-                               siginfo.si_code = FPE_FLTUND;
+                               si_code = FPE_FLTUND;
                        } else if (isr & 0x2200) {
-                               siginfo.si_code = FPE_FLTRES;
+                               si_code = FPE_FLTRES;
                        }
-                       siginfo.si_isr = isr;
-                       siginfo.si_flags = __ISR_VALID;
-                       siginfo.si_imm = 0;
-                       force_sig_info(SIGFPE, &siginfo, current);
+                       force_sig_fault(SIGFPE, si_code,
+                                       (void __user *) (regs->cr_iip + ia64_psr(regs)->ri),
+                                       0, __ISR_VALID, isr, current);
                }
        }
        return 0;
@@ -408,7 +389,6 @@ ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
                       struct pt_regs regs)
 {
        struct illegal_op_return rv;
-       struct siginfo si;
        char buf[128];
 
 #ifdef CONFIG_IA64_BRL_EMU
@@ -426,11 +406,9 @@ ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
        if (die_if_kernel(buf, &regs, 0))
                return rv;
 
-       clear_siginfo(&si);
-       si.si_signo = SIGILL;
-       si.si_code = ILL_ILLOPC;
-       si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri);
-       force_sig_info(SIGILL, &si, current);
+       force_sig_fault(SIGILL, ILL_ILLOPC,
+                       (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri),
+                       0, 0, 0, current);
        return rv;
 }
 
@@ -441,7 +419,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 {
        unsigned long code, error = isr, iip;
        char buf[128];
-       int result, sig;
+       int result, sig, si_code;
        static const char *reason[] = {
                "IA-64 Illegal Operation fault",
                "IA-64 Privileged Operation fault",
@@ -490,7 +468,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 
              case 26: /* NaT Consumption */
                if (user_mode(&regs)) {
-                       struct siginfo siginfo;
                        void __user *addr;
 
                        if (((isr >> 4) & 0xf) == 2) {
@@ -505,15 +482,8 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
                                addr = (void __user *) (regs.cr_iip
                                                        + ia64_psr(&regs)->ri);
                        }
-                       clear_siginfo(&siginfo);
-                       siginfo.si_signo = sig;
-                       siginfo.si_code = code;
-                       siginfo.si_errno = 0;
-                       siginfo.si_addr = addr;
-                       siginfo.si_imm = vector;
-                       siginfo.si_flags = __ISR_VALID;
-                       siginfo.si_isr = isr;
-                       force_sig_info(sig, &siginfo, current);
+                       force_sig_fault(sig, code, addr,
+                                       vector, __ISR_VALID, isr, current);
                        return;
                } else if (ia64_done_with_exception(&regs))
                        return;
@@ -522,17 +492,8 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 
              case 31: /* Unsupported Data Reference */
                if (user_mode(&regs)) {
-                       struct siginfo siginfo;
-
-                       clear_siginfo(&siginfo);
-                       siginfo.si_signo = SIGILL;
-                       siginfo.si_code = ILL_ILLOPN;
-                       siginfo.si_errno = 0;
-                       siginfo.si_addr = (void __user *) iip;
-                       siginfo.si_imm = vector;
-                       siginfo.si_flags = __ISR_VALID;
-                       siginfo.si_isr = isr;
-                       force_sig_info(SIGILL, &siginfo, current);
+                       force_sig_fault(SIGILL, ILL_ILLOPN, (void __user *) iip,
+                                       vector, __ISR_VALID, isr, current);
                        return;
                }
                sprintf(buf, "Unsupported data reference");
@@ -541,10 +502,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
              case 29: /* Debug */
              case 35: /* Taken Branch Trap */
              case 36: /* Single Step Trap */
-             {
-               struct siginfo siginfo;
-
-               clear_siginfo(&siginfo);
                if (fsys_mode(current, &regs)) {
                        extern char __kernel_syscall_via_break[];
                        /*
@@ -568,7 +525,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
                switch (vector) {
                      default:
                      case 29:
-                       siginfo.si_code = TRAP_HWBKPT;
+                       si_code = TRAP_HWBKPT;
 #ifdef CONFIG_ITANIUM
                        /*
                         * Erratum 10 (IFA may contain incorrect address) now has
@@ -578,37 +535,22 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
                          ifa = regs.cr_iip;
 #endif
                        break;
-                     case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
-                     case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
+                     case 35: si_code = TRAP_BRANCH; ifa = 0; break;
+                     case 36: si_code = TRAP_TRACE; ifa = 0; break;
                }
-               if (notify_die(DIE_FAULT, "ia64_fault", &regs, vector, siginfo.si_code, SIGTRAP)
+               if (notify_die(DIE_FAULT, "ia64_fault", &regs, vector, si_code, SIGTRAP)
                                == NOTIFY_STOP)
                        return;
-               siginfo.si_signo = SIGTRAP;
-               siginfo.si_errno = 0;
-               siginfo.si_addr  = (void __user *) ifa;
-               siginfo.si_imm   = 0;
-               siginfo.si_flags = __ISR_VALID;
-               siginfo.si_isr   = isr;
-               force_sig_info(SIGTRAP, &siginfo, current);
+               force_sig_fault(SIGTRAP, si_code, (void __user *) ifa,
+                               0, __ISR_VALID, isr, current);
                return;
-             }
 
              case 32: /* fp fault */
              case 33: /* fp trap */
                result = handle_fpu_swa((vector == 32) ? 1 : 0, &regs, isr);
                if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) {
-                       struct siginfo siginfo;
-
-                       clear_siginfo(&siginfo);
-                       siginfo.si_signo = SIGFPE;
-                       siginfo.si_errno = 0;
-                       siginfo.si_code = FPE_FLTINV;
-                       siginfo.si_addr = (void __user *) iip;
-                       siginfo.si_flags = __ISR_VALID;
-                       siginfo.si_isr = isr;
-                       siginfo.si_imm = 0;
-                       force_sig_info(SIGFPE, &siginfo, current);
+                       force_sig_fault(SIGFPE, FPE_FLTINV, (void __user *) iip,
+                                       0, __ISR_VALID, isr, current);
                }
                return;
 
@@ -634,17 +576,9 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
                } else {
                        /* Unimplemented Instr. Address Trap */
                        if (user_mode(&regs)) {
-                               struct siginfo siginfo;
-
-                               clear_siginfo(&siginfo);
-                               siginfo.si_signo = SIGILL;
-                               siginfo.si_code = ILL_BADIADDR;
-                               siginfo.si_errno = 0;
-                               siginfo.si_flags = 0;
-                               siginfo.si_isr = 0;
-                               siginfo.si_imm = 0;
-                               siginfo.si_addr = (void __user *) iip;
-                               force_sig_info(SIGILL, &siginfo, current);
+                               force_sig_fault(SIGILL, ILL_BADIADDR,
+                                               (void __user *) iip,
+                                               0, 0, 0, current);
                                return;
                        }
                        sprintf(buf, "Unimplemented Instruction Address fault");