diff options
author | Maciej W. Rozycki <macro@imgtec.com> | 2016-10-28 08:21:03 +0100 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2016-11-04 01:28:41 +0100 |
commit | 5a1aca4469fdccd5b74ba0b4e490173b2b447895 (patch) | |
tree | bdfad3f7a9ce39cc48edd2a1cff8c89a0549c60a /arch/mips/kernel/ptrace.c | |
parent | c9e5603974573367c4d80964a845237a2297228c (diff) |
MIPS: Fix FCSR Cause bit handling for correct SIGFPE issue
Sanitize FCSR Cause bit handling, following a trail of past attempts:
* commit 4249548454f7 ("MIPS: ptrace: Fix FP context restoration FCSR
regression"),
* commit 443c44032a54 ("MIPS: Always clear FCSR cause bits after
emulation"),
* commit 64bedffe4968 ("MIPS: Clear [MSA]FPE CSR.Cause after
notify_die()"),
* commit b1442d39fac2 ("MIPS: Prevent user from setting FCSR cause
bits"),
* commit b54d2901517d ("Properly handle branch delay slots in connection
with signals.").
Specifically do not mask these bits out in ptrace(2) processing and send
a SIGFPE signal instead whenever a matching pair of an FCSR Cause and
Enable bit is seen as execution of an affected context is about to
resume. Only then clear Cause bits, and even then do not clear any bits
that are set but masked with the respective Enable bits. Adjust Cause
bit clearing throughout code likewise, except within the FPU emulator
proper where they are set according to IEEE 754 exceptions raised as the
operation emulated executed. Do so so that any IEEE 754 exceptions
subject to their default handling are recorded like with operations
executed by FPU hardware.
Signed-off-by: Maciej W. Rozycki <macro@imgtec.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/14460/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/ptrace.c')
-rw-r--r-- | arch/mips/kernel/ptrace.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index fd3a9580661a..a92994d60e91 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -79,16 +79,15 @@ void ptrace_disable(struct task_struct *child) } /* - * Poke at FCSR according to its mask. Don't set the cause bits as - * this is currently not handled correctly in FP context restoration - * and will cause an oops if a corresponding enable bit is set. + * Poke at FCSR according to its mask. Set the Cause bits even + * if a corresponding Enable bit is set. This will be noticed at + * the time the thread is switched to and SIGFPE thrown accordingly. */ static void ptrace_setfcr31(struct task_struct *child, u32 value) { u32 fcr31; u32 mask; - value &= ~FPU_CSR_ALL_X; fcr31 = child->thread.fpu.fcr31; mask = boot_cpu_data.fpu_msk31; child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask); |