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:
parent
85dcd28828
commit
0775c0fa95
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user