DragonFly BSD
DragonFly bugs List (threaded) for 2006-04
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

real patch (Re: crashme panic)


From: Matthew Dillon <dillon@xxxxxxxxxxxxxxxxxxxx>
Date: Sun, 2 Apr 2006 12:29:44 -0700 (PDT)

    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)



[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]