summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjkoshy <jkoshy@FreeBSD.org>2005-07-13 11:32:10 +0000
committerjkoshy <jkoshy@FreeBSD.org>2005-07-13 11:32:10 +0000
commit289f3af54f87004c6a7d4ed25238810c48ecb7f2 (patch)
tree47f4ead998b4edc235018bc4922ae16ca8d21d52
parentb01a145dbf9b0649925cd1b8fccb00a7e78b8615 (diff)
downloadFreeBSD-src-289f3af54f87004c6a7d4ed25238810c48ecb7f2.zip
FreeBSD-src-289f3af54f87004c6a7d4ed25238810c48ecb7f2.tar.gz
Use an interrupt gate for the NMI handler and prevent too-early
enabling of interrupts inside of trap(). Fix a typo in a comment. Revert rev 1.113 of "sys/i386/i386/exception.s" as it is no longer needed. Reviewed by: bde MFC after: 3 days
-rw-r--r--sys/i386/i386/exception.s29
-rw-r--r--sys/i386/i386/machdep.c2
-rw-r--r--sys/i386/i386/trap.c7
3 files changed, 7 insertions, 31 deletions
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index 6a45179..2e69ab8 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -78,6 +78,8 @@ 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)
@@ -213,33 +215,6 @@ 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
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index be715d0..f413a20 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -2114,7 +2114,7 @@ init386(first)
GSEL(GCODE_SEL, SEL_KPL));
setidt(IDT_DB, &IDTVEC(dbg), SDT_SYS386IGT, SEL_KPL,
GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_NMI, &IDTVEC(nmi), SDT_SYS386TGT, SEL_KPL,
+ setidt(IDT_NMI, &IDTVEC(nmi), SDT_SYS386IGT, SEL_KPL,
GSEL(GCODE_SEL, SEL_KPL));
setidt(IDT_BP, &IDTVEC(bpt), SDT_SYS386IGT, SEL_UPL,
GSEL(GCODE_SEL, SEL_KPL));
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index be714dd..1e5a346 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -238,11 +238,12 @@ trap(frame)
printf("kernel trap %d with interrupts disabled\n",
type);
/*
- * Page faults need interrupts diasabled until later,
+ * Page faults need interrupts disabled until later,
* and we shouldn't enable interrupts while in a
- * critical section.
+ * critical section or if servicing an NMI.
*/
- if (type != T_PAGEFLT && td->td_critnest == 0)
+ if (type != T_NMI && type != T_PAGEFLT &&
+ td->td_critnest == 0)
enable_intr();
}
}
OpenPOWER on IntegriCloud