diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2007-11-12 14:47:57 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2007-11-12 14:47:57 +0000 |
commit | afb3df9f0afbf723c689164b67e753d0a7b08e06 (patch) | |
tree | af5f125ecadbc3cec939bbf8b9aa5102ae9fefcb /sys/arch/amd64 | |
parent | 5e745dc91cb9de34a00ccf48e8fa133f607058f4 (diff) |
fix some problems with lazy fpu context handling:
put the "fninit" where it belongs logically
deal with XMM exceptions
From NetBSD (drochner)
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r-- | sys/arch/amd64/amd64/fpu.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/sys/arch/amd64/amd64/fpu.c b/sys/arch/amd64/amd64/fpu.c index cc19b095f2d..ae14f4a4a36 100644 --- a/sys/arch/amd64/amd64/fpu.c +++ b/sys/arch/amd64/amd64/fpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu.c,v 1.12 2006/11/29 12:24:17 miod Exp $ */ +/* $OpenBSD: fpu.c,v 1.13 2007/11/12 14:47:56 millert Exp $ */ /* $NetBSD: fpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ /*- @@ -118,7 +118,7 @@ fputrap(struct trapframe *frame) { struct proc *p = curcpu()->ci_fpcurproc; struct savefpu *sfp = &p->p_addr->u_pcb.pcb_savefpu; - u_int32_t statbits; + u_int32_t mxcsr, statbits; u_int16_t cw; int code; union sigval sv; @@ -134,7 +134,10 @@ fputrap(struct trapframe *frame) fxsave(sfp); if (frame->tf_trapno == T_XMM) { - statbits = sfp->fp_fxsave.fx_mxcsr; + mxcsr = sfp->fp_fxsave.fx_mxcsr; + statbits = mxcsr; + mxcsr &= ~0x3f; + ldmxcsr(&mxcsr); } else { fninit(); fwait(); @@ -207,11 +210,6 @@ fpudna(struct cpu_info *ci) if (ci->ci_fpcurproc != NULL && ci->ci_fpcurproc != p) { fpusave_cpu(ci, 1); uvmexp.fpswtch++; - } else { - clts(); - fninit(); - fwait(); - stts(); } splx(s); @@ -237,6 +235,7 @@ fpudna(struct cpu_info *ci) splx(s); if ((p->p_md.md_flags & MDP_USEDFPU) == 0) { + fninit(); fldcw(&p->p_addr->u_pcb.pcb_savefpu.fp_fxsave.fx_fcw); ldmxcsr(&p->p_addr->u_pcb.pcb_savefpu.fp_fxsave.fx_mxcsr); p->p_md.md_flags |= MDP_USEDFPU; |