Skip to content

Commit 78a509f

Browse files
nomuranecIngo Molnar
authored and
Ingo Molnar
committed
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: Jun'ichi Nomura <junichi.nomura@nec.com> Signed-off-by: Derek Barbosa <debarbos@redhat.com> Signed-off-by: Ingo 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>
1 parent 2cc14f5 commit 78a509f

File tree

4 files changed

+8
-0
lines changed

4 files changed

+8
-0
lines changed

arch/x86/boot/compressed/ident_map_64.c

+5
Original file line numberDiff line numberDiff line change
@@ -386,3 +386,8 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code)
386386
*/
387387
kernel_add_identity_map(address, end);
388388
}
389+
390+
void do_boot_nmi_trap(struct pt_regs *regs, unsigned long error_code)
391+
{
392+
/* Empty handler to ignore NMI during early boot */
393+
}

arch/x86/boot/compressed/idt_64.c

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ void load_stage2_idt(void)
6161
boot_idt_desc.address = (unsigned long)boot_idt;
6262

6363
set_idt_entry(X86_TRAP_PF, boot_page_fault);
64+
set_idt_entry(X86_TRAP_NMI, boot_nmi_trap);
6465

6566
#ifdef CONFIG_AMD_MEM_ENCRYPT
6667
/*

arch/x86/boot/compressed/idt_handlers_64.S

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ SYM_FUNC_END(\name)
7070
.code64
7171

7272
EXCEPTION_HANDLER boot_page_fault do_boot_page_fault error_code=1
73+
EXCEPTION_HANDLER boot_nmi_trap do_boot_nmi_trap error_code=0
7374

7475
#ifdef CONFIG_AMD_MEM_ENCRYPT
7576
EXCEPTION_HANDLER boot_stage1_vc do_vc_no_ghcb error_code=1

arch/x86/boot/compressed/misc.h

+1
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ static inline void cleanup_exception_handling(void) { }
196196

197197
/* IDT Entry Points */
198198
void boot_page_fault(void);
199+
void boot_nmi_trap(void);
199200
void boot_stage1_vc(void);
200201
void boot_stage2_vc(void);
201202

0 commit comments

Comments
 (0)