I realized that the piece of code at the end of the old NMI handler was 
still necessary.  I have attached a patch to the previous version to fix 
the problem.  The full version of the patch with this fix is on my web 
page at http://home.attbi.com/~minyard/linux-nmi-v8.diff.
-Corey
--------------010507040703030903050002
Content-Type: text/plain;
 name="linux-nmi-v7-v8.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="linux-nmi-v7-v8.diff"
--- linux.v8/arch/i386/kernel/nmi.c	Thu Oct 24 20:53:04 2002
+++ linux/arch/i386/kernel/nmi.c	Fri Oct 25 08:21:22 2002
@@ -208,30 +208,29 @@
 
 	if (!handled)
 		unknown_nmi_error(regs, cpu);
-#if 0
-	/*
-	 * It MAY be possible to only call handlers until one returns
-	 * that it handled the NMI, if, we do the following.  Assuming
-	 * that all the incoming signals causing NMIs are
-	 * level-triggered, this code will cause another NMI
-	 * immediately if the incoming signal is still asserted.  I
-	 * don't know if the assumption is correct or if it's better
-	 * to call all the handlers or do the I/O.
-	 *
-	 * I'm pretty sure that this won't work with the performance
-	 * registers NMI output, so I'm guessing that this won't work.
-	 */
 	else {
 		/*
 		 * Reassert NMI in case it became active meanwhile
-		 * as it's edge-triggered.
+		 * as it's edge-triggered.    Don't do this if the NMI
+		 * wasn't handled to avoid an infinite NMI loop.
+		 *
+		 * This is necessary in case we have another external
+		 * NMI while processing this one.  The external NMIs
+		 * are level-generated, into the processor NMIs are
+		 * edge-triggered, so if you have one NMI source
+		 * come in while another is already there, the level
+		 * will never go down to cause another edge, and
+		 * no more NMIs will happen.  This does NOT apply
+		 * to internally generated NMIs, though, so you
+		 * can't use the same trick to only call one handler
+		 * at a time.  Otherwise, if two internal NMIs came
+		 * in at the same time you might miss one.
 		 */
 		outb(0x8f, 0x70);
 		inb(0x71);		/* dummy */
 		outb(0x0f, 0x70);
 		inb(0x71);		/* dummy */
 	}
-#endif
 }
 
 void __init init_nmi(void)
--------------010507040703030903050002--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/