MFC { exception.s:r1.114, machdep.c:r1.617, trap.c:r1.278 }

Use an interrupt gate for the NMI handler and prevent too-early
enabling of interrupts inside of trap().

Revert rev 1.113 of "sys/i386/i386/exception.s" as it is no longer
needed.

Approved by:	re (kensmith)
This commit is contained in:
jkoshy 2005-07-28 03:30:53 +00:00
parent 85dcd28828
commit 0775c0fa95
3 changed files with 7 additions and 31 deletions

View File

@ -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

View File

@ -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));

View File

@ -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();
}
}