Commit 78a509fb authored by Jun'ichi Nomura's avatar Jun'ichi Nomura Committed by Ingo Molnar

x86/boot: Ignore NMIs during very early boot

When there are two racing NMIs on x86, the first NMI invokes NMI handler and
the 2nd NMI is latched until IRET is executed.

If panic on NMI and panic kexec are enabled, the first NMI triggers
panic and starts booting the next kernel via kexec. Note that the 2nd
NMI is still latched. During the early boot of the next kernel, once
an IRET is executed as a result of a page fault, then the 2nd NMI is
unlatched and invokes the NMI handler.

However, NMI handler is not set up at the early stage of boot, which
results in a boot failure.

Avoid such problems by setting up a NOP handler for early NMIs.

[ mingo: Refined the changelog. ]
Signed-off-by: default avatarJun'ichi Nomura <junichi.nomura@nec.com>
Signed-off-by: default avatarDerek Barbosa <debarbos@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@kernel.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Peter Zijlstra <peterz@infradead.org>
parent 2cc14f52
...@@ -386,3 +386,8 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -386,3 +386,8 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code)
*/ */
kernel_add_identity_map(address, end); kernel_add_identity_map(address, end);
} }
void do_boot_nmi_trap(struct pt_regs *regs, unsigned long error_code)
{
/* Empty handler to ignore NMI during early boot */
}
...@@ -61,6 +61,7 @@ void load_stage2_idt(void) ...@@ -61,6 +61,7 @@ void load_stage2_idt(void)
boot_idt_desc.address = (unsigned long)boot_idt; boot_idt_desc.address = (unsigned long)boot_idt;
set_idt_entry(X86_TRAP_PF, boot_page_fault); set_idt_entry(X86_TRAP_PF, boot_page_fault);
set_idt_entry(X86_TRAP_NMI, boot_nmi_trap);
#ifdef CONFIG_AMD_MEM_ENCRYPT #ifdef CONFIG_AMD_MEM_ENCRYPT
/* /*
......
...@@ -70,6 +70,7 @@ SYM_FUNC_END(\name) ...@@ -70,6 +70,7 @@ SYM_FUNC_END(\name)
.code64 .code64
EXCEPTION_HANDLER boot_page_fault do_boot_page_fault error_code=1 EXCEPTION_HANDLER boot_page_fault do_boot_page_fault error_code=1
EXCEPTION_HANDLER boot_nmi_trap do_boot_nmi_trap error_code=0
#ifdef CONFIG_AMD_MEM_ENCRYPT #ifdef CONFIG_AMD_MEM_ENCRYPT
EXCEPTION_HANDLER boot_stage1_vc do_vc_no_ghcb error_code=1 EXCEPTION_HANDLER boot_stage1_vc do_vc_no_ghcb error_code=1
......
...@@ -196,6 +196,7 @@ static inline void cleanup_exception_handling(void) { } ...@@ -196,6 +196,7 @@ static inline void cleanup_exception_handling(void) { }
/* IDT Entry Points */ /* IDT Entry Points */
void boot_page_fault(void); void boot_page_fault(void);
void boot_nmi_trap(void);
void boot_stage1_vc(void); void boot_stage1_vc(void);
void boot_stage2_vc(void); void boot_stage2_vc(void);
......
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