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.
This commit is contained in:
parent
fe3ed5cadc
commit
e37c5b4039
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user