272 lines
6.5 KiB
Diff
272 lines
6.5 KiB
Diff
--- sys/amd64/amd64/fpu.c.orig
|
|
+++ sys/amd64/amd64/fpu.c
|
|
@@ -744,6 +744,7 @@
|
|
int max_ext_n, i, owned;
|
|
|
|
pcb = td->td_pcb;
|
|
+ critical_enter();
|
|
if ((pcb->pcb_flags & PCB_USERFPUINITDONE) == 0) {
|
|
bcopy(fpu_initialstate, get_pcb_user_save_pcb(pcb),
|
|
cpu_max_ext_state_size);
|
|
@@ -750,9 +751,9 @@
|
|
get_pcb_user_save_pcb(pcb)->sv_env.en_cw =
|
|
pcb->pcb_initial_fpucw;
|
|
fpuuserinited(td);
|
|
+ critical_exit();
|
|
return (_MC_FPOWNED_PCB);
|
|
}
|
|
- critical_enter();
|
|
if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) {
|
|
fpusave(get_pcb_user_save_pcb(pcb));
|
|
owned = _MC_FPOWNED_FPU;
|
|
@@ -759,7 +760,6 @@
|
|
} else {
|
|
owned = _MC_FPOWNED_PCB;
|
|
}
|
|
- critical_exit();
|
|
if (use_xsave) {
|
|
/*
|
|
* Handle partially saved state.
|
|
@@ -779,6 +779,7 @@
|
|
*xstate_bv |= bit;
|
|
}
|
|
}
|
|
+ critical_exit();
|
|
return (owned);
|
|
}
|
|
|
|
@@ -787,6 +788,7 @@
|
|
{
|
|
struct pcb *pcb;
|
|
|
|
+ CRITICAL_ASSERT(td);
|
|
pcb = td->td_pcb;
|
|
if (PCB_USER_FPU(pcb))
|
|
set_pcb_flags(pcb,
|
|
@@ -845,26 +847,25 @@
|
|
|
|
addr->sv_env.en_mxcsr &= cpu_mxcsr_mask;
|
|
pcb = td->td_pcb;
|
|
+ error = 0;
|
|
critical_enter();
|
|
if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) {
|
|
error = fpusetxstate(td, xfpustate, xfpustate_size);
|
|
- if (error != 0) {
|
|
- critical_exit();
|
|
- return (error);
|
|
+ if (error == 0) {
|
|
+ bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr));
|
|
+ fpurestore(get_pcb_user_save_td(td));
|
|
+ set_pcb_flags(pcb, PCB_FPUINITDONE |
|
|
+ PCB_USERFPUINITDONE);
|
|
}
|
|
- bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr));
|
|
- fpurestore(get_pcb_user_save_td(td));
|
|
- critical_exit();
|
|
- set_pcb_flags(pcb, PCB_FPUINITDONE | PCB_USERFPUINITDONE);
|
|
} else {
|
|
- critical_exit();
|
|
error = fpusetxstate(td, xfpustate, xfpustate_size);
|
|
- if (error != 0)
|
|
- return (error);
|
|
- bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr));
|
|
- fpuuserinited(td);
|
|
+ if (error == 0) {
|
|
+ bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr));
|
|
+ fpuuserinited(td);
|
|
+ }
|
|
}
|
|
- return (0);
|
|
+ critical_exit();
|
|
+ return (error);
|
|
}
|
|
|
|
/*
|
|
@@ -1037,6 +1038,7 @@
|
|
ctx->flags = FPU_KERN_CTX_DUMMY | FPU_KERN_CTX_INUSE;
|
|
return (0);
|
|
}
|
|
+ critical_enter();
|
|
KASSERT(!PCB_USER_FPU(pcb) || pcb->pcb_save ==
|
|
get_pcb_user_save_pcb(pcb), ("mangled pcb_save"));
|
|
ctx->flags = FPU_KERN_CTX_INUSE;
|
|
@@ -1047,6 +1049,7 @@
|
|
pcb->pcb_save = fpu_kern_ctx_savefpu(ctx);
|
|
set_pcb_flags(pcb, PCB_KERNFPU);
|
|
clear_pcb_flags(pcb, PCB_FPUINITDONE);
|
|
+ critical_exit();
|
|
return (0);
|
|
}
|
|
|
|
@@ -1065,7 +1068,6 @@
|
|
|
|
clear_pcb_flags(pcb, PCB_FPUNOSAVE | PCB_FPUINITDONE);
|
|
start_emulating();
|
|
- critical_exit();
|
|
} else {
|
|
KASSERT((ctx->flags & FPU_KERN_CTX_INUSE) != 0,
|
|
("leaving not inuse ctx"));
|
|
@@ -1079,7 +1081,6 @@
|
|
critical_enter();
|
|
if (curthread == PCPU_GET(fpcurthread))
|
|
fpudrop();
|
|
- critical_exit();
|
|
pcb->pcb_save = ctx->prev;
|
|
}
|
|
|
|
@@ -1096,6 +1097,7 @@
|
|
clear_pcb_flags(pcb, PCB_FPUINITDONE);
|
|
KASSERT(!PCB_USER_FPU(pcb), ("unpaired fpu_kern_leave"));
|
|
}
|
|
+ critical_exit();
|
|
return (0);
|
|
}
|
|
|
|
--- sys/amd64/amd64/machdep.c.orig
|
|
+++ sys/amd64/amd64/machdep.c
|
|
@@ -2158,8 +2158,10 @@
|
|
set_fpregs(struct thread *td, struct fpreg *fpregs)
|
|
{
|
|
|
|
+ critical_enter();
|
|
set_fpregs_xmm(fpregs, get_pcb_user_save_td(td));
|
|
fpuuserinited(td);
|
|
+ critical_exit();
|
|
return (0);
|
|
}
|
|
|
|
--- sys/i386/i386/machdep.c.orig
|
|
+++ sys/i386/i386/machdep.c
|
|
@@ -3004,6 +3004,7 @@
|
|
set_fpregs(struct thread *td, struct fpreg *fpregs)
|
|
{
|
|
|
|
+ critical_enter();
|
|
if (cpu_fxsr)
|
|
npx_set_fpregs_xmm((struct save87 *)fpregs,
|
|
&get_pcb_user_save_td(td)->sv_xmm);
|
|
@@ -3011,6 +3012,7 @@
|
|
bcopy(fpregs, &get_pcb_user_save_td(td)->sv_87,
|
|
sizeof(*fpregs));
|
|
npxuserinited(td);
|
|
+ critical_exit();
|
|
return (0);
|
|
}
|
|
|
|
--- sys/i386/isa/npx.c.orig
|
|
+++ sys/i386/isa/npx.c
|
|
@@ -974,14 +974,15 @@
|
|
return (_MC_FPOWNED_NONE);
|
|
|
|
pcb = td->td_pcb;
|
|
+ critical_enter();
|
|
if ((pcb->pcb_flags & PCB_NPXINITDONE) == 0) {
|
|
bcopy(npx_initialstate, get_pcb_user_save_pcb(pcb),
|
|
cpu_max_ext_state_size);
|
|
SET_FPU_CW(get_pcb_user_save_pcb(pcb), pcb->pcb_initial_npxcw);
|
|
npxuserinited(td);
|
|
+ critical_exit();
|
|
return (_MC_FPOWNED_PCB);
|
|
}
|
|
- critical_enter();
|
|
if (td == PCPU_GET(fpcurthread)) {
|
|
fpusave(get_pcb_user_save_pcb(pcb));
|
|
if (!cpu_fxsr)
|
|
@@ -995,7 +996,6 @@
|
|
} else {
|
|
owned = _MC_FPOWNED_PCB;
|
|
}
|
|
- critical_exit();
|
|
if (use_xsave) {
|
|
/*
|
|
* Handle partially saved state.
|
|
@@ -1018,6 +1018,7 @@
|
|
*xstate_bv |= bit;
|
|
}
|
|
}
|
|
+ critical_exit();
|
|
return (owned);
|
|
}
|
|
|
|
@@ -1026,6 +1027,7 @@
|
|
{
|
|
struct pcb *pcb;
|
|
|
|
+ CRITICAL_ASSERT(td);
|
|
pcb = td->td_pcb;
|
|
if (PCB_USER_FPU(pcb))
|
|
pcb->pcb_flags |= PCB_NPXINITDONE;
|
|
@@ -1083,28 +1085,26 @@
|
|
if (cpu_fxsr)
|
|
addr->sv_xmm.sv_env.en_mxcsr &= cpu_mxcsr_mask;
|
|
pcb = td->td_pcb;
|
|
+ error = 0;
|
|
critical_enter();
|
|
if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) {
|
|
error = npxsetxstate(td, xfpustate, xfpustate_size);
|
|
- if (error != 0) {
|
|
- critical_exit();
|
|
- return (error);
|
|
+ if (error == 0) {
|
|
+ if (!cpu_fxsr)
|
|
+ fnclex(); /* As in npxdrop(). */
|
|
+ bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr));
|
|
+ fpurstor(get_pcb_user_save_td(td));
|
|
+ pcb->pcb_flags |= PCB_NPXUSERINITDONE | PCB_NPXINITDONE;
|
|
}
|
|
- if (!cpu_fxsr)
|
|
- fnclex(); /* As in npxdrop(). */
|
|
- bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr));
|
|
- fpurstor(get_pcb_user_save_td(td));
|
|
- critical_exit();
|
|
- pcb->pcb_flags |= PCB_NPXUSERINITDONE | PCB_NPXINITDONE;
|
|
} else {
|
|
- critical_exit();
|
|
error = npxsetxstate(td, xfpustate, xfpustate_size);
|
|
- if (error != 0)
|
|
- return (error);
|
|
- bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr));
|
|
- npxuserinited(td);
|
|
+ if (error == 0) {
|
|
+ bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr));
|
|
+ npxuserinited(td);
|
|
+ }
|
|
}
|
|
- return (0);
|
|
+ critical_exit();
|
|
+ return (error);
|
|
}
|
|
|
|
static void
|
|
@@ -1373,6 +1373,7 @@
|
|
return (0);
|
|
}
|
|
pcb = td->td_pcb;
|
|
+ critical_enter();
|
|
KASSERT(!PCB_USER_FPU(pcb) || pcb->pcb_save ==
|
|
get_pcb_user_save_pcb(pcb), ("mangled pcb_save"));
|
|
ctx->flags = FPU_KERN_CTX_INUSE;
|
|
@@ -1383,6 +1384,7 @@
|
|
pcb->pcb_save = fpu_kern_ctx_savefpu(ctx);
|
|
pcb->pcb_flags |= PCB_KERNNPX;
|
|
pcb->pcb_flags &= ~PCB_NPXINITDONE;
|
|
+ critical_exit();
|
|
return (0);
|
|
}
|
|
|
|
@@ -1401,7 +1403,6 @@
|
|
critical_enter();
|
|
if (curthread == PCPU_GET(fpcurthread))
|
|
npxdrop();
|
|
- critical_exit();
|
|
pcb->pcb_save = ctx->prev;
|
|
if (pcb->pcb_save == get_pcb_user_save_pcb(pcb)) {
|
|
if ((pcb->pcb_flags & PCB_NPXUSERINITDONE) != 0)
|
|
@@ -1416,6 +1417,7 @@
|
|
pcb->pcb_flags &= ~PCB_NPXINITDONE;
|
|
KASSERT(!PCB_USER_FPU(pcb), ("unpaired fpu_kern_leave"));
|
|
}
|
|
+ critical_exit();
|
|
return (0);
|
|
}
|
|
|