Messages in this thread Patch in this message | | | Date | Fri, 25 Oct 2002 08:26:27 -0500 | From | Corey Minyard <> | Subject | [PATCH] NMI request/release, version 8 |
| |
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 --- 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) | |