aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2015-04-03 18:27:06 -0400
committerRalf Baechle <ralf@linux-mips.org>2015-04-07 19:10:15 -0400
commited2d72c1eb3643b7c109bdf387563d9b9a30c279 (patch)
treecd0cc0203cef78f94b60770889f0e996a60387c6
parentcfafc4feb39a5f5f12cf30da33c0b6ae89ce907d (diff)
MIPS: Respect the FCSR exception mask for `si_code'
Respect the FCSR exception mask when interpreting the IEEE 754 exception condition to report with SIGFPE in `si_code', so as not to use one that has been masked where a different one set in parallel caused the FPE hardware exception to trigger. As per the IEEE Std 754 the Inexact exception can happen together with Overflow or Underflow. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/9703/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/kernel/traps.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 88f04f0d2d21..dbfa47cdc8c1 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -12,6 +12,7 @@
12 * Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc. All rights reserved. 12 * Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc. All rights reserved.
13 * Copyright (C) 2014, Imagination Technologies Ltd. 13 * Copyright (C) 2014, Imagination Technologies Ltd.
14 */ 14 */
15#include <linux/bitops.h>
15#include <linux/bug.h> 16#include <linux/bug.h>
16#include <linux/compiler.h> 17#include <linux/compiler.h>
17#include <linux/context_tracking.h> 18#include <linux/context_tracking.h>
@@ -817,7 +818,15 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
817 process_fpemu_return(sig, fault_addr); 818 process_fpemu_return(sig, fault_addr);
818 819
819 goto out; 820 goto out;
820 } else if (fcr31 & FPU_CSR_INV_X) 821 }
822
823 /*
824 * Inexact can happen together with Overflow or Underflow.
825 * Respect the mask to deliver the correct exception.
826 */
827 fcr31 &= (fcr31 & FPU_CSR_ALL_E) <<
828 (ffs(FPU_CSR_ALL_X) - ffs(FPU_CSR_ALL_E));
829 if (fcr31 & FPU_CSR_INV_X)
821 info.si_code = FPE_FLTINV; 830 info.si_code = FPE_FLTINV;
822 else if (fcr31 & FPU_CSR_DIV_X) 831 else if (fcr31 & FPU_CSR_DIV_X)
823 info.si_code = FPE_FLTDIV; 832 info.si_code = FPE_FLTDIV;