summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
ed2d72c)
Clear any FCSR cause bits recorded in the saved FPU context after
emulation in all cases rather than in `do_fpe' only, so that any
unmasked IEEE 754 exception left from emulation does not cause a fatal
kernel-mode FPE hardware exception with the CTC1 instruction used by the
kernel to subsequently restore FCSR hardware from the saved FPU context.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9704/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
err = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 0,
&fault_addr);
err = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 0,
&fault_addr);
+ /*
+ * We can't allow the emulated instruction to leave any of
+ * the cause bits set in $fcr31.
+ */
+ current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+
/*
* this is a tricky issue - lose_fpu() uses LL/SC atomics
* if FPU is owned and effectively cancels user level LL/SC.
/*
* this is a tricky issue - lose_fpu() uses LL/SC atomics
* if FPU is owned and effectively cancels user level LL/SC.
sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1,
&fault_addr);
sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1,
&fault_addr);
+ /*
+ * We can't allow the emulated instruction to leave any of
+ * the cause bits set in $fcr31.
+ */
+ current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+
/* If something went wrong, signal */
process_fpemu_return(sig, fault_addr);
/* If something went wrong, signal */
process_fpemu_return(sig, fault_addr);
/*
* We can't allow the emulated instruction to leave any of
/*
* We can't allow the emulated instruction to leave any of
- * the cause bit set in $fcr31.
+ * the cause bits set in $fcr31.
*/
current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
*/
current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
sig = fpu_emulator_cop1Handler(regs,
¤t->thread.fpu,
0, &fault_addr);
sig = fpu_emulator_cop1Handler(regs,
¤t->thread.fpu,
0, &fault_addr);
+
+ /*
+ * We can't allow the emulated instruction to leave
+ * any of the cause bits set in $fcr31.
+ */
+ current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+
if (!process_fpemu_return(sig, fault_addr) && !err)
mt_ase_fp_affinity();
}
if (!process_fpemu_return(sig, fault_addr) && !err)
mt_ase_fp_affinity();
}