[PPC64] Fix mismatch between thread flags and MSR

When sigreturn() restored a thread's context, SRR1 was being restored
to its previous value, but pcb_flags was not being touched.

This could cause a mismatch between the thread's MSR and its pcb_flags.
For instance, when the thread used the FPU for the first time inside
the signal handler, sigreturn() would clear SRR1, but not pcb_flags.
Then, the thread would return with the FPU bit cleared in MSR and,
the next time it tried to use the FPU, it would fail on a KASSERT
that checked if the FPU was disabled.

This change clears the FPU bit in both pcb_flags and frame->srr1,
as the code that restores the context expects to use the FPU trap
to re-enable it.

PR:		234539
Reported by:	sbruno
Reviewed by:	jhibbits, sbruno
Differential Revision:	https://reviews.freebsd.org/D19166
This commit is contained in:
Leandro Lupori 2019-02-14 15:15:32 +00:00
parent 72091bb393
commit 59621b207c

View File

@ -474,6 +474,10 @@ set_mcontext(struct thread *td, mcontext_t *mcp)
else
tf->fixreg[2] = tls;
/* Disable FPU */
tf->srr1 &= ~PSL_FP;
pcb->pcb_flags &= ~PCB_FPU;
if (mcp->mc_flags & _MC_FP_VALID) {
/* enable_fpu() will happen lazily on a fault */
pcb->pcb_flags |= PCB_FPREGS;