diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/kernel/traps.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index d6103e510899..6379003f9d8d 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -606,6 +606,8 @@ asmlinkage void do_ov(struct pt_regs *regs) | |||
606 | */ | 606 | */ |
607 | asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | 607 | asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) |
608 | { | 608 | { |
609 | siginfo_t info; | ||
610 | |||
609 | die_if_kernel("FP exception in kernel code", regs); | 611 | die_if_kernel("FP exception in kernel code", regs); |
610 | 612 | ||
611 | if (fcr31 & FPU_CSR_UNI_X) { | 613 | if (fcr31 & FPU_CSR_UNI_X) { |
@@ -641,9 +643,22 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
641 | force_sig(sig, current); | 643 | force_sig(sig, current); |
642 | 644 | ||
643 | return; | 645 | return; |
644 | } | 646 | } else if (fcr31 & FPU_CSR_INV_X) |
645 | 647 | info.si_code = FPE_FLTINV; | |
646 | force_sig(SIGFPE, current); | 648 | else if (fcr31 & FPU_CSR_DIV_X) |
649 | info.si_code = FPE_FLTDIV; | ||
650 | else if (fcr31 & FPU_CSR_OVF_X) | ||
651 | info.si_code = FPE_FLTOVF; | ||
652 | else if (fcr31 & FPU_CSR_UDF_X) | ||
653 | info.si_code = FPE_FLTUND; | ||
654 | else if (fcr31 & FPU_CSR_INE_X) | ||
655 | info.si_code = FPE_FLTRES; | ||
656 | else | ||
657 | info.si_code = __SI_FAULT; | ||
658 | info.si_signo = SIGFPE; | ||
659 | info.si_errno = 0; | ||
660 | info.si_addr = (void __user *) regs->cp0_epc; | ||
661 | force_sig_info(SIGFPE, &info, current); | ||
647 | } | 662 | } |
648 | 663 | ||
649 | asmlinkage void do_bp(struct pt_regs *regs) | 664 | asmlinkage void do_bp(struct pt_regs *regs) |