PR port-i386/39299 FPU use in signal handlers is unsafe

This commit is contained in:
ad 2008-11-11 15:53:53 +00:00
parent 4903bac4b2
commit c269b07b80
4 changed files with 39 additions and 28 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fpu.c,v 1.28 2008/11/11 14:40:18 ad Exp $ */
/* $NetBSD: fpu.c,v 1.29 2008/11/11 15:53:53 ad 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.28 2008/11/11 14:40:18 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.29 2008/11/11 15:53:53 ad Exp $");
#include "opt_multiprocessor.h"
@ -394,13 +394,13 @@ fpusave_lwp(struct lwp *l, bool save)
oci = l->l_addr->u_pcb.pcb_fpcpu;
if (oci == NULL) {
splx(s);
return;
break;
}
if (oci == curcpu()) {
KASSERT(oci->ci_fpcurlwp == l);
fpusave_cpu(save);
splx(s);
return;
break;
}
splx(s);
x86_send_ipi(oci, X86_IPI_SYNCH_FPU);
@ -413,4 +413,9 @@ 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 &= ~MDP_USEDFPU;
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.104 2008/11/11 14:40:18 ad Exp $ */
/* $NetBSD: machdep.c,v 1.105 2008/11/11 15:53:53 ad Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008
@ -112,7 +112,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.104 2008/11/11 14:40:18 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.105 2008/11/11 15:53:53 ad Exp $");
/* #define XENDEBUG_LOW */
@ -537,6 +537,9 @@ buildcontext(struct lwp *l, void *catcher, void *f)
tf->tf_rflags &= ~PSL_CLEARSIG;
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 &= ~MDP_USEDFPU;
}
void
@ -1947,9 +1950,10 @@ cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
l->l_md.md_flags |= MDP_IRET;
}
if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
fpusave_lwp(l, false);
if ((flags & _UC_FPU) != 0) {
if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
fpusave_lwp(l, false);
memcpy(&l->l_addr->u_pcb.pcb_savefpu.fp_fxsave, mcp->__fpregs,
sizeof (mcp->__fpregs));
l->l_md.md_flags |= MDP_USEDFPU;

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.646 2008/11/11 14:40:18 ad Exp $ */
/* $NetBSD: machdep.c,v 1.647 2008/11/11 15:53:53 ad Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008 The NetBSD Foundation, Inc.
@ -65,7 +65,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.646 2008/11/11 14:40:18 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.647 2008/11/11 15:53:53 ad Exp $");
#include "opt_beep.h"
#include "opt_compat_ibcs2.h"
@ -770,6 +770,9 @@ buildcontext(struct lwp *l, int sel, void *catcher, void *fp)
tf->tf_eflags &= ~PSL_CLEARSIG;
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;
}
static void
@ -2211,8 +2214,6 @@ cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags)
/*
* If this process is the current FP owner, dump its
* context to the PCB first.
* XXX npxsave() also clears the FPU state; depending on the
* XXX application this might be a penalty.
*/
if (l->l_addr->u_pcb.pcb_fpcpu) {
npxsave_lwp(l, true);
@ -2294,15 +2295,16 @@ cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
tf->tf_ss = gr[_REG_SS];
}
#if NNPX > 0
/*
* If we were using the FPU, forget that we were.
*/
if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
npxsave_lwp(l, false);
#endif
/* Restore floating point register context, if any. */
if ((flags & _UC_FPU) != 0) {
#if NNPX > 0
/*
* If we were using the FPU, forget that we were.
*/
if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
npxsave_lwp(l, false);
#endif
if (flags & _UC_FXSAVE) {
if (i386_use_fxsave) {
memcpy(
@ -2326,12 +2328,7 @@ cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
sizeof (l->l_addr->u_pcb.pcb_savefpu.sv_87));
}
}
/* If not set already. */
l->l_md.md_flags |= MDL_USEDFPU;
#if 0
/* Apparently unused. */
l->l_addr->u_pcb.pcb_saveemc = mcp->mc_fp.fp_emcsts;
#endif
}
mutex_enter(p->p_lock);
if (flags & _UC_SETSTACK)

View File

@ -1,4 +1,4 @@
/* $NetBSD: npx.c,v 1.131 2008/11/11 14:40:19 ad Exp $ */
/* $NetBSD: npx.c,v 1.132 2008/11/11 15:53:53 ad Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -96,7 +96,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npx.c,v 1.131 2008/11/11 14:40:19 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: npx.c,v 1.132 2008/11/11 15:53:53 ad Exp $");
#if 0
#define IPRINTF(x) printf x
@ -700,13 +700,13 @@ npxsave_lwp(struct lwp *l, bool save)
oci = l->l_addr->u_pcb.pcb_fpcpu;
if (oci == NULL) {
splx(s);
return;
break;
}
if (oci == curcpu()) {
KASSERT(oci->ci_fpcurlwp == l);
npxsave_cpu(save);
splx(s);
return;
break;
}
splx(s);
x86_send_ipi(oci, X86_IPI_SYNCH_FPU);
@ -719,4 +719,9 @@ npxsave_lwp(struct lwp *l, bool save)
panic("npxsave_lwp: did not");
}
}
if (!save) {
/* Ensure we restart with a clean slate. */
l->l_md.md_flags &= ~MDL_USEDFPU;
}
}