Commit 5fa10196 authored by H. Peter Anvin's avatar H. Peter Anvin

x86: Ignore NMIs that come in during early boot

Don Zickus reports:

A customer generated an external NMI using their iLO to test kdump
worked.  Unfortunately, the machine hung.  Disabling the nmi_watchdog
made things work.

I speculated the external NMI fired, caused the machine to panic (as
expected) and the perf NMI from the watchdog came in and was latched.
My guess was this somehow caused the hang.

   ----

It appears that the latched NMI stays latched until the early page
table generation on 64 bits, which causes exceptions to happen which
end in IRET, which re-enable NMI.  Therefore, ignore NMIs that come in
during early execution, until we have proper exception handling.
Reported-and-tested-by: default avatarDon Zickus <dzickus@redhat.com>
Link: http://lkml.kernel.org/r/1394221143-29713-1-git-send-email-dzickus@redhat.comSigned-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
Cc: <stable@vger.kernel.org> # v3.5+, older with some backport effort
parent d4078e23
...@@ -544,6 +544,10 @@ ENDPROC(early_idt_handlers) ...@@ -544,6 +544,10 @@ ENDPROC(early_idt_handlers)
/* This is global to keep gas from relaxing the jumps */ /* This is global to keep gas from relaxing the jumps */
ENTRY(early_idt_handler) ENTRY(early_idt_handler)
cld cld
cmpl $X86_TRAP_NMI,(%esp)
je is_nmi # Ignore NMI
cmpl $2,%ss:early_recursion_flag cmpl $2,%ss:early_recursion_flag
je hlt_loop je hlt_loop
incl %ss:early_recursion_flag incl %ss:early_recursion_flag
...@@ -594,8 +598,9 @@ ex_entry: ...@@ -594,8 +598,9 @@ ex_entry:
pop %edx pop %edx
pop %ecx pop %ecx
pop %eax pop %eax
addl $8,%esp /* drop vector number and error code */
decl %ss:early_recursion_flag decl %ss:early_recursion_flag
is_nmi:
addl $8,%esp /* drop vector number and error code */
iret iret
ENDPROC(early_idt_handler) ENDPROC(early_idt_handler)
......
...@@ -343,6 +343,9 @@ early_idt_handlers: ...@@ -343,6 +343,9 @@ early_idt_handlers:
ENTRY(early_idt_handler) ENTRY(early_idt_handler)
cld cld
cmpl $X86_TRAP_NMI,(%rsp)
je is_nmi # Ignore NMI
cmpl $2,early_recursion_flag(%rip) cmpl $2,early_recursion_flag(%rip)
jz 1f jz 1f
incl early_recursion_flag(%rip) incl early_recursion_flag(%rip)
...@@ -405,8 +408,9 @@ ENTRY(early_idt_handler) ...@@ -405,8 +408,9 @@ ENTRY(early_idt_handler)
popq %rdx popq %rdx
popq %rcx popq %rcx
popq %rax popq %rax
addq $16,%rsp # drop vector number and error code
decl early_recursion_flag(%rip) decl early_recursion_flag(%rip)
is_nmi:
addq $16,%rsp # drop vector number and error code
INTERRUPT_RETURN INTERRUPT_RETURN
ENDPROC(early_idt_handler) ENDPROC(early_idt_handler)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment