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)

Reply via email to