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:
parent
82c83e34dd
commit
151a683010
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=147865
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user