The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Bradley Morgan <include@grrlz.net>
To: akpm@linux-foundation.org
Cc: pmladek@suse.com, feng.tang@linux.alibaba.com,
	linux-kernel@vger.kernel.org, include@grrlz.net,
	Sashiko <sashiko-bot@kernel.org>
Subject: [PATCH v3] panic: fix redirect CPU race in panic_try_force_cpu()
Date: Wed,  8 Jul 2026 16:35:32 +0000	[thread overview]
Message-ID: <20260708163532.18538-1-include@grrlz.net> (raw)

The cmpxchg() in panic_try_force_cpu() makes sure that only one CPU
tries to redirect panic() to the requested CPU. It is similar to the
cmpxchg() in panic_try_start() which makes sure that only one CPU does
the panic(). In both situations, only the winner of cmpxchg() should
proceed further. Other CPUs should go offline.

There is a bug in panic_try_force_cpu() because CPUs continue with
vpanic() when the cmpxchg() fails. As a result, they might win in
panic_try_start() instead of the requested CPU.

The loser cannot just return true, because a CPU that already won the
redirect cmpxchg and then reenters panic(), for example via an NMI
during the string formatting, would fail its own cmpxchg and stop
itself, abandoning the panic. Check old_cpu == this_cpu so a recursive
reentry falls through to panic_try_start() instead.

Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260705164123.18746-1-include@grrlz.net
Closes: https://sashiko.dev/#/patchset/20260707172252.4842-1-include@grrlz.net

Signed-off-by: Bradley Morgan <include@grrlz.net>
---
 kernel/panic.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Changes since v2:
  - Rewrote the commit message to describe the race and the recursive case.
  - Used Reported-by and Closes tags.
  - Documented the reason return old_cpu != this_cpu is needed.

diff --git a/kernel/panic.c b/kernel/panic.c
index 03f1eef07b17..ebdc46af6aa9 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -401,11 +401,11 @@ static bool panic_try_force_cpu(const char *fmt, va_list args)
 		return false;
 
 	/*
-	 * Only one CPU can do the redirect. Use atomic cmpxchg to ensure
-	 * we don't race with another CPU also trying to redirect.
+	 * Only one CPU can do the redirection. Others should go
+	 * offline. Continue with panic() when ending recursively here.
 	 */
 	if (!atomic_try_cmpxchg(&panic_redirect_cpu, &old_cpu, this_cpu))
-		return false;
+		return old_cpu != this_cpu;
 
 	/*
 	 * Use dynamically allocated buffer if available, otherwise
-- 
2.53.0


                 reply	other threads:[~2026-07-08 16:35 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260708163532.18538-1-include@grrlz.net \
    --to=include@grrlz.net \
    --cc=akpm@linux-foundation.org \
    --cc=feng.tang@linux.alibaba.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pmladek@suse.com \
    --cc=sashiko-bot@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox