summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2004-06-18 04:01:54 +0000
committerpeter <peter@FreeBSD.org>2004-06-18 04:01:54 +0000
commit8c286596fcd7a157c6f4293d10e21ced450c765f (patch)
tree7c3c3c00a8147f66ff8fb0ff254880dde41226ee /sys
parent3163bfb503d9be02b08b47903e08eb464713c080 (diff)
downloadFreeBSD-src-8c286596fcd7a157c6f4293d10e21ced450c765f.zip
FreeBSD-src-8c286596fcd7a157c6f4293d10e21ced450c765f.tar.gz
Try harder to give new processes a clean initial fpu state. fpu_cleanstate
wasn't actually clean, it was saving the xmm registers as left over by the bios. fninit() doesn't clear those. In fpudna(), instead of doing a fninit() and forgetting to load the initial mxcsr, do a full fxrstor(&fpu_cleanstate). Otherwise we hand over whatever random values are left in the xmm registers by the last user. I'm not certain of whether this is excessive paranoia or not, but there was an outright bug in neglecting to set the mxcsr value that caused awk to SIGFPE in some case. Especially for Tim Robbins. :-) i386 probably should do something about the mxcsr setings too. Found by: tjr
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/fpu.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c
index d002ef0..38f1c16 100644
--- a/sys/amd64/amd64/fpu.c
+++ b/sys/amd64/amd64/fpu.c
@@ -125,6 +125,8 @@ fpuinit(void)
ldmxcsr(mxcsr);
fxsave(&fpu_cleanstate);
start_emulating();
+ bzero(fpu_cleanstate.sv_fp, sizeof(fpu_cleanstate.sv_fp));
+ bzero(fpu_cleanstate.sv_xmm, sizeof(fpu_cleanstate.sv_xmm));
fpu_cleanstate_ready = 1;
intr_restore(savecrit);
}
@@ -384,7 +386,6 @@ fpudna()
{
struct pcb *pcb;
register_t s;
- u_short control;
if (PCPU_GET(fpcurthread) == curthread) {
printf("fpudna: fpcurthread == curthread %d times\n",
@@ -409,13 +410,10 @@ fpudna()
if ((pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
/*
- * This is the first time this thread has used the FPU or
- * the PCB doesn't contain a clean FPU state. Explicitly
- * initialize the FPU and load the default control word.
+ * This is the first time this thread has used the FPU,
+ * explicitly load sanitized registers.
*/
- fninit();
- control = __INITIAL_FPUCW__;
- fldcw(&control);
+ fxrstor(&fpu_cleanstate);
pcb->pcb_flags |= PCB_FPUINITDONE;
} else
fxrstor(&pcb->pcb_save);
OpenPOWER on IntegriCloud