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)
This commit is contained in:
Joseph Koshy 2005-07-09 17:19:46 +00:00
parent 82c83e34dd
commit 151a683010
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=147865

View File

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