From e37c5b4039950f6c6b0546d9d23e73a3bdf5ffae Mon Sep 17 00:00:00 2001 From: bde Date: Sun, 20 May 2001 18:05:44 +0000 Subject: Use a critical region to protect almost everything in npxinit(). npxinit() didn't have the usual race because it doesn't save to curpcb, but it may have had a worse form of it since it uses the npx when it doesn't "own" it. I'm not sure if locking prevented this. npxinit() is normally caled with the proc lock but not sched_lock. Use a critical region to protect pushing of curproc's npx state to curpcb in npxexit(). Not doing so was harmless since it at worst saved a wrong state to a dieing pcb. --- sys/amd64/isa/npx.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sys/amd64/isa') diff --git a/sys/amd64/isa/npx.c b/sys/amd64/isa/npx.c index a57bffc..477f7ba 100644 --- a/sys/amd64/isa/npx.c +++ b/sys/amd64/isa/npx.c @@ -484,6 +484,7 @@ npxinit(control) u_short control; { struct save87 dummy; + critical_t savecrit; if (!npx_exists) return; @@ -492,12 +493,14 @@ npxinit(control) * fnsave to throw away any junk in the fpu. npxsave() initializes * the fpu and sets npxproc = NULL as important side effects. */ + savecrit = critical_enter(); npxsave(&dummy); stop_emulating(); fldcw(&control); if (PCPU_GET(curpcb) != NULL) fnsave(&PCPU_GET(curpcb)->pcb_savefpu); start_emulating(); + critical_exit(savecrit); } /* @@ -507,9 +510,12 @@ void npxexit(p) struct proc *p; { + critical_t savecrit; + savecrit = critical_enter(); if (p == PCPU_GET(npxproc)) npxsave(&PCPU_GET(curpcb)->pcb_savefpu); + critical_exit(savecrit); #ifdef NPX_DEBUG if (npx_exists) { u_int masked_exceptions; -- cgit v1.1