diff options
author | Maciej W. Rozycki <macro@linux-mips.org> | 2015-04-03 18:27:06 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-04-07 19:10:15 -0400 |
commit | ed2d72c1eb3643b7c109bdf387563d9b9a30c279 (patch) | |
tree | cd0cc0203cef78f94b60770889f0e996a60387c6 | |
parent | cfafc4feb39a5f5f12cf30da33c0b6ae89ce907d (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.c | 11 |
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; |