summaryrefslogtreecommitdiffstats
path: root/sys/amd64/isa
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2001-05-20 18:05:44 +0000
committerbde <bde@FreeBSD.org>2001-05-20 18:05:44 +0000
commite37c5b4039950f6c6b0546d9d23e73a3bdf5ffae (patch)
treeef2e0731f44f4d0f6cc157c312674262199a0633 /sys/amd64/isa
parentfe3ed5cadca20fbbc88e70b0e90ba5261ab16058 (diff)
downloadFreeBSD-src-e37c5b4039950f6c6b0546d9d23e73a3bdf5ffae.zip
FreeBSD-src-e37c5b4039950f6c6b0546d9d23e73a3bdf5ffae.tar.gz
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.
Diffstat (limited to 'sys/amd64/isa')
-rw-r--r--sys/amd64/isa/npx.c6
1 files changed, 6 insertions, 0 deletions
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;
OpenPOWER on IntegriCloud