Page MenuHomeFreeBSD

D60054.id.diff
No OneTemporary

D60054.id.diff

diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c
--- a/sys/powerpc/powerpc/exec_machdep.c
+++ b/sys/powerpc/powerpc/exec_machdep.c
@@ -522,7 +522,14 @@
*
* Additionally, ensure VSX is disabled as well, as it is illegal
* to leave it turned on when FP or VEC are off.
+ *
+ * The MSR bits in the frame and the PCB flags must change together:
+ * if the thread is switched out in between, cpu_switchin() still
+ * sees the flags, reloads the registers and puts the MSR bits back
+ * into the frame, and the thread then runs with the units enabled
+ * but without owning them.
*/
+ critical_enter();
tf->srr1 &= ~(PSL_FP | PSL_VSX | PSL_VEC);
pcb->pcb_flags &= ~(PCB_FPU | PCB_VSX | PCB_VEC);
@@ -536,7 +543,6 @@
* sigresume is callled will used by the resumed thread, instead of the
* previously saved data from the mcontext.
*/
- critical_enter();
msr = mfmsr() & ~(PSL_FP | PSL_VSX | PSL_VEC);
isync();
mtmsr(msr);
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -294,24 +294,30 @@
case EXC_FPU:
KASSERT((td->td_pcb->pcb_flags & PCB_FPU) != PCB_FPU,
("FPU already enabled for thread"));
+ critical_enter();
enable_fpu(td);
+ critical_exit();
break;
case EXC_VEC:
KASSERT((td->td_pcb->pcb_flags & PCB_VEC) != PCB_VEC,
("Altivec already enabled for thread"));
+ critical_enter();
enable_vec(td);
+ critical_exit();
break;
case EXC_VSX:
KASSERT((td->td_pcb->pcb_flags & PCB_VSX) != PCB_VSX,
("VSX already enabled for thread"));
+ critical_enter();
if (!(td->td_pcb->pcb_flags & PCB_VEC))
enable_vec(td);
if (td->td_pcb->pcb_flags & PCB_FPU)
save_fpu(td);
td->td_pcb->pcb_flags |= PCB_VSX;
enable_fpu(td);
+ critical_exit();
break;
case EXC_FAC:

File Metadata

Mime Type
text/plain
Expires
Mon, Sep 28, 9:03 PM (8 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39804713
Default Alt Text
D60054.id.diff (1 KB)

Event Timeline