Here is the real patch. Get rid of the patch to exception.s and apply
this one.
So far crashme has not been able to crash the box with this patch.
-Matt
Index: i386/isa/npx.c
===================================================================
RCS file: /cvs/src/sys/i386/isa/npx.c,v
retrieving revision 1.29
diff -u -r1.29 npx.c
--- i386/isa/npx.c 4 Nov 2005 08:57:31 -0000 1.29
+++ i386/isa/npx.c 2 Apr 2006 19:24:43 -0000
@@ -33,7 +33,7 @@
*
* from: @(#)npx.c 7.2 (Berkeley) 5/12/91
* $FreeBSD: src/sys/i386/isa/npx.c,v 1.80.2.3 2001/10/20 19:04:38 tegge Exp $
- * $DragonFly: src/sys/i386/isa/npx.c,v 1.29 2005/11/04 08:57:31 dillon Exp $
+ * $DragonFly$
*/
#include "opt_cpu.h"
@@ -746,7 +746,9 @@
* solution for signals other than SIGFPE.
*
* The MP lock is not held on entry (see i386/i386/exception.s) and
- * should not be held on exit.
+ * should not be held on exit. Interrupts are enabled. We must enter
+ * a critical section to stabilize the FP system and prevent an interrupt
+ * or preemption from changing the FP state out from under us.
*/
void
npx_intr(void *dummy)
@@ -756,6 +758,21 @@
struct intrframe *frame;
u_long *exstat;
+ crit_enter();
+
+ /*
+ * This exception can only occur with CR0_TS clear, otherwise we
+ * would get a DNA exception. However, since interrupts were
+ * enabled a preemption could have sneaked in and used the FP system
+ * before we entered our critical section. If that occured, the
+ * TS bit will be set and npxthread will be NULL.
+ */
+ if (npx_exists && (rcr0() & CR0_TS)) {
+ KASSERT(mdcpu->gd_npxthread == NULL, ("gd_npxthread was %p with
TS set!", mdcpu->gd_npxthread));
+ npxdna();
+ crit_exit();
+ return;
+ }
if (mdcpu->gd_npxthread == NULL || !npx_exists) {
get_mplock();
printf("npxintr: npxthread = %p, curthread = %p, npx_exists =
%d\n",
@@ -819,12 +836,16 @@
psignal(curproc, SIGFPE);
}
rel_mplock();
+ crit_exit();
}
/*
* Implement the device not available (DNA) exception. gd_npxthread had
* better be NULL. Restore the current thread's FP state and set gd_npxthread
* to curthread.
+ *
+ * Interrupts are enabled and preemption can occur. Enter a critical
+ * section to stabilize the FP state.
*/
int
npxdna(void)