summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2006-06-19 22:36:01 +0000
committerdavidxu <davidxu@FreeBSD.org>2006-06-19 22:36:01 +0000
commit01169f1b552b7e4e1a030d3ba27674cfbdbff346 (patch)
treeca4a7e2072526b7fc9a6e384b4fe0814d744eb5f /sys/amd64
parentf5cde2819f76cb3f86ff02a0c422b289ce94a096 (diff)
downloadFreeBSD-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.c4
-rw-r--r--sys/amd64/amd64/machdep.c7
-rw-r--r--sys/amd64/include/md_var.h1
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[];
OpenPOWER on IntegriCloud