diff options
author | davidxu <davidxu@FreeBSD.org> | 2006-06-19 22:36:01 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2006-06-19 22:36:01 +0000 |
commit | 01169f1b552b7e4e1a030d3ba27674cfbdbff346 (patch) | |
tree | ca4a7e2072526b7fc9a6e384b4fe0814d744eb5f /sys/amd64 | |
parent | f5cde2819f76cb3f86ff02a0c422b289ce94a096 (diff) | |
download | FreeBSD-src-01169f1b552b7e4e1a030d3ba27674cfbdbff346.zip FreeBSD-src-01169f1b552b7e4e1a030d3ba27674cfbdbff346.tar.gz |
MFi386:
Use the method described in IA-32 Intel Architecture Software
Developer's Manual chapter 11.6.6 to get valid mxcsr bits,
use the mxcsr mask to clear invalid bits passed by user code.
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/fpu.c | 4 | ||||
-rw-r--r-- | sys/amd64/amd64/machdep.c | 7 | ||||
-rw-r--r-- | sys/amd64/include/md_var.h | 1 |
3 files changed, 10 insertions, 2 deletions
diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c index 06a7d5d..513b36b 100644 --- a/sys/amd64/amd64/fpu.c +++ b/sys/amd64/amd64/fpu.c @@ -125,6 +125,10 @@ fpuinit(void) mxcsr = __INITIAL_MXCSR__; ldmxcsr(mxcsr); fxsave(&fpu_cleanstate); + if (fpu_cleanstate.sv_env.en_mxcsr_mask) + cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask; + else + cpu_mxcsr_mask = 0xFFBF; start_emulating(); bzero(fpu_cleanstate.sv_fp, sizeof(fpu_cleanstate.sv_fp)); bzero(fpu_cleanstate.sv_xmm, sizeof(fpu_cleanstate.sv_xmm)); diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 0260462..43c19d3 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -1507,7 +1507,7 @@ set_fpregs_xmm(struct fpreg *fpregs, struct savefpu *sv_xmm) penv_xmm->en_rip = penv_fpreg->en_rip; penv_xmm->en_rdp = penv_fpreg->en_rdp; penv_xmm->en_mxcsr = penv_fpreg->en_mxcsr; - penv_xmm->en_mxcsr_mask = penv_fpreg->en_mxcsr_mask; + penv_xmm->en_mxcsr_mask = penv_fpreg->en_mxcsr_mask & cpu_mxcsr_mask; /* FPU registers */ for (i = 0; i < 8; ++i) @@ -1634,6 +1634,7 @@ get_fpcontext(struct thread *td, mcontext_t *mcp) static int set_fpcontext(struct thread *td, const mcontext_t *mcp) { + struct savefpu *fpstate; if (mcp->mc_fpformat == _MC_FPFMT_NODEV) return (0); @@ -1649,7 +1650,9 @@ set_fpcontext(struct thread *td, const mcontext_t *mcp) * be called with interrupts disabled. * XXX obsolete on trap-16 systems? */ - fpusetregs(td, (struct savefpu *)&mcp->mc_fpstate); + fpstate = (struct savefpu *)&mcp->mc_fpstate; + fpstate->sv_env.en_mxcsr &= cpu_mxcsr_mask; + fpusetregs(td, fpstate); } else return (EINVAL); return (0); diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h index 4e421ee..03220e6 100644 --- a/sys/amd64/include/md_var.h +++ b/sys/amd64/include/md_var.h @@ -47,6 +47,7 @@ extern u_int amd_feature2; extern u_int cpu_fxsr; extern u_int cpu_high; extern u_int cpu_id; +extern u_int cpu_mxcsr_mask; extern u_int cpu_procinfo; extern u_int cpu_procinfo2; extern char cpu_vendor[]; |