Commit a0cb371b authored by Hou Wenlong's avatar Hou Wenlong Committed by Peter Zijlstra
Browse files

x86/bug: Handle __WARN_printf() trap in early_fixup_exception()



The commit 5b472b6e ("x86_64/bug: Implement __WARN_printf()")
implemented __WARN_printf(), which changed the mechanism to use UD1
instead of UD2. However, it only handles the trap in the runtime IDT
handler, while the early booting IDT handler lacks this handling. As a
result, the usage of WARN() before the runtime IDT setup can lead to
kernel crashes. Since KMSAN is enabled after the runtime IDT setup, it
is safe to use handle_bug() directly in early_fixup_exception() to
address this issue.

Fixes: 5b472b6e ("x86_64/bug: Implement __WARN_printf()")
Signed-off-by: default avatarHou Wenlong <houwenlong.hwl@antgroup.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/c4fb3645f60d3a78629d9870e8fcc8535281c24f.1768016713.git.houwenlong.hwl@antgroup.com
parent aa280a08
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ extern int ibt_selftest_noendbr(void);
void handle_invalid_op(struct pt_regs *regs);
#endif

noinstr bool handle_bug(struct pt_regs *regs);

static inline int get_si_code(unsigned long condition)
{
	if (condition & DR_STEP)
+1 −1
Original line number Diff line number Diff line
@@ -397,7 +397,7 @@ static inline void handle_invalid_op(struct pt_regs *regs)
		      ILL_ILLOPN, error_get_trap_addr(regs));
}

static noinstr bool handle_bug(struct pt_regs *regs)
noinstr bool handle_bug(struct pt_regs *regs)
{
	unsigned long addr = regs->ip;
	bool handled = false;
+2 −5
Original line number Diff line number Diff line
@@ -411,14 +411,11 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
		return;

	if (trapnr == X86_TRAP_UD) {
		if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN) {
			/* Skip the ud2. */
			regs->ip += LEN_UD2;
		if (handle_bug(regs))
			return;
		}

		/*
		 * If this was a BUG and report_bug returns or if this
		 * If this was a BUG and handle_bug returns or if this
		 * was just a normal #UD, we want to continue onward and
		 * crash.
		 */