real patch (Re: crashme panic)

Matthew Dillon dillon at apollo.backplane.com
Sun Apr 2 12:35:01 PDT 2006


    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)





More information about the Bugs mailing list