Module Name: src
Committed By: dsl
Date: Sat Feb 15 10:11:15 UTC 2014
Modified Files:
src/sys/arch/amd64/amd64: genassym.cf machdep.c netbsd32_machdep.c
process_machdep.c
src/sys/arch/amd64/include: proc.h
src/sys/arch/i386/i386: compat_16_machdep.c genassym.cf machdep.c
process_machdep.c
src/sys/arch/i386/include: proc.h
src/sys/arch/x86/include: cpu.h cpu_extended_state.h fpu.h
src/sys/arch/x86/x86: fpu.c vm_machdep.c
src/sys/compat/linux/arch/amd64: linux_machdep.c
src/sys/compat/linux/arch/i386: linux_machdep.c
src/sys/compat/linux32/arch/amd64: linux32_machdep.c
Log Message:
Remove all references to MDL_USEDFPU and deferred fpu initialisation.
The cost of zeroing the save area on exec is minimal.
This stops the FP registers of a random process being used the first
time an lwp uses the fpu.
sendsig_siginfo() and get_mcontext() now unconditionally copy the FP
registers.
I'll remove the double-copy for signal handlers soon.
get_mcontext() might have been leaking kernel memory to userspace - and
may still do so if i386_use_fxsave is false (short copies).
To generate a diff of this commit:
cvs rdiff -u -r1.54 -r1.55 src/sys/arch/amd64/amd64/genassym.cf
cvs rdiff -u -r1.203 -r1.204 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.90 -r1.91 src/sys/arch/amd64/amd64/netbsd32_machdep.c
cvs rdiff -u -r1.27 -r1.28 src/sys/arch/amd64/amd64/process_machdep.c
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/amd64/include/proc.h
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/i386/i386/compat_16_machdep.c
cvs rdiff -u -r1.96 -r1.97 src/sys/arch/i386/i386/genassym.cf
cvs rdiff -u -r1.746 -r1.747 src/sys/arch/i386/i386/machdep.c
cvs rdiff -u -r1.82 -r1.83 src/sys/arch/i386/i386/process_machdep.c
cvs rdiff -u -r1.40 -r1.41 src/sys/arch/i386/include/proc.h
cvs rdiff -u -r1.61 -r1.62 src/sys/arch/x86/include/cpu.h
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/x86/include/cpu_extended_state.h
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/x86/include/fpu.h
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/x86/x86/fpu.c
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/x86/x86/vm_machdep.c
cvs rdiff -u -r1.46 -r1.47 src/sys/compat/linux/arch/amd64/linux_machdep.c
cvs rdiff -u -r1.156 -r1.157 src/sys/compat/linux/arch/i386/linux_machdep.c
cvs rdiff -u -r1.34 -r1.35 \
src/sys/compat/linux32/arch/amd64/linux32_machdep.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/amd64/amd64/genassym.cf
diff -u src/sys/arch/amd64/amd64/genassym.cf:1.54 src/sys/arch/amd64/amd64/genassym.cf:1.55
--- src/sys/arch/amd64/amd64/genassym.cf:1.54 Sun Dec 1 01:05:16 2013
+++ src/sys/arch/amd64/amd64/genassym.cf Sat Feb 15 10:11:14 2014
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.54 2013/12/01 01:05:16 christos Exp $
+# $NetBSD: genassym.cf,v 1.55 2014/02/15 10:11:14 dsl Exp $
#
# Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -185,7 +185,6 @@ define PCB_USERSP offsetof(struct pcb,
define PCB_RSP0 offsetof(struct pcb, pcb_rsp0)
define PCB_CR0 offsetof(struct pcb, pcb_cr0)
define PCB_ONFAULT offsetof(struct pcb, pcb_onfault)
-define PCB_FPCPU offsetof(struct pcb, pcb_fpcpu)
define PCB_FLAGS offsetof(struct pcb, pcb_flags)
define PCB_COMPAT32 PCB_COMPAT32
define PCB_FS offsetof(struct pcb, pcb_fs)
Index: src/sys/arch/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.203 src/sys/arch/amd64/amd64/machdep.c:1.204
--- src/sys/arch/amd64/amd64/machdep.c:1.203 Tue Feb 11 20:17:16 2014
+++ src/sys/arch/amd64/amd64/machdep.c Sat Feb 15 10:11:14 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.203 2014/02/11 20:17:16 dsl Exp $ */
+/* $NetBSD: machdep.c,v 1.204 2014/02/15 10:11:14 dsl Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@@ -111,7 +111,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.203 2014/02/11 20:17:16 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.204 2014/02/15 10:11:14 dsl Exp $");
/* #define XENDEBUG_LOW */
@@ -548,8 +548,8 @@ buildcontext(struct lwp *l, void *catche
tf->tf_rsp = (uint64_t)f;
tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
- /* Ensure FP state is reset, if FP is used. */
- l->l_md.md_flags &= ~MDL_USEDFPU;
+ /* Ensure FP state is sane */
+ fpu_save_area_reset(l);
}
void
@@ -566,7 +566,7 @@ sendsig_siginfo(const ksiginfo_t *ksi, c
struct lwp *l = curlwp;
struct proc *p = l->l_proc;
struct sigacts *ps = p->p_sigacts;
- int onstack, tocopy, error;
+ int onstack, error;
int sig = ksi->ksi_signo;
struct sigframe_siginfo *fp, frame;
sig_t catcher = SIGACTION(p, sig).sa_handler;
@@ -587,21 +587,9 @@ sendsig_siginfo(const ksiginfo_t *ksi, c
sp = (char *)tf->tf_rsp - 128;
sp -= sizeof(struct sigframe_siginfo);
- /*
- * Round down the stackpointer to a multiple of 16 for
- * fxsave and the ABI.
- */
+ /* Round down the stackpointer to a multiple of 16 for the ABI. */
fp = (struct sigframe_siginfo *)(((unsigned long)sp & ~15) - 8);
- /*
- * Don't bother copying out FP state if there is none.
- */
- if (l->l_md.md_flags & MDL_USEDFPU)
- tocopy = sizeof (struct sigframe_siginfo);
- else
- tocopy = sizeof (struct sigframe_siginfo) -
- sizeof (frame.sf_uc.uc_mcontext.__fpregs);
-
frame.sf_ra = (uint64_t)ps->sa_sigdesc[sig].sd_tramp;
frame.sf_si._info = ksi->ksi_info;
frame.sf_uc.uc_flags = _UC_SIGMASK;
@@ -614,7 +602,8 @@ sendsig_siginfo(const ksiginfo_t *ksi, c
mutex_exit(p->p_lock);
cpu_getmcontext(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags);
- error = copyout(&frame, fp, tocopy);
+ /* Copyout all the fp regs, the signal handler might expect them. */
+ error = copyout(&frame, fp, sizeof frame);
mutex_enter(p->p_lock);
if (error != 0) {
@@ -1329,23 +1318,13 @@ setregs(struct lwp *l, struct exec_packa
struct pcb *pcb = lwp_getpcb(l);
struct trapframe *tf;
- /* If we were using the FPU, forget about it. */
- if (pcb->pcb_fpcpu != NULL) {
- fpusave_lwp(l, false);
- }
-
#ifdef USER_LDT
pmap_ldt_cleanup(l);
#endif
- l->l_md.md_flags &= ~MDL_USEDFPU;
+ fpu_save_area_clear(l, pack->ep_osversion >= 699002600
+ ? __NetBSD_NPXCW__ : __NetBSD_COMPAT_NPXCW__);
pcb->pcb_flags = 0;
- if (pack->ep_osversion >= 699002600)
- pcb->pcb_savefpu.sv_xmm.fx_cw = __NetBSD_NPXCW__;
- else
- pcb->pcb_savefpu.sv_xmm.fx_cw = __NetBSD_COMPAT_NPXCW__;
- pcb->pcb_savefpu.sv_xmm.fx_mxcsr = __INITIAL_MXCSR__;
- pcb->pcb_savefpu.sv_xmm.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
l->l_proc->p_flag &= ~PK_32;
@@ -1917,6 +1896,7 @@ void
cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags)
{
const struct trapframe *tf = l->l_md.md_regs;
+ struct pcb *pcb;
__greg_t ras_rip;
/* Copy general registers member by member */
@@ -1933,16 +1913,11 @@ cpu_getmcontext(struct lwp *l, mcontext_
mcp->_mc_tlsbase = (uintptr_t)l->l_private;;
*flags |= _UC_TLSBASE;
- if ((l->l_md.md_flags & MDL_USEDFPU) != 0) {
- struct pcb *pcb = lwp_getpcb(l);
+ pcb = lwp_getpcb(l);
- if (pcb->pcb_fpcpu) {
- fpusave_lwp(l, true);
- }
- memcpy(mcp->__fpregs, &pcb->pcb_savefpu.sv_xmm,
- sizeof (mcp->__fpregs));
- *flags |= _UC_FPU;
- }
+ fpusave_lwp(l, true);
+ memcpy(mcp->__fpregs, &pcb->pcb_savefpu.sv_xmm, sizeof (mcp->__fpregs));
+ *flags |= _UC_FPU;
}
int
@@ -1991,13 +1966,10 @@ cpu_setmcontext(struct lwp *l, const mco
l->l_md.md_flags |= MDL_IRET;
}
- if (pcb->pcb_fpcpu != NULL)
- fpusave_lwp(l, false);
-
if ((flags & _UC_FPU) != 0) {
+ fpusave_lwp(l, false);
memcpy(&pcb->pcb_savefpu.sv_xmm, mcp->__fpregs,
sizeof (mcp->__fpregs));
- l->l_md.md_flags |= MDL_USEDFPU;
}
if ((flags & _UC_TLSBASE) != 0)
Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c
diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.90 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.91
--- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.90 Tue Feb 11 20:17:16 2014
+++ src/sys/arch/amd64/amd64/netbsd32_machdep.c Sat Feb 15 10:11:14 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_machdep.c,v 1.90 2014/02/11 20:17:16 dsl Exp $ */
+/* $NetBSD: netbsd32_machdep.c,v 1.91 2014/02/15 10:11:14 dsl Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.90 2014/02/11 20:17:16 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.91 2014/02/15 10:11:14 dsl Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@@ -128,26 +128,17 @@ netbsd32_setregs(struct lwp *l, struct e
pcb = lwp_getpcb(l);
- /* If we were using the FPU, forget about it. */
- if (pcb->pcb_fpcpu != NULL) {
- fpusave_lwp(l, false);
- }
-
#if defined(USER_LDT) && 0
pmap_ldt_cleanup(p);
#endif
netbsd32_adjust_limits(p);
- l->l_md.md_flags &= ~MDL_USEDFPU;
l->l_md.md_flags |= MDL_COMPAT32; /* Force iret not sysret */
pcb->pcb_flags = PCB_COMPAT32;
- if (pack->ep_osversion >= 699002600)
- pcb->pcb_savefpu.sv_xmm.fx_cw = __NetBSD_NPXCW__;
- else
- pcb->pcb_savefpu.sv_xmm.fx_cw = __NetBSD_COMPAT_NPXCW__;
- pcb->pcb_savefpu.sv_xmm.fx_mxcsr = __INITIAL_MXCSR__;
- pcb->pcb_savefpu.sv_xmm.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
+
+ fpu_save_area_clear(l, pack->ep_osversion >= 699002600
+ ? __NetBSD_NPXCW__ : __NetBSD_COMPAT_NPXCW__);
p->p_flag |= PK_32;
@@ -263,8 +254,8 @@ netbsd32_sendsig_sigcontext(const ksigin
tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL);
tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL);
- /* Ensure FP state is reset, if FP is used. */
- l->l_md.md_flags &= ~MDL_USEDFPU;
+ /* Ensure FP state is sane. */
+ fpu_save_area_reset(l);
tf->tf_rip = (uint64_t)catcher;
tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL);
@@ -366,8 +357,8 @@ netbsd32_sendsig_siginfo(const ksiginfo_
tf->tf_rsp = (uint64_t)fp;
tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL);
- /* Ensure FP state is reset, if FP is used. */
- l->l_md.md_flags &= ~MDL_USEDFPU;
+ /* Ensure FP state is sane. */
+ fpu_save_area_reset(l);
/* Remember that we're now on the signal stack. */
if (onstack)
@@ -820,13 +811,9 @@ cpu_setmcontext32(struct lwp *l, const m
/*
* If we were using the FPU, forget that we were.
*/
- if (pcb->pcb_fpcpu != NULL) {
- fpusave_lwp(l, false);
- }
+ fpusave_lwp(l, false);
memcpy(&pcb->pcb_savefpu.sv_xmm, &mcp->__fpregs,
sizeof (pcb->pcb_savefpu.sv_xmm));
- /* If not set already. */
- l->l_md.md_flags |= MDL_USEDFPU;
}
mutex_enter(p->p_lock);
@@ -845,6 +832,7 @@ cpu_getmcontext32(struct lwp *l, mcontex
const struct trapframe *tf = l->l_md.md_regs;
__greg32_t *gr = mcp->__gregs;
__greg32_t ras_eip;
+ struct pcb *pcb;
/* Save register context. */
gr[_REG32_GS] = tf->tf_gs;
@@ -876,17 +864,12 @@ cpu_getmcontext32(struct lwp *l, mcontex
mcp->_mc_tlsbase = (uint32_t)(uintptr_t)l->l_private;
*flags |= _UC_TLSBASE;
- /* Save floating point register context, if any. */
- if ((l->l_md.md_flags & MDL_USEDFPU) != 0) {
- struct pcb *pcb = lwp_getpcb(l);
-
- if (pcb->pcb_fpcpu) {
- fpusave_lwp(l, true);
- }
- memcpy(&mcp->__fpregs, &pcb->pcb_savefpu.sv_xmm,
- sizeof (pcb->pcb_savefpu.sv_xmm));
- *flags |= _UC_FPU;
- }
+ /* Save floating point register context. */
+ fpusave_lwp(l, true);
+ pcb = lwp_getpcb(l);
+ memcpy(&mcp->__fpregs, &pcb->pcb_savefpu.sv_xmm,
+ sizeof (pcb->pcb_savefpu.sv_xmm));
+ *flags |= _UC_FPU;
}
void
Index: src/sys/arch/amd64/amd64/process_machdep.c
diff -u src/sys/arch/amd64/amd64/process_machdep.c:1.27 src/sys/arch/amd64/amd64/process_machdep.c:1.28
--- src/sys/arch/amd64/amd64/process_machdep.c:1.27 Tue Feb 11 20:17:16 2014
+++ src/sys/arch/amd64/amd64/process_machdep.c Sat Feb 15 10:11:14 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: process_machdep.c,v 1.27 2014/02/11 20:17:16 dsl Exp $ */
+/* $NetBSD: process_machdep.c,v 1.28 2014/02/15 10:11:14 dsl Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -53,7 +53,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.27 2014/02/11 20:17:16 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.28 2014/02/15 10:11:14 dsl Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -103,34 +103,12 @@ process_read_regs(struct lwp *l, struct
}
int
-process_read_fpregs(struct lwp *l, struct fpreg *regs,size_t *sz)
+process_read_fpregs(struct lwp *l, struct fpreg *regs, size_t *sz)
{
- struct fxsave *frame = process_fpframe(l);
- if (l->l_md.md_flags & MDL_USEDFPU) {
- fpusave_lwp(l, true);
- } else {
- uint16_t cw;
- uint32_t mxcsr, mxcsr_mask;
-
- /*
- * Fake a FNINIT.
- * The initial control word was already set by setregs(), so
- * save it temporarily.
- */
- cw = frame->fx_cw;
- mxcsr = frame->fx_mxcsr;
- mxcsr_mask = frame->fx_mxcsr_mask;
- memset(frame, 0, sizeof(*regs));
- frame->fx_cw = cw;
- frame->fx_sw = 0x0000;
- frame->fx_tw = 0x00; /* abridged tag; all empty */
- frame->fx_mxcsr = mxcsr;
- frame->fx_mxcsr_mask = mxcsr_mask;
- l->l_md.md_flags |= MDL_USEDFPU;
- }
+ fpusave_lwp(l, true);
- regs->fxstate = *frame;
+ regs->fxstate = *process_fpframe(l);
return (0);
}
@@ -160,15 +138,10 @@ process_write_regs(struct lwp *l, const
int
process_write_fpregs(struct lwp *l, const struct fpreg *regs, size_t sz)
{
- struct fxsave *frame = process_fpframe(l);
- if (l->l_md.md_flags & MDL_USEDFPU) {
- fpusave_lwp(l, false);
- } else {
- l->l_md.md_flags |= MDL_USEDFPU;
- }
+ fpusave_lwp(l, false);
- memcpy(frame, ®s->fxstate, sizeof(*regs));
+ memcpy(process_fpframe(l), ®s->fxstate, sizeof(*regs));
return (0);
}
Index: src/sys/arch/amd64/include/proc.h
diff -u src/sys/arch/amd64/include/proc.h:1.17 src/sys/arch/amd64/include/proc.h:1.18
--- src/sys/arch/amd64/include/proc.h:1.17 Sun Dec 1 01:05:16 2013
+++ src/sys/arch/amd64/include/proc.h Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: proc.h,v 1.17 2013/12/01 01:05:16 christos Exp $ */
+/* $NetBSD: proc.h,v 1.18 2014/02/15 10:11:15 dsl Exp $ */
/*
* Copyright (c) 1991 Regents of the University of California.
@@ -53,7 +53,6 @@ struct mdlwp {
volatile int md_astpending;
};
-#define MDL_USEDFPU 0x0001 /* has used the FPU */
#define MDL_COMPAT32 0x0008 /* i386, always return via iret */
#define MDL_IRET 0x0010 /* force return via iret, not sysret */
Index: src/sys/arch/i386/i386/compat_16_machdep.c
diff -u src/sys/arch/i386/i386/compat_16_machdep.c:1.24 src/sys/arch/i386/i386/compat_16_machdep.c:1.25
--- src/sys/arch/i386/i386/compat_16_machdep.c:1.24 Sun Dec 1 01:05:16 2013
+++ src/sys/arch/i386/i386/compat_16_machdep.c Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: compat_16_machdep.c,v 1.24 2013/12/01 01:05:16 christos Exp $ */
+/* $NetBSD: compat_16_machdep.c,v 1.25 2014/02/15 10:11:15 dsl Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.24 2013/12/01 01:05:16 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.25 2014/02/15 10:11:15 dsl Exp $");
#ifdef _KERNEL_OPT
#include "opt_vm86.h"
@@ -260,9 +260,8 @@ sendsig_sigcontext(const ksiginfo_t *ksi
/* NOTREACHED */
}
- int svufpu = l->l_md.md_flags & MDL_USEDFPU;
+ fpu_save_area_reset(l);
buildcontext(l, sel, catcher, fp);
- l->l_md.md_flags |= svufpu;
/* Remember that we're now on the signal stack. */
if (onstack)
Index: src/sys/arch/i386/i386/genassym.cf
diff -u src/sys/arch/i386/i386/genassym.cf:1.96 src/sys/arch/i386/i386/genassym.cf:1.97
--- src/sys/arch/i386/i386/genassym.cf:1.96 Sun Dec 1 01:05:16 2013
+++ src/sys/arch/i386/i386/genassym.cf Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.96 2013/12/01 01:05:16 christos Exp $
+# $NetBSD: genassym.cf,v 1.97 2014/02/15 10:11:15 dsl Exp $
#
# Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -204,7 +204,6 @@ define PCB_ESP offsetof(struct pcb, pc
define PCB_ESP0 offsetof(struct pcb, pcb_esp0)
define PCB_CR0 offsetof(struct pcb, pcb_cr0)
define PCB_ONFAULT offsetof(struct pcb, pcb_onfault)
-define PCB_FPCPU offsetof(struct pcb, pcb_fpcpu)
define PCB_FSD offsetof(struct pcb, pcb_fsd)
define PCB_GSD offsetof(struct pcb, pcb_gsd)
define PCB_IOMAP offsetof(struct pcb, pcb_iomap)
Index: src/sys/arch/i386/i386/machdep.c
diff -u src/sys/arch/i386/i386/machdep.c:1.746 src/sys/arch/i386/i386/machdep.c:1.747
--- src/sys/arch/i386/i386/machdep.c:1.746 Tue Feb 4 22:48:26 2014
+++ src/sys/arch/i386/i386/machdep.c Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.746 2014/02/04 22:48:26 dsl Exp $ */
+/* $NetBSD: machdep.c,v 1.747 2014/02/15 10:11:15 dsl Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.746 2014/02/04 22:48:26 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.747 2014/02/15 10:11:15 dsl Exp $");
#include "opt_beep.h"
#include "opt_compat_ibcs2.h"
@@ -667,8 +667,8 @@ buildcontext(struct lwp *l, int sel, voi
tf->tf_esp = (int)fp;
tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
- /* Ensure FP state is reset, if FP is used. */
- l->l_md.md_flags &= ~MDL_USEDFPU;
+ /* Ensure FP state is reset. */
+ fpu_save_area_reset(l);
}
void
@@ -865,27 +865,14 @@ setregs(struct lwp *l, struct exec_packa
struct pmap *pmap = vm_map_pmap(&l->l_proc->p_vmspace->vm_map);
struct pcb *pcb = lwp_getpcb(l);
struct trapframe *tf;
- uint16_t control;
-
- /* If we were using the FPU, forget about it. */
- if (pcb->pcb_fpcpu != NULL)
- fpusave_lwp(l, false);
#ifdef USER_LDT
pmap_ldt_cleanup(l);
#endif
- if (pack->ep_osversion >= 699002600)
- control = __INITIAL_NPXCW__;
- else
- control = __NetBSD_COMPAT_NPXCW__;
+ fpu_save_area_clear(l, pack->ep_osversion >= 699002600
+ ? __INITIAL_NPXCW__ : __NetBSD_COMPAT_NPXCW__);
- l->l_md.md_flags &= ~MDL_USEDFPU;
- if (i386_use_fxsave) {
- pcb->pcb_savefpu.sv_xmm.fx_cw = control;
- pcb->pcb_savefpu.sv_xmm.fx_mxcsr = __INITIAL_MXCSR__;
- } else
- pcb->pcb_savefpu.sv_87.s87_cw = control;
memcpy(&pcb->pcb_fsd, &gdt[GUDATA_SEL], sizeof(pcb->pcb_fsd));
memcpy(&pcb->pcb_gsd, &gdt[GUDATA_SEL], sizeof(pcb->pcb_gsd));
@@ -1590,6 +1577,7 @@ cpu_getmcontext(struct lwp *l, mcontext_
{
const struct trapframe *tf = l->l_md.md_regs;
__greg_t *gr = mcp->__gregs;
+ struct pcb *pcb;
__greg_t ras_eip;
/* Save register context. */
@@ -1633,36 +1621,33 @@ cpu_getmcontext(struct lwp *l, mcontext_
mcp->_mc_tlsbase = (uintptr_t)l->l_private;
*flags |= _UC_TLSBASE;
- /* Save floating point register context, if any. */
- if ((l->l_md.md_flags & MDL_USEDFPU) != 0) {
- struct pcb *pcb = lwp_getpcb(l);
+ /* Save floating point register context. */
+ pcb = lwp_getpcb(l);
- /*
- * If this process is the current FP owner, dump its
- * context to the PCB first.
- */
- if (pcb->pcb_fpcpu)
- fpusave_lwp(l, true);
- if (i386_use_fxsave) {
- __CTASSERT(sizeof pcb->pcb_savefpu.sv_xmm ==
- sizeof mcp->__fpregs.__fp_reg_set.__fp_xmm_state);
- memcpy(&mcp->__fpregs.__fp_reg_set.__fp_xmm_state,
- &pcb->pcb_savefpu.sv_xmm,
- sizeof (mcp->__fpregs.__fp_reg_set.__fp_xmm_state));
- *flags |= _UC_FXSAVE;
- } else {
- __CTASSERT(sizeof pcb->pcb_savefpu.sv_87 ==
- sizeof mcp->__fpregs.__fp_reg_set.__fpchip_state);
- memcpy(&mcp->__fpregs.__fp_reg_set.__fpchip_state,
- &pcb->pcb_savefpu.sv_87,
- sizeof (mcp->__fpregs.__fp_reg_set.__fpchip_state));
- }
+ /*
+ * If this process is the current FP owner, dump its
+ * context to the PCB first.
+ */
+ fpusave_lwp(l, true);
+ if (i386_use_fxsave) {
+ __CTASSERT(sizeof pcb->pcb_savefpu.sv_xmm ==
+ sizeof mcp->__fpregs.__fp_reg_set.__fp_xmm_state);
+ memcpy(&mcp->__fpregs.__fp_reg_set.__fp_xmm_state,
+ &pcb->pcb_savefpu.sv_xmm,
+ sizeof (mcp->__fpregs.__fp_reg_set.__fp_xmm_state));
+ *flags |= _UC_FXSAVE;
+ } else {
+ __CTASSERT(sizeof pcb->pcb_savefpu.sv_87 ==
+ sizeof mcp->__fpregs.__fp_reg_set.__fpchip_state);
+ memcpy(&mcp->__fpregs.__fp_reg_set.__fpchip_state,
+ &pcb->pcb_savefpu.sv_87,
+ sizeof (mcp->__fpregs.__fp_reg_set.__fpchip_state));
+ }
#if 0
- /* Apparently nothing ever touches this. */
- ucp->mcp.mc_fp.fp_emcsts = pcb->pcb_saveemc;
+ /* Apparently nothing ever touches this. */
+ ucp->mcp.mc_fp.fp_emcsts = pcb->pcb_saveemc;
#endif
- *flags |= _UC_FPU;
- }
+ *flags |= _UC_FPU;
}
int
@@ -1738,19 +1723,14 @@ cpu_setmcontext(struct lwp *l, const mco
if ((flags & _UC_TLSBASE) != 0)
lwp_setprivate(l, (void *)(uintptr_t)mcp->_mc_tlsbase);
- /*
- * If we were using the FPU, forget that we were.
- */
- if (pcb->pcb_fpcpu != NULL)
- fpusave_lwp(l, false);
-
- /* Restore floating point register context, if any. */
+ /* Restore floating point register context, if given. */
if ((flags & _UC_FPU) != 0) {
__CTASSERT(sizeof pcb->pcb_savefpu.sv_xmm ==
sizeof mcp->__fpregs.__fp_reg_set.__fp_xmm_state);
__CTASSERT(sizeof pcb->pcb_savefpu.sv_87 ==
sizeof mcp->__fpregs.__fp_reg_set.__fpchip_state);
+ fpusave_lwp(l, false);
if (flags & _UC_FXSAVE) {
if (i386_use_fxsave) {
memcpy(&pcb->pcb_savefpu.sv_xmm,
@@ -1773,8 +1753,8 @@ cpu_setmcontext(struct lwp *l, const mco
sizeof (pcb->pcb_savefpu.sv_87));
}
}
- l->l_md.md_flags |= MDL_USEDFPU;
}
+
mutex_enter(p->p_lock);
if (flags & _UC_SETSTACK)
l->l_sigstk.ss_flags |= SS_ONSTACK;
Index: src/sys/arch/i386/i386/process_machdep.c
diff -u src/sys/arch/i386/i386/process_machdep.c:1.82 src/sys/arch/i386/i386/process_machdep.c:1.83
--- src/sys/arch/i386/i386/process_machdep.c:1.82 Fri Feb 7 22:40:22 2014
+++ src/sys/arch/i386/i386/process_machdep.c Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: process_machdep.c,v 1.82 2014/02/07 22:40:22 dsl Exp $ */
+/* $NetBSD: process_machdep.c,v 1.83 2014/02/15 10:11:15 dsl Exp $ */
/*-
* Copyright (c) 1998, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.82 2014/02/07 22:40:22 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.83 2014/02/15 10:11:15 dsl Exp $");
#include "opt_vm86.h"
#include "opt_ptrace.h"
@@ -131,34 +131,7 @@ process_read_fpregs(struct lwp *l, struc
{
union savefpu *frame = process_fpframe(l);
- if (l->l_md.md_flags & MDL_USEDFPU) {
- fpusave_lwp(l, true);
- } else {
- /*
- * Fake a FNINIT.
- * The initial control word was already set by setregs(), so
- * save it temporarily.
- */
- if (i386_use_fxsave) {
- uint32_t mxcsr = frame->sv_xmm.fx_mxcsr;
- uint16_t cw = frame->sv_xmm.fx_cw;
-
- /* XXX Don't zero XMM regs? */
- memset(&frame->sv_xmm, 0, sizeof(frame->sv_xmm));
- frame->sv_xmm.fx_cw = cw;
- frame->sv_xmm.fx_mxcsr = mxcsr;
- frame->sv_xmm.fx_sw = 0x0000;
- frame->sv_xmm.fx_tw = 0x00;
- } else {
- uint16_t cw = frame->sv_87.s87_cw;
-
- memset(&frame->sv_87, 0, sizeof(frame->sv_87));
- frame->sv_87.s87_cw = cw;
- frame->sv_87.s87_sw = 0x0000;
- frame->sv_87.s87_tw = 0xffff;
- }
- l->l_md.md_flags |= MDL_USEDFPU;
- }
+ fpusave_lwp(l, true);
__CTASSERT(sizeof *regs == sizeof (struct save87));
if (i386_use_fxsave) {
@@ -229,11 +202,7 @@ process_write_fpregs(struct lwp *l, cons
{
union savefpu *frame = process_fpframe(l);
- if (l->l_md.md_flags & MDL_USEDFPU) {
- fpusave_lwp(l, false);
- } else {
- l->l_md.md_flags |= MDL_USEDFPU;
- }
+ fpusave_lwp(l, false);
if (i386_use_fxsave) {
process_s87_to_xmm((const struct save87 *)regs, &frame->sv_xmm);
@@ -269,60 +238,26 @@ process_set_pc(struct lwp *l, void *addr
static int
process_machdep_read_xmmregs(struct lwp *l, struct xmmregs *regs)
{
- union savefpu *frame = process_fpframe(l);
if (i386_use_fxsave == 0)
return (EINVAL);
- if (l->l_md.md_flags & MDL_USEDFPU) {
- struct pcb *pcb = lwp_getpcb(l);
+ fpusave_lwp(l, true);
- if (pcb->pcb_fpcpu != NULL) {
- fpusave_lwp(l, true);
- }
- } else {
- /*
- * Fake a FNINIT.
- * The initial control word was already set by setregs(),
- * so save it temporarily.
- */
- uint32_t mxcsr = frame->sv_xmm.fx_mxcsr;
- uint16_t cw = frame->sv_xmm.fx_cw;
-
- /* XXX Don't zero XMM regs? */
- memset(&frame->sv_xmm, 0, sizeof(frame->sv_xmm));
- frame->sv_xmm.fx_cw = cw;
- frame->sv_xmm.fx_mxcsr = mxcsr;
- frame->sv_xmm.fx_sw = 0x0000;
- frame->sv_xmm.fx_tw = 0x00;
-
- l->l_md.md_flags |= MDL_USEDFPU;
- }
-
- memcpy(regs, &frame->sv_xmm, sizeof(*regs));
+ memcpy(regs, &process_fpframe(l)->sv_xmm, sizeof(*regs));
return (0);
}
static int
process_machdep_write_xmmregs(struct lwp *l, struct xmmregs *regs)
{
- union savefpu *frame = process_fpframe(l);
if (i386_use_fxsave == 0)
return (EINVAL);
- if (l->l_md.md_flags & MDL_USEDFPU) {
- struct pcb *pcb = lwp_getpcb(l);
-
- /* If we were using the FPU, drop it. */
- if (pcb->pcb_fpcpu != NULL) {
- fpusave_lwp(l, false);
- }
- } else {
- l->l_md.md_flags |= MDL_USEDFPU;
- }
+ fpusave_lwp(l, false);
- memcpy(&frame->sv_xmm, regs, sizeof(*regs));
+ memcpy(&process_fpframe(l)->sv_xmm, regs, sizeof(*regs));
return (0);
}
Index: src/sys/arch/i386/include/proc.h
diff -u src/sys/arch/i386/include/proc.h:1.40 src/sys/arch/i386/include/proc.h:1.41
--- src/sys/arch/i386/include/proc.h:1.40 Sun Dec 1 01:05:16 2013
+++ src/sys/arch/i386/include/proc.h Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: proc.h,v 1.40 2013/12/01 01:05:16 christos Exp $ */
+/* $NetBSD: proc.h,v 1.41 2014/02/15 10:11:15 dsl Exp $ */
/*
* Copyright (c) 1991 Regents of the University of California.
@@ -52,7 +52,6 @@ struct mdlwp {
};
/* md_flags */
-#define MDL_USEDFPU 0x0001 /* has used the FPU */
#define MDL_IOPL 0x0002 /* XEN: i/o privilege */
struct mdproc {
Index: src/sys/arch/x86/include/cpu.h
diff -u src/sys/arch/x86/include/cpu.h:1.61 src/sys/arch/x86/include/cpu.h:1.62
--- src/sys/arch/x86/include/cpu.h:1.61 Wed Feb 12 23:24:09 2014
+++ src/sys/arch/x86/include/cpu.h Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.61 2014/02/12 23:24:09 dsl Exp $ */
+/* $NetBSD: cpu.h,v 1.62 2014/02/15 10:11:15 dsl Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -435,10 +435,6 @@ void i8254_initclocks(void);
void cpu_probe_features(struct cpu_info *);
-/* npx.c */
-void fpusave_lwp(struct lwp *, bool);
-void fpusave_cpu(bool);
-
/* vm_machdep.c */
paddr_t kvtop(void *);
Index: src/sys/arch/x86/include/cpu_extended_state.h
diff -u src/sys/arch/x86/include/cpu_extended_state.h:1.6 src/sys/arch/x86/include/cpu_extended_state.h:1.7
--- src/sys/arch/x86/include/cpu_extended_state.h:1.6 Thu Feb 13 19:37:08 2014
+++ src/sys/arch/x86/include/cpu_extended_state.h Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_extended_state.h,v 1.6 2014/02/13 19:37:08 dsl Exp $ */
+/* $NetBSD: cpu_extended_state.h,v 1.7 2014/02/15 10:11:15 dsl Exp $ */
#ifndef _X86_CPU_EXTENDED_STATE_H_
#define _X86_CPU_EXTENDED_STATE_H_
@@ -122,8 +122,9 @@ __CTASSERT_NOLINT(sizeof (struct fxsave)
/* The end of the fsave buffer can be used by the operating system */
struct fxsave_os {
- uint8_t fxo_fxsave[512 - 48];
- /* 48 bytes available */
+ uint8_t fxo_fxsave[512 - 48];
+ /* 48 bytes available, NB copied to/from userspace */
+ uint16_t fxo_dflt_cw; /* Control word for signal handlers */
};
union savefpu {
Index: src/sys/arch/x86/include/fpu.h
diff -u src/sys/arch/x86/include/fpu.h:1.2 src/sys/arch/x86/include/fpu.h:1.3
--- src/sys/arch/x86/include/fpu.h:1.2 Wed Feb 12 23:24:09 2014
+++ src/sys/arch/x86/include/fpu.h Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.h,v 1.2 2014/02/12 23:24:09 dsl Exp $ */
+/* $NetBSD: fpu.h,v 1.3 2014/02/15 10:11:15 dsl Exp $ */
#ifndef _X86_FPU_H_
#define _X86_FPU_H_
@@ -7,8 +7,9 @@
#ifdef _KERNEL
-struct trapframe;
struct cpu_info;
+struct lwp;
+struct trapframe;
void fpuinit(struct cpu_info *);
void fpusave_lwp(struct lwp *, bool);
@@ -20,6 +21,11 @@ void fpudna(struct trapframe *);
void process_xmm_to_s87(const struct fxsave *, struct save87 *);
void process_s87_to_xmm(const struct save87 *, struct fxsave *);
+/* Set all to defaults (eg during exec) */
+void fpu_save_area_clear(struct lwp *, unsigned int);
+/* Reset control words only - for signal handlers */
+void fpu_save_area_reset(struct lwp *);
+
#endif
#endif /* _X86_FPU_H_ */
Index: src/sys/arch/x86/x86/fpu.c
diff -u src/sys/arch/x86/x86/fpu.c:1.4 src/sys/arch/x86/x86/fpu.c:1.5
--- src/sys/arch/x86/x86/fpu.c:1.4 Thu Feb 13 19:37:08 2014
+++ src/sys/arch/x86/x86/fpu.c Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.c,v 1.4 2014/02/13 19:37:08 dsl Exp $ */
+/* $NetBSD: fpu.c,v 1.5 2014/02/15 10:11:15 dsl Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc. All
@@ -100,7 +100,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.4 2014/02/13 19:37:08 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.5 2014/02/15 10:11:15 dsl Exp $");
#include "opt_multiprocessor.h"
@@ -430,34 +430,20 @@ fpudna(struct trapframe *frame)
clts();
ci->ci_fpcurlwp = l;
pcb->pcb_fpcpu = ci;
- if ((l->l_md.md_flags & MDL_USEDFPU) == 0) {
- fninit();
- if (i386_use_fxsave) {
- fldcw(&pcb->pcb_savefpu.sv_xmm.fx_cw);
- x86_ldmxcsr(&pcb->pcb_savefpu.sv_xmm.fx_mxcsr);
- } else {
- fldcw(&pcb->pcb_savefpu.sv_87.s87_cw);
- }
- l->l_md.md_flags |= MDL_USEDFPU;
- } else if (i386_use_fxsave) {
- /*
- * AMD FPU's do not restore FIP, FDP, and FOP on fxrstor,
- * leaking other process's execution history. Clear them
- * manually.
- */
+ if (i386_use_fxsave) {
/*
+ * AMD FPU's do not restore FIP, FDP, and FOP on fxrstor,
+ * leaking other process's execution history.
+ * Clear them manually by loading a zero onto the fpu stack.
+ *
* Clear the ES bit in the x87 status word if it is currently
* set, in order to avoid causing a fault in the upcoming load.
*/
if (fngetsw() & 0x80)
fnclex();
-
- /*
- * Load a zero into the x87 stack. This mangles the x87 stack,
- * but we don't care since we're about to call fxrstor() anyway.
- */
fldummy();
+
fxrstor(&pcb->pcb_savefpu.sv_xmm);
} else {
frstor(&pcb->pcb_savefpu.sv_87);
@@ -509,15 +495,14 @@ fpusave_cpu(bool save)
void
fpusave_lwp(struct lwp *l, bool save)
{
+ struct pcb *pcb = lwp_getpcb(l);
struct cpu_info *oci;
- struct pcb *pcb;
int s, spins, ticks;
spins = 0;
ticks = hardclock_ticks;
for (;;) {
s = splhigh();
- pcb = lwp_getpcb(l);
oci = pcb->pcb_fpcpu;
if (oci == NULL) {
splx(s);
@@ -546,9 +531,52 @@ fpusave_lwp(struct lwp *l, bool save)
panic("fpusave_lwp: did not");
}
}
+}
- if (!save) {
- /* Ensure we restart with a clean slate. */
- l->l_md.md_flags &= ~MDL_USEDFPU;
+/*
+ * exec needs to clear the fpu save area to avoid leaking info from the
+ * old process to userspace.
+ * We must also load these values into the fpu - otherwise the process
+ * will see another processes fpu registers.
+ */
+void
+fpu_save_area_clear(struct lwp *lwp, unsigned int x87_cw)
+{
+ struct pcb *pcb;
+ union savefpu *fpu_save;
+
+ fpusave_lwp(lwp, false);
+
+ pcb = lwp_getpcb(lwp);
+ fpu_save = &pcb->pcb_savefpu;
+
+ if (i386_use_fxsave) {
+ memset(&fpu_save->sv_xmm, 0, sizeof fpu_save->sv_xmm);
+ fpu_save->sv_xmm.fx_mxcsr = __INITIAL_MXCSR__;
+ fpu_save->sv_xmm.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
+ fpu_save->sv_xmm.fx_cw = x87_cw;
+ } else {
+ memset(&fpu_save->sv_87, 0, sizeof fpu_save->sv_87);
+ fpu_save->sv_87.s87_tw = 0xffff;
+ fpu_save->sv_87.s87_cw = x87_cw;
+ }
+ fpu_save->sv_os.fxo_dflt_cw = x87_cw;
+}
+
+/* For signal handlers the register values don't matter */
+void
+fpu_save_area_reset(struct lwp *lwp)
+{
+ struct pcb *pcb = lwp_getpcb(lwp);
+ union savefpu *fpu_save = &pcb->pcb_savefpu;
+
+ if (i386_use_fxsave) {
+ fpu_save->sv_xmm.fx_mxcsr = __INITIAL_MXCSR__;
+ fpu_save->sv_xmm.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
+ fpu_save->sv_xmm.fx_tw = 0;
+ fpu_save->sv_xmm.fx_cw = fpu_save->sv_os.fxo_dflt_cw;
+ } else {
+ fpu_save->sv_87.s87_tw = 0xffff;
+ fpu_save->sv_87.s87_cw = fpu_save->sv_os.fxo_dflt_cw;
}
}
Index: src/sys/arch/x86/x86/vm_machdep.c
diff -u src/sys/arch/x86/x86/vm_machdep.c:1.21 src/sys/arch/x86/x86/vm_machdep.c:1.22
--- src/sys/arch/x86/x86/vm_machdep.c:1.21 Tue Feb 11 20:17:16 2014
+++ src/sys/arch/x86/x86/vm_machdep.c Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.21 2014/02/11 20:17:16 dsl Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.22 2014/02/15 10:11:15 dsl Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.21 2014/02/11 20:17:16 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.22 2014/02/15 10:11:15 dsl Exp $");
#include "opt_mtrr.h"
@@ -137,9 +137,7 @@ cpu_lwp_fork(struct lwp *l1, struct lwp
* If parent LWP was using FPU, then we have to save the FPU h/w
* state to PCB so that we can copy it.
*/
- if (pcb1->pcb_fpcpu != NULL) {
- fpusave_lwp(l1, true);
- }
+ fpusave_lwp(l1, true);
/*
* Sync the PCB before we copy it.
@@ -238,12 +236,9 @@ cpu_lwp_fork(struct lwp *l1, struct lwp
void
cpu_lwp_free(struct lwp *l, int proc)
{
- struct pcb *pcb = lwp_getpcb(l);
/* If we were using the FPU, forget about it. */
- if (pcb->pcb_fpcpu != NULL) {
- fpusave_lwp(l, false);
- }
+ fpusave_lwp(l, false);
#ifdef MTRR
if (proc && l->l_proc->p_md.md_flags & MDP_USEDMTRR)
Index: src/sys/compat/linux/arch/amd64/linux_machdep.c
diff -u src/sys/compat/linux/arch/amd64/linux_machdep.c:1.46 src/sys/compat/linux/arch/amd64/linux_machdep.c:1.47
--- src/sys/compat/linux/arch/amd64/linux_machdep.c:1.46 Tue Feb 11 20:17:16 2014
+++ src/sys/compat/linux/arch/amd64/linux_machdep.c Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_machdep.c,v 1.46 2014/02/11 20:17:16 dsl Exp $ */
+/* $NetBSD: linux_machdep.c,v 1.47 2014/02/15 10:11:15 dsl Exp $ */
/*-
* Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved.
@@ -33,7 +33,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.46 2014/02/11 20:17:16 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.47 2014/02/15 10:11:15 dsl Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -83,15 +83,8 @@ linux_setregs(struct lwp *l, struct exec
struct pcb *pcb = lwp_getpcb(l);
struct trapframe *tf;
- /* If we were using the FPU, forget about it. */
- if (pcb->pcb_fpcpu != NULL)
- fpusave_lwp(l, 0);
-
- l->l_md.md_flags &= ~MDL_USEDFPU;
+ fpu_save_area_clear(l, __NetBSD_NPXCW__);
pcb->pcb_flags = 0;
- pcb->pcb_savefpu.sv_xmm.fx_cw = __NetBSD_NPXCW__;
- pcb->pcb_savefpu.sv_xmm.fx_mxcsr = __INITIAL_MXCSR__;
- pcb->pcb_savefpu.sv_xmm.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
l->l_proc->p_flag &= ~PK_32;
@@ -152,15 +145,9 @@ linux_sendsig(const ksiginfo_t *ksi, con
else
sp = (char *)tf->tf_rsp - 128;
- /*
- * Save FPU state, if any
- */
- if (l->l_md.md_flags & MDL_USEDFPU) {
- sp = (char *)
- (((long)sp - sizeof (*fpsp)) & ~0xfUL);
- fpsp = (struct linux__fpstate *)sp;
- } else
- fpsp = NULL;
+ /* Save FPU state */
+ sp = (char *) (((long)sp - sizeof (*fpsp)) & ~0xfUL);
+ fpsp = (struct linux__fpstate *)sp;
/*
* Populate the rt_sigframe
Index: src/sys/compat/linux/arch/i386/linux_machdep.c
diff -u src/sys/compat/linux/arch/i386/linux_machdep.c:1.156 src/sys/compat/linux/arch/i386/linux_machdep.c:1.157
--- src/sys/compat/linux/arch/i386/linux_machdep.c:1.156 Sun Jan 26 19:16:17 2014
+++ src/sys/compat/linux/arch/i386/linux_machdep.c Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_machdep.c,v 1.156 2014/01/26 19:16:17 dsl Exp $ */
+/* $NetBSD: linux_machdep.c,v 1.157 2014/02/15 10:11:15 dsl Exp $ */
/*-
* Copyright (c) 1995, 2000, 2008, 2009 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.156 2014/01/26 19:16:17 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.157 2014/02/15 10:11:15 dsl Exp $");
#if defined(_KERNEL_OPT)
#include "opt_vm86.h"
@@ -126,25 +126,13 @@ extern char linux_sigcode[], linux_rt_si
void
linux_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack)
{
- struct pcb *pcb = lwp_getpcb(l);
struct trapframe *tf;
- /* If we were using the FPU, forget about it. */
- if (pcb->pcb_fpcpu != NULL)
- fpusave_lwp(l, false);
-
-
#ifdef USER_LDT
pmap_ldt_cleanup(l);
#endif
- l->l_md.md_flags &= ~MDL_USEDFPU;
-
- if (i386_use_fxsave) {
- pcb->pcb_savefpu.sv_xmm.fx_cw = __Linux_NPXCW__;
- pcb->pcb_savefpu.sv_xmm.fx_mxcsr = __INITIAL_MXCSR__;
- } else
- pcb->pcb_savefpu.sv_87.s87_cw = __Linux_NPXCW__;
+ fpu_save_area_clear(l, __Linux_NPXCW__);
tf = l->l_md.md_regs;
tf->tf_gs = 0;
Index: src/sys/compat/linux32/arch/amd64/linux32_machdep.c
diff -u src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.34 src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.35
--- src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.34 Fri Feb 7 22:40:22 2014
+++ src/sys/compat/linux32/arch/amd64/linux32_machdep.c Sat Feb 15 10:11:15 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: linux32_machdep.c,v 1.34 2014/02/07 22:40:22 dsl Exp $ */
+/* $NetBSD: linux32_machdep.c,v 1.35 2014/02/15 10:11:15 dsl Exp $ */
/*-
* Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
@@ -31,7 +31,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.34 2014/02/07 22:40:22 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.35 2014/02/15 10:11:15 dsl Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@@ -273,22 +273,16 @@ linux32_setregs(struct lwp *l, struct ex
struct trapframe *tf;
struct proc *p = l->l_proc;
- /* If we were using the FPU, forget about it. */
- if (pcb->pcb_fpcpu != NULL)
- fpusave_lwp(l, 0);
-
#if defined(USER_LDT) && 0
pmap_ldt_cleanup(p);
#endif
netbsd32_adjust_limits(p);
- l->l_md.md_flags &= ~MDL_USEDFPU;
+ fpu_save_area_clear(l, __Linux_NPXCW__);
+
l->l_md.md_flags |= MDL_COMPAT32; /* Forces iret not sysret */
pcb->pcb_flags = PCB_COMPAT32;
- pcb->pcb_savefpu.sv_xmm.fx_cw = __Linux_NPXCW__;
- pcb->pcb_savefpu.sv_xmm.fx_mxcsr = __INITIAL_MXCSR__;
- pcb->pcb_savefpu.sv_xmm.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
p->p_flag |= PK_32;