MIPS: Always clear FCSR cause bits after emulation
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>
This commit is contained in:
parent
ed2d72c1eb
commit
443c44032a
|
@ -1169,6 +1169,12 @@ fpu_emul:
|
|||
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.
|
||||
|
|
|
@ -761,6 +761,12 @@ static int simulate_fp(struct pt_regs *regs, unsigned int opcode,
|
|||
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);
|
||||
|
||||
|
@ -807,7 +813,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
|
|||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
@ -1384,6 +1390,13 @@ asmlinkage void do_cpu(struct pt_regs *regs)
|
|||
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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue