aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorThiemo Seufer <ths@networkno.de>2007-08-22 01:42:04 +0100
committerRalf Baechle <ralf@linux-mips.org>2007-08-27 02:16:59 +0100
commit948a34cf3988462090291774e55f21f7efdfb072 (patch)
tree1f1191db06e1472fbe34b85f97754b2a7864820c /arch
parent34412c7231f513283ab501eea41774b4ae623dcc (diff)
[MIPS] Maintain si_code field properly for FP exceptions
The appended patch adds code to update siginfo_t's si_code field. It fixes e.g. a floating point overflow regression in the SBCL testsuite. Signed-off-By: Thiemo Seufer <ths@linux-mips.org> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/kernel/traps.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index d6103e51089..6379003f9d8 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)
*/
asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
{
+ siginfo_t info;
+
die_if_kernel("FP exception in kernel code", regs);
if (fcr31 & FPU_CSR_UNI_X) {
@@ -641,9 +643,22 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
force_sig(sig, current);
return;
- }
-
- force_sig(SIGFPE, current);
+ } else if (fcr31 & FPU_CSR_INV_X)
+ info.si_code = FPE_FLTINV;
+ else if (fcr31 & FPU_CSR_DIV_X)
+ info.si_code = FPE_FLTDIV;
+ else if (fcr31 & FPU_CSR_OVF_X)
+ info.si_code = FPE_FLTOVF;
+ else if (fcr31 & FPU_CSR_UDF_X)
+ info.si_code = FPE_FLTUND;
+ else if (fcr31 & FPU_CSR_INE_X)
+ info.si_code = FPE_FLTRES;
+ else
+ info.si_code = __SI_FAULT;
+ info.si_signo = SIGFPE;
+ info.si_errno = 0;
+ info.si_addr = (void __user *) regs->cp0_epc;
+ force_sig_info(SIGFPE, &info, current);
}
asmlinkage void do_bp(struct pt_regs *regs)