[PATCH 3.16 096/254] MIPS: Respect the FCSR exception mask for `si_code'

Ben Hutchings
2018-02-28T16:15:20Z

From: "Maciej W. Rozycki" <macro@linux-mips.org>

commit ed2d72c1eb3643b7c109bdf387563d9b9a30c279 upstream.

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>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
arch/mips/kernel/traps.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -12,6 +12,7 @@
* Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc. All rights reserved.
* Copyright (C) 2014, Imagination Technologies Ltd.
*/
+#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/compiler.h>
#include <linux/context_tracking.h>
@@ -785,7 +786,15 @@ asmlinkage void do_fpe(struct pt_regs *r
process_fpemu_return(sig, fault_addr);

goto out;
- } else if (fcr31 & FPU_CSR_INV_X)
+ }
+
+ /*
+ * Inexact can happen together with Overflow or Underflow.
+ * Respect the mask to deliver the correct exception.
+ */
+ fcr31 &= (fcr31 & FPU_CSR_ALL_E) <<
+ (ffs(FPU_CSR_ALL_X) - ffs(FPU_CSR_ALL_E));
+ if (fcr31 & FPU_CSR_INV_X)
info.si_code = FPE_FLTINV;
else if (fcr31 & FPU_CSR_DIV_X)
info.si_code = FPE_FLTDIV;