[PATCH v4 6/7] watchdog: pretimeout_panic: Use nmi_panic() when invoked from NMI context

From: Mayank Rungta

Date: Wed Nov 11 2026 - 22:20:27 EST


When a watchdog pretimeout interrupt is registered as an NMI (or
pseudo-NMI), pretimeout_panic() executes in NMI context. Calling plain
panic() from NMI context is unsafe if the current CPU was already inside
vpanic() with regular interrupts disabled (where the watchdog is no
longer fed): vpanic() assumes panic_cpu == raw_smp_processor_id() only
occurs when entered via nmi_panic(), so it falls through into a
recursive panic on the same CPU, corrupting the static panic buffer,
panic notifiers, and crash dump state.

Invoke nmi_panic() when in_nmi() is true so that an NMI interrupting a
CPU that is already panicking safely returns, or stops via
nmi_panic_self_stop() if another CPU is panicking.

Signed-off-by: Mayank Rungta <mrungta@xxxxxxxxxx>
---
drivers/watchdog/pretimeout_panic.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/pretimeout_panic.c b/drivers/watchdog/pretimeout_panic.c
index 8c3ac674dc45..634ae3b6c961 100644
--- a/drivers/watchdog/pretimeout_panic.c
+++ b/drivers/watchdog/pretimeout_panic.c
@@ -5,7 +5,10 @@

#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/panic.h>
+#include <linux/preempt.h>
#include <linux/watchdog.h>
+#include <asm/irq_regs.h>

#include "watchdog_pretimeout.h"

@@ -17,7 +20,10 @@
*/
static void pretimeout_panic(struct watchdog_device *wdd)
{
- panic("watchdog pretimeout event\n");
+ if (in_nmi())
+ nmi_panic(get_irq_regs(), "watchdog pretimeout event\n");
+ else
+ panic("watchdog pretimeout event\n");
}

static struct watchdog_governor watchdog_gov_panic = {
--
2.56.0.611.g1030f0b940-goog