summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2011-03-20 21:44:09 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2011-03-20 21:44:09 +0000
commit2adbed0e667a38266c5f7af35a555358a3a18065 (patch)
tree0cacbe115f2ec8d48c44183272e96f6a904dabff /sys/arch/amd64
parent66da337841752aaa4e76f748b61818f649a94e5f (diff)
When reading MXCSR from userland sigcontext or a ptrace request,
mask out invalid bits to prevent a protect fault. Original diff by joshe@; further feedback and ok kettenis@
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/amd64/fpu.c17
-rw-r--r--sys/arch/amd64/amd64/machdep.c9
-rw-r--r--sys/arch/amd64/amd64/process_machdep.c5
-rw-r--r--sys/arch/amd64/include/fpu.h4
4 files changed, 28 insertions, 7 deletions
diff --git a/sys/arch/amd64/amd64/fpu.c b/sys/arch/amd64/amd64/fpu.c
index 45d98c1cceb..047468a8fd8 100644
--- a/sys/arch/amd64/amd64/fpu.c
+++ b/sys/arch/amd64/amd64/fpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fpu.c,v 1.21 2010/09/29 15:11:31 joshe Exp $ */
+/* $OpenBSD: fpu.c,v 1.22 2011/03/20 21:44:08 guenther Exp $ */
/* $NetBSD: fpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */
/*-
@@ -96,6 +96,11 @@ void fpudna(struct cpu_info *);
static int x86fpflags_to_siginfo(u_int32_t);
/*
+ * The mxcsr_mask for this host, taken from fxsave() on the primary CPU
+ */
+uint32_t fpu_mxcsr_mask;
+
+/*
* Init the FPU.
*/
void
@@ -103,6 +108,16 @@ fpuinit(struct cpu_info *ci)
{
lcr0(rcr0() & ~(CR0_EM|CR0_TS));
fninit();
+ if (fpu_mxcsr_mask == 0) {
+ struct fxsave64 fx __attribute__((aligned(16)));
+
+ bzero(&fx, sizeof(fx));
+ fxsave(&fx);
+ if (fx.fx_mxcsr_mask)
+ fpu_mxcsr_mask = fx.fx_mxcsr_mask;
+ else
+ fpu_mxcsr_mask = __INITIAL_MXCSR_MASK__;
+ }
lcr0(rcr0() | (CR0_TS));
}
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index bff89202e01..2a961d94d3e 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.131 2011/03/18 03:10:47 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.132 2011/03/20 21:44:08 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
@@ -655,9 +655,11 @@ sys_sigreturn(struct proc *p, void *v, register_t *retval)
fpusave_proc(p, 0);
if (ksc.sc_fpstate) {
- if ((error = copyin(ksc.sc_fpstate,
- &p->p_addr->u_pcb.pcb_savefpu.fp_fxsave, sizeof (struct fxsave64))))
+ struct fxsave64 *fx = &p->p_addr->u_pcb.pcb_savefpu.fp_fxsave;
+
+ if ((error = copyin(ksc.sc_fpstate, fx, sizeof(*fx))))
return (error);
+ fx->fx_mxcsr &= fpu_mxcsr_mask;
p->p_md.md_flags |= MDP_USEDFPU;
}
@@ -1504,6 +1506,7 @@ init_x86_64(paddr_t first_avail)
cpu_init_idt();
intr_default_setup();
+ fpuinit(&cpu_info_primary);
softintr_init();
splraise(IPL_IPI);
diff --git a/sys/arch/amd64/amd64/process_machdep.c b/sys/arch/amd64/amd64/process_machdep.c
index 98febadb35e..5ea4192a7e1 100644
--- a/sys/arch/amd64/amd64/process_machdep.c
+++ b/sys/arch/amd64/amd64/process_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: process_machdep.c,v 1.9 2010/09/29 15:11:31 joshe Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.10 2011/03/20 21:44:08 guenther Exp $ */
/* $NetBSD: process_machdep.c,v 1.1 2003/04/26 18:39:31 fvdl Exp $ */
/*-
@@ -137,7 +137,7 @@ process_read_fpregs(struct proc *p, struct fpreg *regs)
frame->fx_fsw = 0x0000;
frame->fx_ftw = 0xff;
frame->fx_mxcsr = __INITIAL_MXCSR__;
- frame->fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
+ frame->fx_mxcsr_mask = fpu_mxcsr_mask;
p->p_md.md_flags |= MDP_USEDFPU;
}
@@ -198,6 +198,7 @@ process_write_fpregs(struct proc *p, struct fpreg *regs)
}
memcpy(frame, &regs->fxstate, sizeof(*regs));
+ frame->fx_mxcsr &= fpu_mxcsr_mask;
return (0);
}
diff --git a/sys/arch/amd64/include/fpu.h b/sys/arch/amd64/include/fpu.h
index 612e1bb0137..345bebbb8ce 100644
--- a/sys/arch/amd64/include/fpu.h
+++ b/sys/arch/amd64/include/fpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: fpu.h,v 1.7 2010/11/20 20:11:17 miod Exp $ */
+/* $OpenBSD: fpu.h,v 1.8 2011/03/20 21:44:08 guenther Exp $ */
/* $NetBSD: fpu.h,v 1.1 2003/04/26 18:39:40 fvdl Exp $ */
#ifndef _AMD64_FPU_H_
@@ -49,6 +49,8 @@ struct savefpu {
struct trapframe;
struct cpu_info;
+extern uint32_t fpu_mxcsr_mask;
+
void fpuinit(struct cpu_info *);
void fpudrop(void);
void fpudiscard(struct proc *);