From fa9df4abe12110a487787e1d598d0c05af348a13 Mon Sep 17 00:00:00 2001 From: davidxu Date: Tue, 30 May 2006 23:44:21 +0000 Subject: 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 --- sys/i386/i386/initcpu.c | 1 + sys/i386/i386/machdep.c | 6 +++--- sys/i386/i386/ptrace_machdep.c | 11 +++++------ sys/i386/include/md_var.h | 1 + sys/i386/include/npx.h | 4 ++-- sys/i386/isa/npx.c | 9 +++++++++ 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); } -- cgit v1.1