summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2006-05-30 23:44:21 +0000
committerdavidxu <davidxu@FreeBSD.org>2006-05-30 23:44:21 +0000
commitfa9df4abe12110a487787e1d598d0c05af348a13 (patch)
tree8fe4415c7c155100ca395c3fcc5aca0e656c49c0
parente96ef6e51ce2eada4161f8c46c031c67179ff703 (diff)
downloadFreeBSD-src-fa9df4abe12110a487787e1d598d0c05af348a13.zip
FreeBSD-src-fa9df4abe12110a487787e1d598d0c05af348a13.tar.gz
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. Reviewed by: bde
-rw-r--r--sys/i386/i386/initcpu.c1
-rw-r--r--sys/i386/i386/machdep.c6
-rw-r--r--sys/i386/i386/ptrace_machdep.c11
-rw-r--r--sys/i386/include/md_var.h1
-rw-r--r--sys/i386/include/npx.h4
-rw-r--r--sys/i386/isa/npx.c9
6 files changed, 21 insertions, 11 deletions
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c
index 9bb89d5..9fc5a05 100644
--- a/sys/i386/i386/initcpu.c
+++ b/sys/i386/i386/initcpu.c
@@ -87,6 +87,7 @@ char cpu_vendor[20] = ""; /* CPU Origin code */
#ifdef CPU_ENABLE_SSE
u_int cpu_fxsr; /* SSE enabled */
+u_int cpu_mxcsr_mask; /* valid bits in mxcsr */
#endif
#ifdef I486_CPU
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index ce4891f..4c455cd 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -2710,9 +2710,9 @@ set_fpcontext(struct thread *td, const mcontext_t *mcp)
bcopy(&mcp->mc_fpstate, addr, sizeof(mcp->mc_fpstate));
}
#ifdef DEV_NPX
- /* clear high 16 bits of mxcsr to avoid security problem. */
- if (cpu_fxsr)
- addr->sv_xmm.sv_env.en_mxcsr &= 0xFFFF;
+#ifdef CPU_ENABLE_SSE
+ addr->sv_xmm.sv_env.en_mxcsr &= cpu_mxcsr_mask;
+#endif
/*
* XXX we violate the dubious requirement that npxsetregs()
* be called with interrupts disabled.
diff --git a/sys/i386/i386/ptrace_machdep.c b/sys/i386/i386/ptrace_machdep.c
index b002651..409db16 100644
--- a/sys/i386/i386/ptrace_machdep.c
+++ b/sys/i386/i386/ptrace_machdep.c
@@ -45,22 +45,21 @@ int
cpu_ptrace(struct thread *td, int req, void *addr, int data)
{
#ifdef CPU_ENABLE_SSE
+ struct savexmm *fpstate;
int error;
if (!cpu_fxsr)
return (EINVAL);
+ fpstate = &td->td_pcb->pcb_save.sv_xmm;
switch (req) {
case PT_GETXMMREGS:
- error = copyout(&td->td_pcb->pcb_save.sv_xmm, addr,
- sizeof(td->td_pcb->pcb_save.sv_xmm));
+ error = copyout(fpstate, addr, sizeof(*fpstate));
break;
case PT_SETXMMREGS:
- error = copyin(addr, &td->td_pcb->pcb_save.sv_xmm,
- sizeof(td->td_pcb->pcb_save.sv_xmm));
- /* clear high 16 bits of mxcsr to avoid security problem. */
- td->td_pcb->pcb_save.sv_xmm.sv_env.en_mxcsr &= 0xFFFF;
+ error = copyin(addr, fpstate, sizeof(*fpstate));
+ fpstate->sv_env.en_mxcsr &= cpu_mxcsr_mask;
break;
default:
diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h
index 92b7152..b0d640c 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/include/md_var.h
@@ -52,6 +52,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[];
diff --git a/sys/i386/include/npx.h b/sys/i386/include/npx.h
index 86b9af8..11f1034 100644
--- a/sys/i386/include/npx.h
+++ b/sys/i386/include/npx.h
@@ -92,8 +92,8 @@ struct envxmm {
u_int32_t en_foo; /* floating operand offset */
u_int16_t en_fos; /* floating operand segment selector */
u_int16_t en_pad1; /* padding */
- u_int32_t en_mxcsr; /* SSE sontorol/status register */
- u_int32_t en_pad2; /* padding */
+ u_int32_t en_mxcsr; /* SSE control/status register */
+ u_int32_t en_mxcsr_mask; /* valid bits in mxcsr */
};
/* Contents of each SSE extended accumulator */
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index bc39629..ba202fc 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -417,6 +417,15 @@ npx_attach(dev)
stop_emulating();
fpusave(&npx_cleanstate);
start_emulating();
+#ifdef CPU_ENABLE_SSE
+ if (cpu_fxsr) {
+ if (npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask)
+ cpu_mxcsr_mask =
+ npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask;
+ else
+ cpu_mxcsr_mask = 0xFFBF;
+ }
+#endif
npx_cleanstate_ready = 1;
intr_restore(s);
}
OpenPOWER on IntegriCloud