The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH 0/3] watchdog: qcom: Support NMI pretimeout warnings
@ 2026-07-30 21:32 Mayank Rungta via B4 Relay
  2026-07-30 21:32 ` [PATCH 1/3] watchdog: pretimeout: Protect governor access with RCU for NMI safety Mayank Rungta via B4 Relay
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Mayank Rungta via B4 Relay @ 2026-07-30 21:32 UTC (permalink / raw)
  To: Wim Van Sebroeck, Guenter Roeck, Thomas Gleixner
  Cc: linux-watchdog, linux-kernel, linux-arm-msm, Kirill A. Shutemov,
	Douglas Anderson, Mayank Rungta

On ARM64 Qualcomm SoCs, when a system freezes completely due to hard
locked CPUs with standard interrupts disabled, a standard watchdog
pretimeout warning interrupt (bark) fails to fire. To diagnose total
system lockups, we need to transition the Qualcomm hardware watchdog
pretimeout bark interrupt into an NMI (or pseudo-NMI).

Enabling NMI pretimeout handlers within loadable driver module requires
making watchdog pretimeout NMI-safe and unlocking GPL module access to
NMI registration functions.

This 3-patch series achieves NMI pretimeout enablement for qcom-wdt:
 1) Replaces spinlocks in watchdog_notify_pretimeout() with RCU to
    guarantee safe execution from NMI context.
 2) Exports request_nmi(), free_nmi(), enable_nmi(), and
    disable_nmi_nosync() to GPL loadable kernel modules.
 3) Updates qcom-wdt to request its pretimeout bark interrupt as a
    NMI (or pseudo-NMI).

Testing & Verification:
 - Built and tested on ARM64 Qualcomm Snapdragon SoC (Google CoachZ)
   loadable module configurations (CONFIG_QCOM_WDT=m).
 - With GICv3 pseudo-NMI enabled, simulated hard CPU lockups and
   IRQ-disabled hang conditions via lkdtm. Confirmed that qcom-wdt traps
   the watchdog pretimeout bark interrupt as a pseudo-NMI, safely
   executes watchdog_notify_pretimeout() without deadlocks.
 - Verified that runtime transitions between pretimeout governors in
   sysfs execute safely.
 - Booted with pseudo-NMIs disabled and confirmed that qcom-wdt detects
   unsupported NMI and falls back to standard IRQ.

Signed-off-by: Mayank Rungta <mrungta@google.com>
---
Mayank Rungta (3):
      watchdog: pretimeout: Protect governor access with RCU for NMI safety
      genirq: Export NMI APIs
      watchdog: qcom: Register pretimeout interrupt as NMI

 drivers/watchdog/qcom-wdt.c            | 55 +++++++++++++++++++++++++++++++---
 drivers/watchdog/watchdog_pretimeout.c | 47 ++++++++++++++++-------------
 include/linux/watchdog.h               |  2 +-
 kernel/irq/manage.c                    |  4 +++
 4 files changed, 82 insertions(+), 26 deletions(-)
---
base-commit: 3fe08b9796f36ef437ab9328e7dd1e5ff2d66603
change-id: 20260724-qcom-wdt-nmi-series-06a48da7b415

Best regards,
-- 
Mayank Rungta <mrungta@google.com>



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/3] watchdog: pretimeout: Protect governor access with RCU for NMI safety
  2026-07-30 21:32 [PATCH 0/3] watchdog: qcom: Support NMI pretimeout warnings Mayank Rungta via B4 Relay
@ 2026-07-30 21:32 ` Mayank Rungta via B4 Relay
  2026-07-30 21:46   ` Doug Anderson
  2026-07-30 21:32 ` [PATCH 2/3] genirq: Export NMI APIs Mayank Rungta via B4 Relay
  2026-07-30 21:32 ` [PATCH 3/3] watchdog: qcom: Register pretimeout interrupt as NMI Mayank Rungta via B4 Relay
  2 siblings, 1 reply; 14+ messages in thread
From: Mayank Rungta via B4 Relay @ 2026-07-30 21:32 UTC (permalink / raw)
  To: Wim Van Sebroeck, Guenter Roeck, Thomas Gleixner
  Cc: linux-watchdog, linux-kernel, linux-arm-msm, Kirill A. Shutemov,
	Douglas Anderson, Mayank Rungta

From: Mayank Rungta <mrungta@google.com>

Currently, watchdog_notify_pretimeout() acquires pretimeout_lock using
spin_lock_irqsave() to safely dereference wdd->gov before invoking the
pretimeout callback.

On architectures supporting pseudo-NMIs (ARM64 GICv3), watchdog drivers
may register their pretimeout warning interrupt (bark) as an NMI.
Because spin_lock_irqsave() disables regular interrupts but leaves NMIs
unmasked, if a pretimeout NMI fires while pretimeout_lock is already
held by normal process context, attempting to re-acquire pretimeout_lock
triggers an unrecoverable deadlock.

To make pretimeout notifications completely safe to execute from NMI,
convert read access to wdd->gov inside watchdog_notify_pretimeout() from
a spinlock to lockless RCU. Use rcu_assign_pointer() when modifying
wdd->gov and invoke synchronize_rcu() during governor unregister and
pretimeout unregister routines.

Signed-off-by: Mayank Rungta <mrungta@google.com>
---
 drivers/watchdog/watchdog_pretimeout.c | 47 +++++++++++++++++++---------------
 include/linux/watchdog.h               |  2 +-
 2 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/drivers/watchdog/watchdog_pretimeout.c b/drivers/watchdog/watchdog_pretimeout.c
index 02e09b9e396d..3793d4cb60f8 100644
--- a/drivers/watchdog/watchdog_pretimeout.c
+++ b/drivers/watchdog/watchdog_pretimeout.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/list.h>
+#include <linux/rcupdate.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
@@ -17,7 +18,7 @@
 /* Default watchdog pretimeout governor */
 static struct watchdog_governor *default_gov;
 
-/* The spinlock protects default_gov, wdd->gov and pretimeout_list */
+/* The spinlock protects default_gov and pretimeout_list */
 static DEFINE_SPINLOCK(pretimeout_lock);
 
 /* List of watchdog devices, which can generate a pretimeout event */
@@ -67,12 +68,14 @@ int watchdog_pretimeout_available_governors_get(char *buf)
 
 int watchdog_pretimeout_governor_get(struct watchdog_device *wdd, char *buf)
 {
+	struct watchdog_governor *gov;
 	int count = 0;
 
-	spin_lock_irq(&pretimeout_lock);
-	if (wdd->gov)
-		count = sysfs_emit(buf, "%s\n", wdd->gov->name);
-	spin_unlock_irq(&pretimeout_lock);
+	rcu_read_lock();
+	gov = rcu_dereference(wdd->gov);
+	if (gov)
+		count = sysfs_emit(buf, "%s\n", gov->name);
+	rcu_read_unlock();
 
 	return count;
 }
@@ -91,7 +94,7 @@ int watchdog_pretimeout_governor_set(struct watchdog_device *wdd,
 	}
 
 	spin_lock_irq(&pretimeout_lock);
-	wdd->gov = priv->gov;
+	rcu_assign_pointer(wdd->gov, priv->gov);
 	spin_unlock_irq(&pretimeout_lock);
 
 	mutex_unlock(&governor_lock);
@@ -101,16 +104,13 @@ int watchdog_pretimeout_governor_set(struct watchdog_device *wdd,
 
 void watchdog_notify_pretimeout(struct watchdog_device *wdd)
 {
-	unsigned long flags;
+	struct watchdog_governor *gov;
 
-	spin_lock_irqsave(&pretimeout_lock, flags);
-	if (!wdd->gov) {
-		spin_unlock_irqrestore(&pretimeout_lock, flags);
-		return;
-	}
-
-	wdd->gov->pretimeout(wdd);
-	spin_unlock_irqrestore(&pretimeout_lock, flags);
+	rcu_read_lock();
+	gov = rcu_dereference(wdd->gov);
+	if (gov)
+		gov->pretimeout(wdd);
+	rcu_read_unlock();
 }
 EXPORT_SYMBOL_GPL(watchdog_notify_pretimeout);
 
@@ -140,8 +140,8 @@ int watchdog_register_governor(struct watchdog_governor *gov)
 		default_gov = gov;
 
 		list_for_each_entry(p, &pretimeout_list, entry)
-			if (!p->wdd->gov)
-				p->wdd->gov = default_gov;
+			if (!rcu_access_pointer(p->wdd->gov))
+				rcu_assign_pointer(p->wdd->gov, default_gov);
 		spin_unlock_irq(&pretimeout_lock);
 	}
 
@@ -170,11 +170,14 @@ void watchdog_unregister_governor(struct watchdog_governor *gov)
 	if (default_gov == gov)
 		default_gov = NULL;
 	list_for_each_entry(p, &pretimeout_list, entry)
-		if (p->wdd->gov == gov)
-			p->wdd->gov = default_gov;
+		if (rcu_dereference_protected(p->wdd->gov,
+					      lockdep_is_held(&pretimeout_lock)) == gov)
+			rcu_assign_pointer(p->wdd->gov, default_gov);
 	spin_unlock_irq(&pretimeout_lock);
 
 	mutex_unlock(&governor_lock);
+
+	synchronize_rcu();
 }
 EXPORT_SYMBOL(watchdog_unregister_governor);
 
@@ -192,7 +195,7 @@ int watchdog_register_pretimeout(struct watchdog_device *wdd)
 	spin_lock_irq(&pretimeout_lock);
 	list_add(&p->entry, &pretimeout_list);
 	p->wdd = wdd;
-	wdd->gov = default_gov;
+	rcu_assign_pointer(wdd->gov, default_gov);
 	spin_unlock_irq(&pretimeout_lock);
 
 	return 0;
@@ -206,7 +209,7 @@ void watchdog_unregister_pretimeout(struct watchdog_device *wdd)
 		return;
 
 	spin_lock_irq(&pretimeout_lock);
-	wdd->gov = NULL;
+	rcu_assign_pointer(wdd->gov, NULL);
 
 	list_for_each_entry_safe(p, t, &pretimeout_list, entry) {
 		if (p->wdd == wdd) {
@@ -216,4 +219,6 @@ void watchdog_unregister_pretimeout(struct watchdog_device *wdd)
 		}
 	}
 	spin_unlock_irq(&pretimeout_lock);
+
+	synchronize_rcu();
 }
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index 29cd03686154..5a3c35968cc8 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -105,7 +105,7 @@ struct watchdog_device {
 	const struct attribute_group **groups;
 	const struct watchdog_info *info;
 	const struct watchdog_ops *ops;
-	const struct watchdog_governor *gov;
+	const struct watchdog_governor __rcu *gov;
 	unsigned int bootstatus;
 	unsigned int timeout;
 	unsigned int pretimeout;

-- 
2.55.0.508.g3f0d502094-goog



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/3] genirq: Export NMI APIs
  2026-07-30 21:32 [PATCH 0/3] watchdog: qcom: Support NMI pretimeout warnings Mayank Rungta via B4 Relay
  2026-07-30 21:32 ` [PATCH 1/3] watchdog: pretimeout: Protect governor access with RCU for NMI safety Mayank Rungta via B4 Relay
@ 2026-07-30 21:32 ` Mayank Rungta via B4 Relay
  2026-07-30 21:49   ` Doug Anderson
  2026-07-30 21:32 ` [PATCH 3/3] watchdog: qcom: Register pretimeout interrupt as NMI Mayank Rungta via B4 Relay
  2 siblings, 1 reply; 14+ messages in thread
From: Mayank Rungta via B4 Relay @ 2026-07-30 21:32 UTC (permalink / raw)
  To: Wim Van Sebroeck, Guenter Roeck, Thomas Gleixner
  Cc: linux-watchdog, linux-kernel, linux-arm-msm, Kirill A. Shutemov,
	Douglas Anderson, Mayank Rungta

From: Mayank Rungta <mrungta@google.com>

Currently, request_nmi(), free_nmi(), enable_nmi() and disable_nmi_nosync()
are restricted to built-in kernel code because they are not exported to
loadable modules.

Export these APIs to allow loadable modules to register and manage NMIs.
This allows watchdog drivers configured as loadable modules to register
their bark interrupt as an NMI.

Signed-off-by: Mayank Rungta <mrungta@google.com>
---
 kernel/irq/manage.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 2fbff2618a1e..fb0b8da32f4c 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -766,6 +766,7 @@ void disable_nmi_nosync(unsigned int irq)
 {
 	disable_irq_nosync(irq);
 }
+EXPORT_SYMBOL_GPL(disable_nmi_nosync);
 
 void __enable_irq(struct irq_desc *desc)
 {
@@ -833,6 +834,7 @@ void enable_nmi(unsigned int irq)
 {
 	enable_irq(irq);
 }
+EXPORT_SYMBOL_GPL(enable_nmi);
 
 static int set_irq_wake_real(unsigned int irq, unsigned int on)
 {
@@ -2080,6 +2082,7 @@ const void *free_nmi(unsigned int irq, void *dev_id)
 
 	return __cleanup_nmi(irq, desc);
 }
+EXPORT_SYMBOL_GPL(free_nmi);
 
 /**
  * request_threaded_irq - allocate an interrupt line
@@ -2342,6 +2345,7 @@ int request_nmi(unsigned int irq, irq_handler_t handler,
 
 	return retval;
 }
+EXPORT_SYMBOL_GPL(request_nmi);
 
 void enable_percpu_irq(unsigned int irq, unsigned int type)
 {

-- 
2.55.0.508.g3f0d502094-goog



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/3] watchdog: qcom: Register pretimeout interrupt as NMI
  2026-07-30 21:32 [PATCH 0/3] watchdog: qcom: Support NMI pretimeout warnings Mayank Rungta via B4 Relay
  2026-07-30 21:32 ` [PATCH 1/3] watchdog: pretimeout: Protect governor access with RCU for NMI safety Mayank Rungta via B4 Relay
  2026-07-30 21:32 ` [PATCH 2/3] genirq: Export NMI APIs Mayank Rungta via B4 Relay
@ 2026-07-30 21:32 ` Mayank Rungta via B4 Relay
  2026-07-30 21:52   ` Doug Anderson
  2026-07-31 11:56   ` Konrad Dybcio
  2 siblings, 2 replies; 14+ messages in thread
From: Mayank Rungta via B4 Relay @ 2026-07-30 21:32 UTC (permalink / raw)
  To: Wim Van Sebroeck, Guenter Roeck, Thomas Gleixner
  Cc: linux-watchdog, linux-kernel, linux-arm-msm, Kirill A. Shutemov,
	Douglas Anderson, Mayank Rungta

From: Mayank Rungta <mrungta@google.com>

When a system is completely unresponsive due to an interrupt storm or
deadlocked CPU cores with standard interrupts disabled, a standard watchdog
pretimeout bark interrupt will fail to execute, preventing the pretimeout
governor from capturing CPU backtraces before the hardware reset bite.

Attempt to register the pretimeout interrupt as an NMI (or pseudo-NMI)
using request_nmi(). If NMI registration fails due to lack of platform
GIC pseudo-NMI support, fall back to devm_request_irq().

Explicitly arm and disarm the NMI during watchdog start and stop operations
using enable_nmi() and disable_nmi_nosync().

NMI Execution Call Trace (lkdtm HARDLOCKUP freeze break):
 Kernel panic - not syncing: watchdog pretimeout event
 CPU: 0 UID: 0 PID: 5419 Comm: bash Not tainted 6.19.0-rc5-00022
 Hardware name: Google CoachZ (rev3+) (DT)
 Call trace:
  show_stack+0x24/0x34 (C)
  dump_stack_lvl+0x84/0xac
  dump_stack+0x1c/0x34
  vpanic+0xfc/0x2d0
  panic+0x6c/0x74
  watchdog_notify_pretimeout+0x34/0x48
  qcom_wdt_isr+0x20/0x34
  handle_fasteoi_nmi+0x50/0x88
  handle_irq_desc+0x4c/0x68
  generic_handle_domain_nmi+0x38/0x48
  __gic_handle_nmi.isra.0+0x40/0x90
  gic_handle_irq+0x64/0x234
  call_on_irq_stack+0x48/0x88
  do_interrupt_handler+0x74/0xc4
  el1_interrupt+0x5c/0xb0
  lkdtm_HARDLOCKUP+0x18/0x28 (P)

Signed-off-by: Mayank Rungta <mrungta@google.com>
---
 drivers/watchdog/qcom-wdt.c | 55 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 4 deletions(-)

diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index 49bd04841f0c..19d8e91cff40 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -51,6 +51,9 @@ struct qcom_wdt {
 	unsigned long		rate;
 	void __iomem		*base;
 	const u32		*layout;
+	int			irq;
+	bool			is_nmi;
+	bool			irq_enabled;
 };
 
 static void __iomem *wdt_addr(struct qcom_wdt *wdt, enum wdt_reg reg)
@@ -73,6 +76,30 @@ static irqreturn_t qcom_wdt_isr(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
+static void qcom_wdt_enable_irq(struct qcom_wdt *wdt)
+{
+	if (wdt->is_nmi && wdt->irq > 0 && !wdt->irq_enabled) {
+		enable_nmi(wdt->irq);
+		wdt->irq_enabled = true;
+	}
+}
+
+static void qcom_wdt_disable_irq(struct qcom_wdt *wdt)
+{
+	if (wdt->is_nmi && wdt->irq > 0 && wdt->irq_enabled) {
+		disable_nmi_nosync(wdt->irq);
+		wdt->irq_enabled = false;
+	}
+}
+
+static void qcom_wdt_free_nmi(void *arg)
+{
+	struct qcom_wdt *wdt = arg;
+
+	qcom_wdt_disable_irq(wdt);
+	free_nmi(wdt->irq, &wdt->wdd);
+}
+
 static int qcom_wdt_start(struct watchdog_device *wdd)
 {
 	struct qcom_wdt *wdt = to_qcom_wdt(wdd);
@@ -83,6 +110,8 @@ static int qcom_wdt_start(struct watchdog_device *wdd)
 	writel(bark * wdt->rate, wdt_addr(wdt, WDT_BARK_TIME));
 	writel(wdd->timeout * wdt->rate, wdt_addr(wdt, WDT_BITE_TIME));
 	writel(QCOM_WDT_ENABLE, wdt_addr(wdt, WDT_EN));
+
+	qcom_wdt_enable_irq(wdt);
 	return 0;
 }
 
@@ -90,6 +119,8 @@ static int qcom_wdt_stop(struct watchdog_device *wdd)
 {
 	struct qcom_wdt *wdt = to_qcom_wdt(wdd);
 
+	qcom_wdt_disable_irq(wdt);
+
 	writel(0, wdt_addr(wdt, WDT_EN));
 	return 0;
 }
@@ -240,6 +271,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
 	u32 percpu_offset;
 	int irq, ret;
 	struct clk *clk;
+	unsigned long irq_flags;
 
 	data = of_device_get_match_data(dev);
 	if (!data) {
@@ -290,10 +322,25 @@ static int qcom_wdt_probe(struct platform_device *pdev)
 	/* check if there is pretimeout support */
 	irq = platform_get_irq_optional(pdev, 0);
 	if (data->pretimeout && irq > 0) {
-		ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0,
-				       "wdt_bark", &wdt->wdd);
-		if (ret)
-			return ret;
+		wdt->irq = irq;
+		irq_flags = IRQF_PERCPU | IRQF_NOBALANCING |
+			    IRQF_NO_AUTOEN | IRQF_NO_THREAD;
+
+		ret = request_nmi(irq, qcom_wdt_isr, irq_flags,
+				  "wdt_bark", &wdt->wdd);
+		if (ret) {
+			/* Fallback to normal interrupt if NMI not supported */
+			ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0,
+					       "wdt_bark", &wdt->wdd);
+			if (ret)
+				return ret;
+		} else {
+			wdt->is_nmi = true;
+			ret = devm_add_action_or_reset(dev, qcom_wdt_free_nmi,
+						       wdt);
+			if (ret)
+				return ret;
+		}
 
 		wdt->wdd.info = &qcom_wdt_pt_info;
 		wdt->wdd.pretimeout = 1;

-- 
2.55.0.508.g3f0d502094-goog



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/3] watchdog: pretimeout: Protect governor access with RCU for NMI safety
  2026-07-30 21:32 ` [PATCH 1/3] watchdog: pretimeout: Protect governor access with RCU for NMI safety Mayank Rungta via B4 Relay
@ 2026-07-30 21:46   ` Doug Anderson
  2026-08-07  5:34     ` Guenter Roeck
  0 siblings, 1 reply; 14+ messages in thread
From: Doug Anderson @ 2026-07-30 21:46 UTC (permalink / raw)
  To: mrungta
  Cc: Wim Van Sebroeck, Guenter Roeck, Thomas Gleixner, linux-watchdog,
	linux-kernel, linux-arm-msm, Kirill A. Shutemov

Hi,

On Thu, Jul 30, 2026 at 2:33 PM Mayank Rungta via B4 Relay
<devnull+mrungta.google.com@kernel.org> wrote:
>
> From: Mayank Rungta <mrungta@google.com>
>
> Currently, watchdog_notify_pretimeout() acquires pretimeout_lock using
> spin_lock_irqsave() to safely dereference wdd->gov before invoking the
> pretimeout callback.
>
> On architectures supporting pseudo-NMIs (ARM64 GICv3), watchdog drivers
> may register their pretimeout warning interrupt (bark) as an NMI.
> Because spin_lock_irqsave() disables regular interrupts but leaves NMIs
> unmasked, if a pretimeout NMI fires while pretimeout_lock is already
> held by normal process context, attempting to re-acquire pretimeout_lock
> triggers an unrecoverable deadlock.
>
> To make pretimeout notifications completely safe to execute from NMI,
> convert read access to wdd->gov inside watchdog_notify_pretimeout() from
> a spinlock to lockless RCU. Use rcu_assign_pointer() when modifying
> wdd->gov and invoke synchronize_rcu() during governor unregister and
> pretimeout unregister routines.
>
> Signed-off-by: Mayank Rungta <mrungta@google.com>
> ---
>  drivers/watchdog/watchdog_pretimeout.c | 47 +++++++++++++++++++---------------
>  include/linux/watchdog.h               |  2 +-
>  2 files changed, 27 insertions(+), 22 deletions(-)

I pre-reviewed this for Mayank. I'm not an RCU expert, but this looks
right based on my understanding. My AI was also happy with it. ;-)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/3] genirq: Export NMI APIs
  2026-07-30 21:32 ` [PATCH 2/3] genirq: Export NMI APIs Mayank Rungta via B4 Relay
@ 2026-07-30 21:49   ` Doug Anderson
  2026-07-30 22:55     ` Guenter Roeck
  0 siblings, 1 reply; 14+ messages in thread
From: Doug Anderson @ 2026-07-30 21:49 UTC (permalink / raw)
  To: mrungta
  Cc: Wim Van Sebroeck, Guenter Roeck, Thomas Gleixner, linux-watchdog,
	linux-kernel, linux-arm-msm, Kirill A. Shutemov

Hi,

On Thu, Jul 30, 2026 at 2:33 PM Mayank Rungta via B4 Relay
<devnull+mrungta.google.com@kernel.org> wrote:
>
> From: Mayank Rungta <mrungta@google.com>
>
> Currently, request_nmi(), free_nmi(), enable_nmi() and disable_nmi_nosync()
> are restricted to built-in kernel code because they are not exported to
> loadable modules.
>
> Export these APIs to allow loadable modules to register and manage NMIs.
> This allows watchdog drivers configured as loadable modules to register
> their bark interrupt as an NMI.
>
> Signed-off-by: Mayank Rungta <mrungta@google.com>
> ---
>  kernel/irq/manage.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
> index 2fbff2618a1e..fb0b8da32f4c 100644
> --- a/kernel/irq/manage.c
> +++ b/kernel/irq/manage.c
> @@ -766,6 +766,7 @@ void disable_nmi_nosync(unsigned int irq)
>  {
>         disable_irq_nosync(irq);
>  }
> +EXPORT_SYMBOL_GPL(disable_nmi_nosync);
>
>  void __enable_irq(struct irq_desc *desc)
>  {
> @@ -833,6 +834,7 @@ void enable_nmi(unsigned int irq)
>  {
>         enable_irq(irq);
>  }
> +EXPORT_SYMBOL_GPL(enable_nmi);
>
>  static int set_irq_wake_real(unsigned int irq, unsigned int on)
>  {
> @@ -2080,6 +2082,7 @@ const void *free_nmi(unsigned int irq, void *dev_id)
>
>         return __cleanup_nmi(irq, desc);
>  }
> +EXPORT_SYMBOL_GPL(free_nmi);
>
>  /**
>   * request_threaded_irq - allocate an interrupt line
> @@ -2342,6 +2345,7 @@ int request_nmi(unsigned int irq, irq_handler_t handler,
>
>         return retval;
>  }
> +EXPORT_SYMBOL_GPL(request_nmi);

This seems reasonable to me. One thought I had was that we could
possibly get by with fewer exported symbols by changing
disable_nmi_nosync() and enable_nmi() to "static inline" functions in
the header file. That being said, what Mayank has here feels slightly
better to me.

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/3] watchdog: qcom: Register pretimeout interrupt as NMI
  2026-07-30 21:32 ` [PATCH 3/3] watchdog: qcom: Register pretimeout interrupt as NMI Mayank Rungta via B4 Relay
@ 2026-07-30 21:52   ` Doug Anderson
  2026-07-31 11:56   ` Konrad Dybcio
  1 sibling, 0 replies; 14+ messages in thread
From: Doug Anderson @ 2026-07-30 21:52 UTC (permalink / raw)
  To: mrungta
  Cc: Wim Van Sebroeck, Guenter Roeck, Thomas Gleixner, linux-watchdog,
	linux-kernel, linux-arm-msm, Kirill A. Shutemov

Hi,

On Thu, Jul 30, 2026 at 2:33 PM Mayank Rungta via B4 Relay
<devnull+mrungta.google.com@kernel.org> wrote:
>
> From: Mayank Rungta <mrungta@google.com>
>
> When a system is completely unresponsive due to an interrupt storm or
> deadlocked CPU cores with standard interrupts disabled, a standard watchdog
> pretimeout bark interrupt will fail to execute, preventing the pretimeout
> governor from capturing CPU backtraces before the hardware reset bite.
>
> Attempt to register the pretimeout interrupt as an NMI (or pseudo-NMI)
> using request_nmi(). If NMI registration fails due to lack of platform
> GIC pseudo-NMI support, fall back to devm_request_irq().
>
> Explicitly arm and disarm the NMI during watchdog start and stop operations
> using enable_nmi() and disable_nmi_nosync().
>
> NMI Execution Call Trace (lkdtm HARDLOCKUP freeze break):
>  Kernel panic - not syncing: watchdog pretimeout event
>  CPU: 0 UID: 0 PID: 5419 Comm: bash Not tainted 6.19.0-rc5-00022
>  Hardware name: Google CoachZ (rev3+) (DT)
>  Call trace:
>   show_stack+0x24/0x34 (C)
>   dump_stack_lvl+0x84/0xac
>   dump_stack+0x1c/0x34
>   vpanic+0xfc/0x2d0
>   panic+0x6c/0x74
>   watchdog_notify_pretimeout+0x34/0x48
>   qcom_wdt_isr+0x20/0x34
>   handle_fasteoi_nmi+0x50/0x88
>   handle_irq_desc+0x4c/0x68
>   generic_handle_domain_nmi+0x38/0x48
>   __gic_handle_nmi.isra.0+0x40/0x90
>   gic_handle_irq+0x64/0x234
>   call_on_irq_stack+0x48/0x88
>   do_interrupt_handler+0x74/0xc4
>   el1_interrupt+0x5c/0xb0
>   lkdtm_HARDLOCKUP+0x18/0x28 (P)
>
> Signed-off-by: Mayank Rungta <mrungta@google.com>
> ---
>  drivers/watchdog/qcom-wdt.c | 55 +++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 51 insertions(+), 4 deletions(-)

I pre-reviewed this for Mayank and it looks reasonable to me.

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/3] genirq: Export NMI APIs
  2026-07-30 21:49   ` Doug Anderson
@ 2026-07-30 22:55     ` Guenter Roeck
  2026-07-31 23:18       ` Doug Anderson
  0 siblings, 1 reply; 14+ messages in thread
From: Guenter Roeck @ 2026-07-30 22:55 UTC (permalink / raw)
  To: Doug Anderson, mrungta
  Cc: Wim Van Sebroeck, Thomas Gleixner, linux-watchdog, linux-kernel,
	linux-arm-msm, Kirill A. Shutemov

On 7/30/26 14:49, Doug Anderson wrote:
> Hi,
> 
> On Thu, Jul 30, 2026 at 2:33 PM Mayank Rungta via B4 Relay
> <devnull+mrungta.google.com@kernel.org> wrote:
>>
>> From: Mayank Rungta <mrungta@google.com>
>>
>> Currently, request_nmi(), free_nmi(), enable_nmi() and disable_nmi_nosync()
>> are restricted to built-in kernel code because they are not exported to
>> loadable modules.
>>
>> Export these APIs to allow loadable modules to register and manage NMIs.
>> This allows watchdog drivers configured as loadable modules to register
>> their bark interrupt as an NMI.
>>
>> Signed-off-by: Mayank Rungta <mrungta@google.com>
>> ---
>>   kernel/irq/manage.c | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
>> index 2fbff2618a1e..fb0b8da32f4c 100644
>> --- a/kernel/irq/manage.c
>> +++ b/kernel/irq/manage.c
>> @@ -766,6 +766,7 @@ void disable_nmi_nosync(unsigned int irq)
>>   {
>>          disable_irq_nosync(irq);
>>   }
>> +EXPORT_SYMBOL_GPL(disable_nmi_nosync);
>>
>>   void __enable_irq(struct irq_desc *desc)
>>   {
>> @@ -833,6 +834,7 @@ void enable_nmi(unsigned int irq)
>>   {
>>          enable_irq(irq);
>>   }
>> +EXPORT_SYMBOL_GPL(enable_nmi);
>>
>>   static int set_irq_wake_real(unsigned int irq, unsigned int on)
>>   {
>> @@ -2080,6 +2082,7 @@ const void *free_nmi(unsigned int irq, void *dev_id)
>>
>>          return __cleanup_nmi(irq, desc);
>>   }
>> +EXPORT_SYMBOL_GPL(free_nmi);
>>
>>   /**
>>    * request_threaded_irq - allocate an interrupt line
>> @@ -2342,6 +2345,7 @@ int request_nmi(unsigned int irq, irq_handler_t handler,
>>
>>          return retval;
>>   }
>> +EXPORT_SYMBOL_GPL(request_nmi);
> 
> This seems reasonable to me. One thought I had was that we could
> possibly get by with fewer exported symbols by changing
> disable_nmi_nosync() and enable_nmi() to "static inline" functions in
> the header file. That being said, what Mayank has here feels slightly
> better to me.
> 

I don't claim to understand the NMI APIs used, but Sashiko's feedback
seems real to me. Someone who knows that code will need to confirm that
there are no unexpected pitfalls.

Thanks,
Guenter


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/3] watchdog: qcom: Register pretimeout interrupt as NMI
  2026-07-30 21:32 ` [PATCH 3/3] watchdog: qcom: Register pretimeout interrupt as NMI Mayank Rungta via B4 Relay
  2026-07-30 21:52   ` Doug Anderson
@ 2026-07-31 11:56   ` Konrad Dybcio
  2026-07-31 14:12     ` Guenter Roeck
  1 sibling, 1 reply; 14+ messages in thread
From: Konrad Dybcio @ 2026-07-31 11:56 UTC (permalink / raw)
  To: mrungta, Wim Van Sebroeck, Guenter Roeck, Thomas Gleixner
  Cc: linux-watchdog, linux-kernel, linux-arm-msm, Kirill A. Shutemov,
	Douglas Anderson

On 7/30/26 11:32 PM, Mayank Rungta via B4 Relay wrote:
> From: Mayank Rungta <mrungta@google.com>
> 
> When a system is completely unresponsive due to an interrupt storm or
> deadlocked CPU cores with standard interrupts disabled, a standard watchdog
> pretimeout bark interrupt will fail to execute, preventing the pretimeout
> governor from capturing CPU backtraces before the hardware reset bite.

[...]

>  drivers/watchdog/qcom-wdt.c | 55 +++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 51 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
> index 49bd04841f0c..19d8e91cff40 100644
> --- a/drivers/watchdog/qcom-wdt.c
> +++ b/drivers/watchdog/qcom-wdt.c
> @@ -51,6 +51,9 @@ struct qcom_wdt {
>  	unsigned long		rate;
>  	void __iomem		*base;
>  	const u32		*layout;
> +	int			irq;
> +	bool			is_nmi;
> +	bool			irq_enabled;

Do we need to track this? I think we can rely on the framework
NOPing out multiple ops->start requests

Konrad

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/3] watchdog: qcom: Register pretimeout interrupt as NMI
  2026-07-31 11:56   ` Konrad Dybcio
@ 2026-07-31 14:12     ` Guenter Roeck
  2026-07-31 23:54       ` Mayank Rungta
  0 siblings, 1 reply; 14+ messages in thread
From: Guenter Roeck @ 2026-07-31 14:12 UTC (permalink / raw)
  To: Konrad Dybcio, mrungta, Wim Van Sebroeck, Thomas Gleixner
  Cc: linux-watchdog, linux-kernel, linux-arm-msm, Kirill A. Shutemov,
	Douglas Anderson

On 7/31/26 04:56, Konrad Dybcio wrote:
> On 7/30/26 11:32 PM, Mayank Rungta via B4 Relay wrote:
>> From: Mayank Rungta <mrungta@google.com>
>>
>> When a system is completely unresponsive due to an interrupt storm or
>> deadlocked CPU cores with standard interrupts disabled, a standard watchdog
>> pretimeout bark interrupt will fail to execute, preventing the pretimeout
>> governor from capturing CPU backtraces before the hardware reset bite.
> 
> [...]
> 
>>   drivers/watchdog/qcom-wdt.c | 55 +++++++++++++++++++++++++++++++++++++++++----
>>   1 file changed, 51 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
>> index 49bd04841f0c..19d8e91cff40 100644
>> --- a/drivers/watchdog/qcom-wdt.c
>> +++ b/drivers/watchdog/qcom-wdt.c
>> @@ -51,6 +51,9 @@ struct qcom_wdt {
>>   	unsigned long		rate;
>>   	void __iomem		*base;
>>   	const u32		*layout;
>> +	int			irq;
>> +	bool			is_nmi;
>> +	bool			irq_enabled;
> 
> Do we need to track this? I think we can rely on the framework
> NOPing out multiple ops->start requests
> 
Good point. Agreed.

Guenter


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/3] genirq: Export NMI APIs
  2026-07-30 22:55     ` Guenter Roeck
@ 2026-07-31 23:18       ` Doug Anderson
  2026-08-07 16:00         ` Thomas Gleixner
  0 siblings, 1 reply; 14+ messages in thread
From: Doug Anderson @ 2026-07-31 23:18 UTC (permalink / raw)
  To: Guenter Roeck, Thomas Gleixner
  Cc: mrungta, Wim Van Sebroeck, linux-watchdog, linux-kernel,
	linux-arm-msm, Kirill A. Shutemov

Hi,

On Thu, Jul 30, 2026 at 3:55 PM Guenter Roeck <linux@roeck-us.net> wrote:
>
> On 7/30/26 14:49, Doug Anderson wrote:
> > Hi,
> >
> > On Thu, Jul 30, 2026 at 2:33 PM Mayank Rungta via B4 Relay
> > <devnull+mrungta.google.com@kernel.org> wrote:
> >>
> >> From: Mayank Rungta <mrungta@google.com>
> >>
> >> Currently, request_nmi(), free_nmi(), enable_nmi() and disable_nmi_nosync()
> >> are restricted to built-in kernel code because they are not exported to
> >> loadable modules.
> >>
> >> Export these APIs to allow loadable modules to register and manage NMIs.
> >> This allows watchdog drivers configured as loadable modules to register
> >> their bark interrupt as an NMI.
> >>
> >> Signed-off-by: Mayank Rungta <mrungta@google.com>
> >> ---
> >>   kernel/irq/manage.c | 4 ++++
> >>   1 file changed, 4 insertions(+)
> >>
> >> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
> >> index 2fbff2618a1e..fb0b8da32f4c 100644
> >> --- a/kernel/irq/manage.c
> >> +++ b/kernel/irq/manage.c
> >> @@ -766,6 +766,7 @@ void disable_nmi_nosync(unsigned int irq)
> >>   {
> >>          disable_irq_nosync(irq);
> >>   }
> >> +EXPORT_SYMBOL_GPL(disable_nmi_nosync);
> >>
> >>   void __enable_irq(struct irq_desc *desc)
> >>   {
> >> @@ -833,6 +834,7 @@ void enable_nmi(unsigned int irq)
> >>   {
> >>          enable_irq(irq);
> >>   }
> >> +EXPORT_SYMBOL_GPL(enable_nmi);
> >>
> >>   static int set_irq_wake_real(unsigned int irq, unsigned int on)
> >>   {
> >> @@ -2080,6 +2082,7 @@ const void *free_nmi(unsigned int irq, void *dev_id)
> >>
> >>          return __cleanup_nmi(irq, desc);
> >>   }
> >> +EXPORT_SYMBOL_GPL(free_nmi);
> >>
> >>   /**
> >>    * request_threaded_irq - allocate an interrupt line
> >> @@ -2342,6 +2345,7 @@ int request_nmi(unsigned int irq, irq_handler_t handler,
> >>
> >>          return retval;
> >>   }
> >> +EXPORT_SYMBOL_GPL(request_nmi);
> >
> > This seems reasonable to me. One thought I had was that we could
> > possibly get by with fewer exported symbols by changing
> > disable_nmi_nosync() and enable_nmi() to "static inline" functions in
> > the header file. That being said, what Mayank has here feels slightly
> > better to me.
> >
>
> I don't claim to understand the NMI APIs used, but Sashiko's feedback
> seems real to me. Someone who knows that code will need to confirm that
> there are no unexpected pitfalls.

Since Sashiko doesn't reply-to all, here's a link to its feedback:

https://lore.kernel.org/all/20260730214758.DBD5E1F000E9@smtp.kernel.org/

Indeed, it does look like legitimate feedback. While the problems are
pre-existing, it is true that exporting as a module could widen the
exposure because the code backing the NMI handler could now be
unloaded.

I did a little bit of AI analysis of the problem myself. As far as I
can tell, it would be relatively safe to implement a synchronous
"disable_nmi" by just calling "disable_irq", much like is done for
other NMI functions. The caveat here is that it would only be safe on
IRQ controllers that provided irq_get_irqchip_state(). This is because
on NMI we don't set IRQD_IRQ_INPROGRESS and thus
__synchronize_hardirq() will fall back to calling
__irq_get_irqchip_state(). If any controllers supported NMI but
_didn't_ support irq_get_irqchip_state(), we'd silently skip waiting
for NMI completion. Maybe we could simply make it illegal for a
controller to support NMI without irq_get_irqchip_state()?

I guess maybe we need Thomas Gleixner to weigh in on this? Thomas:
should this issue block Mayank's patch? Would you expect him to
propose fixes as part of his series, or is this something you'd prefer
to post patches for yourself?



-Doug

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/3] watchdog: qcom: Register pretimeout interrupt as NMI
  2026-07-31 14:12     ` Guenter Roeck
@ 2026-07-31 23:54       ` Mayank Rungta
  0 siblings, 0 replies; 14+ messages in thread
From: Mayank Rungta @ 2026-07-31 23:54 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Konrad Dybcio, Wim Van Sebroeck, Thomas Gleixner, linux-watchdog,
	linux-kernel, linux-arm-msm, Kirill A. Shutemov, Douglas Anderson

On Fri, Jul 31, 2026 at 7:12 AM Guenter Roeck <linux@roeck-us.net> wrote:
>
> On 7/31/26 04:56, Konrad Dybcio wrote:
> > On 7/30/26 11:32 PM, Mayank Rungta via B4 Relay wrote:
> >> From: Mayank Rungta <mrungta@google.com>
> >>
> >> When a system is completely unresponsive due to an interrupt storm or
> >> deadlocked CPU cores with standard interrupts disabled, a standard watchdog
> >> pretimeout bark interrupt will fail to execute, preventing the pretimeout
> >> governor from capturing CPU backtraces before the hardware reset bite.
> >
> > [...]
> >
> >>   drivers/watchdog/qcom-wdt.c | 55 +++++++++++++++++++++++++++++++++++++++++----
> >>   1 file changed, 51 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
> >> index 49bd04841f0c..19d8e91cff40 100644
> >> --- a/drivers/watchdog/qcom-wdt.c
> >> +++ b/drivers/watchdog/qcom-wdt.c
> >> @@ -51,6 +51,9 @@ struct qcom_wdt {
> >>      unsigned long           rate;
> >>      void __iomem            *base;
> >>      const u32               *layout;
> >> +    int                     irq;
> >> +    bool                    is_nmi;
> >> +    bool                    irq_enabled;
> >
> > Do we need to track this? I think we can rely on the framework
> > NOPing out multiple ops->start requests
> >
> Good point. Agreed.
>
> Guenter
>

Thanks for the review!

It seems you are correct. I initially added irq_enabled to guard
against duplicate starts during bootloader handoff when
qcom_wdt_is_running is true (since qcom_wdt_start() is then called
directly outside watchdog_dev). However, after inspecting
watchdog_dev.c, watchdog_start() routes bootloader handoff
(WDOG_HW_RUNNING) to .ping instead of calling ops->start() again.

I will remove `bool irq_enabled` from struct qcom_wdt in v2 since the
framework ensures enable_nmi() and disable_nmi_nosync() are always 1:1
balanced.

Thanks,
Mayank

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/3] watchdog: pretimeout: Protect governor access with RCU for NMI safety
  2026-07-30 21:46   ` Doug Anderson
@ 2026-08-07  5:34     ` Guenter Roeck
  0 siblings, 0 replies; 14+ messages in thread
From: Guenter Roeck @ 2026-08-07  5:34 UTC (permalink / raw)
  To: Doug Anderson, mrungta
  Cc: Wim Van Sebroeck, Thomas Gleixner, linux-watchdog, linux-kernel,
	linux-arm-msm, Kirill A. Shutemov

On 7/30/26 14:46, Doug Anderson wrote:
> Hi,
> 
> On Thu, Jul 30, 2026 at 2:33 PM Mayank Rungta via B4 Relay
> <devnull+mrungta.google.com@kernel.org> wrote:
>>
>> From: Mayank Rungta <mrungta@google.com>
>>
>> Currently, watchdog_notify_pretimeout() acquires pretimeout_lock using
>> spin_lock_irqsave() to safely dereference wdd->gov before invoking the
>> pretimeout callback.
>>
>> On architectures supporting pseudo-NMIs (ARM64 GICv3), watchdog drivers
>> may register their pretimeout warning interrupt (bark) as an NMI.
>> Because spin_lock_irqsave() disables regular interrupts but leaves NMIs
>> unmasked, if a pretimeout NMI fires while pretimeout_lock is already
>> held by normal process context, attempting to re-acquire pretimeout_lock
>> triggers an unrecoverable deadlock.
>>
>> To make pretimeout notifications completely safe to execute from NMI,
>> convert read access to wdd->gov inside watchdog_notify_pretimeout() from
>> a spinlock to lockless RCU. Use rcu_assign_pointer() when modifying
>> wdd->gov and invoke synchronize_rcu() during governor unregister and
>> pretimeout unregister routines.
>>
>> Signed-off-by: Mayank Rungta <mrungta@google.com>
>> ---
>>   drivers/watchdog/watchdog_pretimeout.c | 47 +++++++++++++++++++---------------
>>   include/linux/watchdog.h               |  2 +-
>>   2 files changed, 27 insertions(+), 22 deletions(-)
> 
> I pre-reviewed this for Mayank. I'm not an RCU expert, but this looks
> right based on my understanding. My AI was also happy with it. ;-)
> 

Sashiko doesn't like it, claiming that some "const" are missing. And, indeed,
after applying it, I get:

drivers/watchdog/watchdog_pretimeout.c: In function ‘watchdog_pretimeout_governor_get’:
drivers/watchdog/watchdog_pretimeout.c:75:13: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
    75 |         gov = rcu_dereference(wdd->gov);
       |             ^
drivers/watchdog/watchdog_pretimeout.c: In function ‘watchdog_notify_pretimeout’:
drivers/watchdog/watchdog_pretimeout.c:110:13: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
   110 |         gov = rcu_dereference(wdd->gov);
       |             ^

Please fix.

Thanks,
Guenter


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/3] genirq: Export NMI APIs
  2026-07-31 23:18       ` Doug Anderson
@ 2026-08-07 16:00         ` Thomas Gleixner
  0 siblings, 0 replies; 14+ messages in thread
From: Thomas Gleixner @ 2026-08-07 16:00 UTC (permalink / raw)
  To: Doug Anderson, Guenter Roeck
  Cc: mrungta, Wim Van Sebroeck, linux-watchdog, linux-kernel,
	linux-arm-msm, Kirill A. Shutemov

On Fri, Jul 31 2026 at 16:18, Doug Anderson wrote:
> On Thu, Jul 30, 2026 at 3:55 PM Guenter Roeck <linux@roeck-us.net> wrote:
>> > This seems reasonable to me. One thought I had was that we could
>> > possibly get by with fewer exported symbols by changing
>> > disable_nmi_nosync() and enable_nmi() to "static inline" functions in
>> > the header file. That being said, what Mayank has here feels slightly
>> > better to me.
>> >
>>
>> I don't claim to understand the NMI APIs used, but Sashiko's feedback
>> seems real to me. Someone who knows that code will need to confirm that
>> there are no unexpected pitfalls.
>
> Since Sashiko doesn't reply-to all, here's a link to its feedback:
>
> https://lore.kernel.org/all/20260730214758.DBD5E1F000E9@smtp.kernel.org/
>
> Indeed, it does look like legitimate feedback. While the problems are
> pre-existing, it is true that exporting as a module could widen the
> exposure because the code backing the NMI handler could now be
> unloaded.
>
> I did a little bit of AI analysis of the problem myself. As far as I
> can tell, it would be relatively safe to implement a synchronous
> "disable_nmi" by just calling "disable_irq", much like is done for
> other NMI functions. The caveat here is that it would only be safe on
> IRQ controllers that provided irq_get_irqchip_state(). This is because
> on NMI we don't set IRQD_IRQ_INPROGRESS and thus
> __synchronize_hardirq() will fall back to calling
> __irq_get_irqchip_state(). If any controllers supported NMI but
> _didn't_ support irq_get_irqchip_state(), we'd silently skip waiting
> for NMI completion. Maybe we could simply make it illegal for a
> controller to support NMI without irq_get_irqchip_state()?
>
> I guess maybe we need Thomas Gleixner to weigh in on this? Thomas:
> should this issue block Mayank's patch? Would you expect him to
> propose fixes as part of his series, or is this something you'd prefer
> to post patches for yourself?

Sorry, I did not pay attention as I was AFK and busy with bugs. I'll
have a look once the dust settles on my side (hopefully soonish).

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-08-07 16:00 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30 21:32 [PATCH 0/3] watchdog: qcom: Support NMI pretimeout warnings Mayank Rungta via B4 Relay
2026-07-30 21:32 ` [PATCH 1/3] watchdog: pretimeout: Protect governor access with RCU for NMI safety Mayank Rungta via B4 Relay
2026-07-30 21:46   ` Doug Anderson
2026-08-07  5:34     ` Guenter Roeck
2026-07-30 21:32 ` [PATCH 2/3] genirq: Export NMI APIs Mayank Rungta via B4 Relay
2026-07-30 21:49   ` Doug Anderson
2026-07-30 22:55     ` Guenter Roeck
2026-07-31 23:18       ` Doug Anderson
2026-08-07 16:00         ` Thomas Gleixner
2026-07-30 21:32 ` [PATCH 3/3] watchdog: qcom: Register pretimeout interrupt as NMI Mayank Rungta via B4 Relay
2026-07-30 21:52   ` Doug Anderson
2026-07-31 11:56   ` Konrad Dybcio
2026-07-31 14:12     ` Guenter Roeck
2026-07-31 23:54       ` Mayank Rungta

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox