summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2004-07-20 21:04:38 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2004-07-20 21:04:38 +0000
commitb1d18f37db4c5298c66cc14d70dae75dd8d762d0 (patch)
tree49e0d022c7330652e1b9c47fdd917b16b512cfa3
parenta807708f9b935b50cccfd43d269ce2fd7927cb42 (diff)
Properly initialize FPU state if it hasn't been used yet.
ok deraadt@
-rw-r--r--sys/arch/i386/i386/process_machdep.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/sys/arch/i386/i386/process_machdep.c b/sys/arch/i386/i386/process_machdep.c
index 61eccce92b4..31fac01b813 100644
--- a/sys/arch/i386/i386/process_machdep.c
+++ b/sys/arch/i386/i386/process_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: process_machdep.c,v 1.18 2004/07/20 18:59:21 kettenis Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.19 2004/07/20 21:04:37 kettenis Exp $ */
/* $NetBSD: process_machdep.c,v 1.22 1996/05/03 19:42:25 christos Exp $ */
/*
@@ -207,24 +207,47 @@ process_read_fpregs(p, regs)
struct proc *p;
struct fpreg *regs;
{
+ union savefpu *frame = process_fpframe(p);
if (p->p_md.md_flags & MDP_USEDFPU) {
- union savefpu *frame = process_fpframe(p);
-
#if NNPX > 0
npxsave_proc(p, 1);
#endif
-
+ } else {
+ /*
+ * Fake a FNINIT.
+ * The initial control word was already set by setregs(), so
+ * save it temporarily.
+ */
if (i386_use_fxsave) {
- struct save87 s87;
+ uint32_t mxcsr = frame->sv_xmm.sv_env.en_mxcsr;
+ uint16_t cw = frame->sv_xmm.sv_env.en_cw;
+
+ /* XXX Don't zero XMM regs? */
+ memset(&frame->sv_xmm, 0, sizeof(frame->sv_xmm));
+ frame->sv_xmm.sv_env.en_cw = cw;
+ frame->sv_xmm.sv_env.en_mxcsr = mxcsr;
+ frame->sv_xmm.sv_env.en_sw = 0x0000;
+ frame->sv_xmm.sv_env.en_tw = 0x00;
+ } else {
+ uint16_t cw = frame->sv_87.sv_env.en_cw;
+
+ memset(&frame->sv_87, 0, sizeof(frame->sv_87));
+ frame->sv_87.sv_env.en_cw = cw;
+ frame->sv_87.sv_env.en_sw = 0x0000;
+ frame->sv_87.sv_env.en_tw = 0xffff;
+ }
+ p->p_md.md_flags |= MDP_USEDFPU;
+ }
+
+ if (i386_use_fxsave) {
+ struct save87 s87;
- /* XXX Yuck */
- process_xmm_to_s87(&frame->sv_xmm, &s87);
- memcpy(regs, &s87, sizeof(*regs));
- } else
- bcopy(frame, regs, sizeof(*regs));
+ /* XXX Yuck */
+ process_xmm_to_s87(&frame->sv_xmm, &s87);
+ memcpy(regs, &s87, sizeof(*regs));
} else
- bzero(regs, sizeof(*regs));
+ memcpy(regs, &frame->sv_87, sizeof(*regs));
return (0);
}