![Jun'ichi Nomura](/assets/img/avatar_default.png)
[ Upstream commit 78a509fba9c9b1fcb77f95b7c6be30da3d24823a ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
78 lines
1.3 KiB
ArmAsm
Executable file
78 lines
1.3 KiB
ArmAsm
Executable file
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Early IDT handler entry points
|
|
*
|
|
* Copyright (C) 2019 SUSE
|
|
*
|
|
* Author: Joerg Roedel <jroedel@suse.de>
|
|
*/
|
|
|
|
#include <asm/segment.h>
|
|
|
|
/* For ORIG_RAX */
|
|
#include "../../entry/calling.h"
|
|
|
|
.macro EXCEPTION_HANDLER name function error_code=0
|
|
SYM_FUNC_START(\name)
|
|
|
|
/* Build pt_regs */
|
|
.if \error_code == 0
|
|
pushq $0
|
|
.endif
|
|
|
|
pushq %rdi
|
|
pushq %rsi
|
|
pushq %rdx
|
|
pushq %rcx
|
|
pushq %rax
|
|
pushq %r8
|
|
pushq %r9
|
|
pushq %r10
|
|
pushq %r11
|
|
pushq %rbx
|
|
pushq %rbp
|
|
pushq %r12
|
|
pushq %r13
|
|
pushq %r14
|
|
pushq %r15
|
|
|
|
/* Call handler with pt_regs */
|
|
movq %rsp, %rdi
|
|
/* Error code is second parameter */
|
|
movq ORIG_RAX(%rsp), %rsi
|
|
call \function
|
|
|
|
/* Restore regs */
|
|
popq %r15
|
|
popq %r14
|
|
popq %r13
|
|
popq %r12
|
|
popq %rbp
|
|
popq %rbx
|
|
popq %r11
|
|
popq %r10
|
|
popq %r9
|
|
popq %r8
|
|
popq %rax
|
|
popq %rcx
|
|
popq %rdx
|
|
popq %rsi
|
|
popq %rdi
|
|
|
|
/* Remove error code and return */
|
|
addq $8, %rsp
|
|
|
|
iretq
|
|
SYM_FUNC_END(\name)
|
|
.endm
|
|
|
|
.text
|
|
.code64
|
|
|
|
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
|
|
EXCEPTION_HANDLER boot_stage1_vc do_vc_no_ghcb error_code=1
|
|
EXCEPTION_HANDLER boot_stage2_vc do_boot_stage2_vc error_code=1
|
|
#endif
|