[tip:,x86/boot] x86/boot: Ignore NMIs during very early boot

Message ID 170133478498.398.5261666675868615202.tip-bot2@tip-bot2
State New
Headers
Series [tip:,x86/boot] x86/boot: Ignore NMIs during very early boot |

Commit Message

tip-bot2 for Thomas Gleixner Nov. 30, 2023, 8:59 a.m. UTC
  The following commit has been merged into the x86/boot branch of tip:

Commit-ID:     78a509fba9c9b1fcb77f95b7c6be30da3d24823a
Gitweb:        https://git.kernel.org/tip/78a509fba9c9b1fcb77f95b7c6be30da3d24823a
Author:        Jun'ichi Nomura <junichi.nomura@nec.com>
AuthorDate:    Wed, 29 Nov 2023 15:44:49 -05:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Thu, 30 Nov 2023 09:55:40 +01:00

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>
---
 arch/x86/boot/compressed/ident_map_64.c    | 5 +++++
 arch/x86/boot/compressed/idt_64.c          | 1 +
 arch/x86/boot/compressed/idt_handlers_64.S | 1 +
 arch/x86/boot/compressed/misc.h            | 1 +
 4 files changed, 8 insertions(+)
  

Comments

Borislav Petkov Nov. 30, 2023, 10:33 a.m. UTC | #1
On Thu, Nov 30, 2023 at 08:59:44AM -0000, tip-bot2 for Jun'ichi Nomura wrote:
> +void do_boot_nmi_trap(struct pt_regs *regs, unsigned long error_code)
> +{
> +	/* Empty handler to ignore NMI during early boot */

It might be good to issue something here to say that a spurious NMI got
ignored.

Something ala

	error_putstr("Spurious early NMI ignored.\n");

so that we at least say that we ignored an NMI and not have it disappear
unnoticed.

Hmmm.
  
Ingo Molnar Jan. 8, 2024, 11:08 a.m. UTC | #2
* Borislav Petkov <bp@alien8.de> wrote:

> On Thu, Nov 30, 2023 at 08:59:44AM -0000, tip-bot2 for Jun'ichi Nomura wrote:
> > +void do_boot_nmi_trap(struct pt_regs *regs, unsigned long error_code)
> > +{
> > +	/* Empty handler to ignore NMI during early boot */
> 
> It might be good to issue something here to say that a spurious NMI got
> ignored.
> 
> Something ala
> 
> 	error_putstr("Spurious early NMI ignored.\n");
> 
> so that we at least say that we ignored an NMI and not have it disappear
> unnoticed.

That makes sense. Jun'ichi-san, could you please send a patch for this?

Thanks,

	Ingo
  
NOMURA JUNICHI(野村 淳一) Jan. 9, 2024, 5:17 a.m. UTC | #3
> From: Ingo Molnar <mingo.kernel.org@gmail.com>
> * Borislav Petkov <bp@alien8.de> wrote:
> > On Thu, Nov 30, 2023 at 08:59:44AM -0000, tip-bot2 for Jun'ichi Nomura wrote:
> > > +void do_boot_nmi_trap(struct pt_regs *regs, unsigned long error_code)
> > > +{
> > > +	/* Empty handler to ignore NMI during early boot */
> >
> > It might be good to issue something here to say that a spurious NMI got
> > ignored.
> >
> > Something ala
> >
> > 	error_putstr("Spurious early NMI ignored.\n");
> >
> > so that we at least say that we ignored an NMI and not have it disappear
> > unnoticed.
> 
> That makes sense. Jun'ichi-san, could you please send a patch for this?

Thank you for comments.  I currently don't have an environment to send a
patch without white space damage.  Could it be possible for you to apply
the attached one?

--
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.
  
NOMURA JUNICHI(野村 淳一) Jan. 12, 2024, 11:25 a.m. UTC | #4
> > From: Ingo Molnar <mingo.kernel.org@gmail.com>
> > * Borislav Petkov <bp@alien8.de> wrote:
> > > On Thu, Nov 30, 2023 at 08:59:44AM -0000, tip-bot2 for Jun'ichi Nomura wrote:
> > > > +void do_boot_nmi_trap(struct pt_regs *regs, unsigned long error_code)
> > > > +{
> > > > +	/* Empty handler to ignore NMI during early boot */
> > >
> > > It might be good to issue something here to say that a spurious NMI got
> > > ignored.
> > >
> > > Something ala
> > >
> > > 	error_putstr("Spurious early NMI ignored.\n");
> > >
> > > so that we at least say that we ignored an NMI and not have it disappear
> > > unnoticed.
> >
> > That makes sense. Jun'ichi-san, could you please send a patch for this?
> 
> Thank you for comments.  I currently don't have an environment to send a
> patch without white space damage.  Could it be possible for you to apply
> the attached one?

Sorry for the noise.  Finally I could send it out here without broken tabs.
https://lore.kernel.org/lkml/ZaEe8FC767f+sxRQ@jeru.linux.bs1.fc.nec.co.jp/

--
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.
  

Patch

diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c
index 473ba59..d040080 100644
--- a/arch/x86/boot/compressed/ident_map_64.c
+++ b/arch/x86/boot/compressed/ident_map_64.c
@@ -386,3 +386,8 @@  void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code)
 	 */
 	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 */
+}
diff --git a/arch/x86/boot/compressed/idt_64.c b/arch/x86/boot/compressed/idt_64.c
index 3cdf94b..d100284 100644
--- a/arch/x86/boot/compressed/idt_64.c
+++ b/arch/x86/boot/compressed/idt_64.c
@@ -61,6 +61,7 @@  void load_stage2_idt(void)
 	boot_idt_desc.address = (unsigned long)boot_idt;
 
 	set_idt_entry(X86_TRAP_PF, boot_page_fault);
+	set_idt_entry(X86_TRAP_NMI, boot_nmi_trap);
 
 #ifdef CONFIG_AMD_MEM_ENCRYPT
 	/*
diff --git a/arch/x86/boot/compressed/idt_handlers_64.S b/arch/x86/boot/compressed/idt_handlers_64.S
index 22890e1..4d03c85 100644
--- a/arch/x86/boot/compressed/idt_handlers_64.S
+++ b/arch/x86/boot/compressed/idt_handlers_64.S
@@ -70,6 +70,7 @@  SYM_FUNC_END(\name)
 	.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
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index c0d502b..bc2f0f1 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -196,6 +196,7 @@  static inline void cleanup_exception_handling(void) { }
 
 /* IDT Entry Points */
 void boot_page_fault(void);
+void boot_nmi_trap(void);
 void boot_stage1_vc(void);
 void boot_stage2_vc(void);