diff options
author | jkoshy <jkoshy@FreeBSD.org> | 2005-07-13 11:32:10 +0000 |
---|---|---|
committer | jkoshy <jkoshy@FreeBSD.org> | 2005-07-13 11:32:10 +0000 |
commit | 289f3af54f87004c6a7d4ed25238810c48ecb7f2 (patch) | |
tree | 47f4ead998b4edc235018bc4922ae16ca8d21d52 | |
parent | b01a145dbf9b0649925cd1b8fccb00a7e78b8615 (diff) | |
download | FreeBSD-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.s | 29 | ||||
-rw-r--r-- | sys/i386/i386/machdep.c | 2 | ||||
-rw-r--r-- | sys/i386/i386/trap.c | 7 |
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(); } } |