From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from confino.investici.org (confino.investici.org [93.190.126.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D94C423760 for ; Wed, 8 Jul 2026 16:35:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=93.190.126.19 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783528540; cv=none; b=j8j/Ve/UlDshy9P1GvxnDG2JYOdvzNokDvw6b31zB7IrTD/+LIzlGlyBbwpRK59/0gLaApNbpdWJJIHXEEbE2K3hAWWLPCHVbSXJKb5eNn/FbhKv6LZ2I9cR8uhh1RAo725GLPL2dDzhuNH9l9vOgjGocZGgQNqucEWccxCFaRc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783528540; c=relaxed/simple; bh=9KpSss5H/QRjserQuUQTxgD63C0b5CkCfiF5oyeQQmU=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=kfnCwJVGFI4bgx2dUKrnJ6koONcu2ir/SbEfNhSV+hQp1++EmLc6lFpQhDKt+kkmMbLQOtcy37G607f81exj2mR0DzJSd4fXwZATVxVVp2A+q9NlWcQG+KM8aVug59EarNKX9/pBR/NCnSEIwlMOHesUD/n57In2p5cFb1xZWYg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=grrlz.net; spf=pass smtp.mailfrom=grrlz.net; dkim=pass (1024-bit key) header.d=grrlz.net header.i=@grrlz.net header.b=XjNy2NYj; arc=none smtp.client-ip=93.190.126.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=grrlz.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=grrlz.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=grrlz.net header.i=@grrlz.net header.b="XjNy2NYj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=grrlz.net; s=stigmate; t=1783528534; bh=rCKEMCZOsM5jmvBY27DJThfUq/5Ontz0sfy44JLo/nI=; h=From:To:Cc:Subject:Date:From; b=XjNy2NYjLnI3eLjygViaUJXE5x/0w7nBCpJbpqrAYo4+N2eQAQoAT1d5AEOcuvIE0 uoTAA0X9jsKRh/6OIRHdOI7HMdq5mABw/u+Cm/8jsKJKXW3a/Je0GFP6Dvd24UiMaE lQPO7GP8eLjLStNA5fkl8uwM6M4u+N49uIksQuKg= Received: from mx1.investici.org (unknown [127.0.0.1]) by confino.investici.org (Postfix) with ESMTP id 4gwNxf12n6z113n; Wed, 08 Jul 2026 16:35:34 +0000 (UTC) Received: by mx1.investici.org (Postfix) id 4gwNxd17kCz113S; Wed, 08 Jul 2026 16:35:33 +0000 (UTC) From: Bradley Morgan To: akpm@linux-foundation.org Cc: pmladek@suse.com, feng.tang@linux.alibaba.com, linux-kernel@vger.kernel.org, include@grrlz.net, Sashiko Subject: [PATCH v3] panic: fix redirect CPU race in panic_try_force_cpu() Date: Wed, 8 Jul 2026 16:35:32 +0000 Message-ID: <20260708163532.18538-1-include@grrlz.net> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 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 --- 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