summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjkoshy <jkoshy@FreeBSD.org>2005-07-09 17:19:46 +0000
committerjkoshy <jkoshy@FreeBSD.org>2005-07-09 17:19:46 +0000
commitc40eef1dc1536fc0840379e08bda24d0e6cbac20 (patch)
treef377bad247112e67dc47dd03410a49b771a80d05
parent51f3adcc08d0ec9aea5c09dc6ac26c44d91e1258 (diff)
downloadFreeBSD-src-c40eef1dc1536fc0840379e08bda24d0e6cbac20.zip
FreeBSD-src-c40eef1dc1536fc0840379e08bda24d0e6cbac20.tar.gz
Have the NMI handler call the C language trap() routine and directly
exit via 'doreti_exit'. Since the NMI interrupt may be taken at any time, including when the processor has masked external interrupts, it is not safe to call ast() as is done for normal interrupts. Approved by: re (scottl)
-rw-r--r--sys/i386/i386/exception.s29
1 files changed, 27 insertions, 2 deletions
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index 2e69ab8..6a45179 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -78,8 +78,6 @@ IDTVEC(div)
pushl $0; TRAP(T_DIVIDE)
IDTVEC(dbg)
pushl $0; TRAP(T_TRCTRAP)
-IDTVEC(nmi)
- pushl $0; TRAP(T_NMI)
IDTVEC(bpt)
pushl $0; TRAP(T_BPTFLT)
IDTVEC(ofl)
@@ -215,6 +213,33 @@ ENTRY(fork_trampoline)
MEXITCOUNT
jmp doreti
+/*
+ * NMI handling is somewhat special: NMI interrupts may be taken at
+ * any time, including when the processor has turned off external
+ * interrupts by clearing EFLAGS.IF. This means that the kernel's
+ * internal state could be inconsistent at the time of the interrupt,
+ * and it is not safe to call "ast()" as is done in the exit path
+ * for normal interrupts.
+ *
+ * The NMI handler therefore invokes the C language routine "trap()"
+ * and directly jumps to 'doreti_exit'.
+ */
+IDTVEC(nmi)
+ /* create a trap frame */
+ pushl $0
+ pushl $T_NMI
+ pushal
+ pushl %ds
+ pushl %es
+ pushl %fs
+ movl $KDSEL,%eax
+ movl %eax,%ds
+ movl %eax,%es
+ movl $KPSEL,%eax
+ movl %eax,%fs
+ FAKE_MCOUNT(TF_EIP(%esp))
+ call trap
+ jmp doreti_exit
/*
* To efficiently implement classification of trap and interrupt handlers
OpenPOWER on IntegriCloud