lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260101123237.277411-1-pnina.feder@mobileye.com>
Date: Thu,  1 Jan 2026 14:32:37 +0200
From: Pnina Feder <pnina.feder@...ileye.com>
To: Andrew Morton <akpm@...ux-foundation.org>
Cc: Petr Mladek <pmladek@...e.com>,
	Sergey Senozhatsky <senozhatsky@...omium.org>,
	linux-kernel@...r.kernel.org,
	Pnina Feder <pnina.feder@...ileye.com>
Subject: [PATCH] panic/kexec: Allow forcing panic execution on a specific CPU

Some platforms require panic handling to execute on a specific CPU
for crash dump to work reliably. This may be due to firmware,
interrupt routing, or platform-specific constraints where only one
CPU is able to safely enter the crash kernel.

Add an optional configuration that allows redirecting panic execution
to a designated target CPU before invoking kexec into the crash kernel.

When CONFIG_PANIC_FORCE_CPU is enabled, the initial panic CPU will
forward the panic to the configured CPU using smp_call_function_single().
If a panic is already in progress on another CPU, redirection is
skipped and a warning is printed.

There is no functional change when the option is disabled.

Signed-off-by: Pnina Feder <pnina.feder@...ileye.com>
---
 kernel/Kconfig.kexec | 17 ++++++++++++
 kernel/panic.c       | 66 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
index 15632358bcf7..4ba08888cc4a 100644
--- a/kernel/Kconfig.kexec
+++ b/kernel/Kconfig.kexec
@@ -179,4 +179,21 @@ config CRASH_MAX_MEMORY_RANGES
 	  the computation behind the value provided through the
 	  /sys/kernel/crash_elfcorehdr_size attribute.
 
+config PANIC_FORCE_CPU
+	bool "Force panic to execute on a specific CPU"
+	depends on SMP && CRASH_DUMP
+	help
+	  Some platforms require panic handling to occur on a specific CPU
+	  for the crash kernel to function correctly. This option forces
+	  panic handling to be redirected to the specified CPU before kexec
+	  into the crash kernel.
+
+config PANIC_FORCE_CPU_ID
+	int "CPU number for panic execution"
+	depends on PANIC_FORCE_CPU
+	default 0
+	help
+	  The CPU number that should handle panic when PANIC_FORCE_CPU is
+	  enabled.
+
 endmenu
diff --git a/kernel/panic.c b/kernel/panic.c
index 0d52210a9e2b..c3fe254292c0 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -300,6 +300,65 @@ void __weak crash_smp_send_stop(void)
 
 atomic_t panic_cpu = ATOMIC_INIT(PANIC_CPU_INVALID);
 
+#ifdef CONFIG_PANIC_FORCE_CPU
+static void do_panic_on_target_cpu(void *info)
+{
+	panic("%s", (char *)info);
+}
+
+/**
+ * panic_force_target_cpu - Redirect panic to a specific CPU for crash kernel
+ * @fmt: panic message format string
+ * @args: arguments for format string
+ *
+ * Some platforms require panic handling to occur on a specific CPU
+ * for the crash kernel to function correctly. This function redirects
+ * panic handling to CONFIG_PANIC_FORCE_CPU_ID before kexec.
+ *
+ * Returns true if panic should proceed on current CPU.
+ * Returns false (never returns) if panic was redirected.
+ */
+static bool panic_force_target_cpu(const char *fmt, va_list args)
+{
+	static char panic_redirect_msg[1024];
+	int cpu = raw_smp_processor_id();
+	int target_cpu = CONFIG_PANIC_FORCE_CPU_ID;
+
+	/* Already on target CPU - proceed normally */
+	if (cpu == target_cpu)
+		return true;
+
+	/* Target CPU is offline, can't redirect */
+	if (!cpu_online(target_cpu)) {
+		pr_warn("panic: CPU %d is offline, cannot redirect panic. "
+			"Crash kernel interrupts may be unavailable.\n", target_cpu);
+		return true;
+	}
+
+	/* Another panic already in progress */
+	if (panic_in_progress()) {
+		pr_warn("panic: Another panic in progress on CPU %d, cannot redirect to CPU %d. "
+			"Crash kernel interrupts may be unavailable.\n",
+			atomic_read(&panic_cpu), target_cpu);
+		return true;
+	}
+
+	pr_info("panic: Redirecting from CPU %d to CPU %d for crash kernel\n",
+		cpu, target_cpu);
+
+	vsnprintf(panic_redirect_msg, sizeof(panic_redirect_msg), fmt, args);
+
+	smp_call_function_single(target_cpu, do_panic_on_target_cpu, panic_redirect_msg, false);
+
+	return false;
+}
+#else
+static inline bool panic_force_target_cpu(const char *fmt, va_list args)
+{
+	return true;
+}
+#endif /* CONFIG_PANIC_FORCE_CPU */
+
 bool panic_try_start(void)
 {
 	int old_cpu, this_cpu;
@@ -451,6 +510,13 @@ void vpanic(const char *fmt, va_list args)
 	local_irq_disable();
 	preempt_disable_notrace();
 
+	/*
+	 * Redirect panic to target CPU if configured (CONFIG_PANIC_FORCE_CPU).
+	 * Returns false and never returns if panic was redirected.
+	 */
+	if (!panic_force_target_cpu(fmt, args))
+		panic_smp_self_stop();
+
 	/*
 	 * It's possible to come here directly from a panic-assertion and
 	 * not have preempt disabled. Some functions called from here want
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ