[PATCH v3 0/5] watchdog: qcom: Support NMI pretimeout warnings

Mayank Rungta posted 5 patches 3 weeks, 2 days ago
drivers/watchdog/qcom-wdt.c            | 33 +++++++++++++++++++---
drivers/watchdog/watchdog_pretimeout.c | 45 +++++++++++++++++-------------
include/linux/interrupt.h              |  1 +
include/linux/watchdog.h               |  2 +-
kernel/irq/manage.c                    | 51 ++++++++++++++++++++++++++++++----
5 files changed, 101 insertions(+), 31 deletions(-)
[PATCH v3 0/5] watchdog: qcom: Support NMI pretimeout warnings
Posted by Mayank Rungta 3 weeks, 2 days ago
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 a loadable driver module requires
addressing NMI teardown synchronization, exporting NMI registration
APIs, and ensuring watchdog pretimeout governor dispatch is NMI-safe.

This 5-patch series achieves NMI pretimeout enablement for qcom-wdt:
 1) Enforces that interrupt controllers claiming NMI support must
    implement ->irq_get_irqchip_state(), and synchronizes in-flight NMI
    handlers during teardown (__cleanup_nmi) to prevent use-after-free
    bugs during module unload or driver unbind.
 2) Implements synchronous disable_nmi() to ensure in-flight handlers on
    other CPUs complete before returning.
 3) Exports request_nmi(), free_nmi(), enable_nmi(), disable_nmi(), and
    disable_nmi_nosync() to GPL loadable kernel modules.
 4) Replaces spinlocks in watchdog_notify_pretimeout() with RCU to
    guarantee safe governor execution from NMI context.
 5) Updates qcom-wdt to request its pretimeout bark interrupt as an
    NMI (or pseudo-NMI) with fallback to standard IRQ.

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 and 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 cleanly falls back to standard IRQ.

Signed-off-by: Mayank Rungta <mrungta@google.com>
---
Changes in v3:
- In __cleanup_nmi() (Patch 1), serialized teardown under desc->request_mutex
  matching __free_irq(), preventing concurrent request_nmi() from racing with
  teardown.
- In __cleanup_nmi() (Patch 1), kept desc->action intact across
  __synchronize_hardirq() to prevent lockless NMI handlers on other CPUs
  from encountering a NULL pointer.
- In __cleanup_nmi() (Patch 1), moved irq_proc_update_valid() under
  desc->lock in the second phase so it observes desc->action == NULL.
- In qcom-wdt (Patch 5), enabled the NMI once during probe (enable_nmi())
  to balance IRQF_NO_AUTOEN and removed interrupt enable/disable calls
  from qcom_wdt_start() / qcom_wdt_stop(), avoiding unbalanced enable
  warnings on WDIOC_SETTIMEOUT / WDIOC_SETPRETIMEOUT (Douglas Anderson).
- In qcom-wdt (Patch 5), simplified teardown to unconditionally call
  disable_nmi() and free_nmi(), dropping is_nmi tracking and watchdog_active()
  checks.
- Link to v2: https://lore.kernel.org/r/20260828-qcom-wdt-nmi-series-v2-0-363979fe6b6b@google.com

Changes in v2:
- Added patch to require ->irq_get_irqchip_state() for NMI-capable
  controllers in irq_supports_nmi(), and synchronize in-flight NMI
  handlers via __synchronize_hardirq() in __cleanup_nmi() to prevent
  use-after-free races during teardown.
- Added patch implementing synchronous disable_nmi() wrapping
  disable_irq().
- Exported disable_nmi() alongside other NMI APIs in genirq export patch.
- Re-ordered series to cluster genirq core changes (patches 1-3) followed
  by watchdog core and driver changes (patches 4-5).
- Fixed compiler warnings in watchdog pretimeout RCU patch by adding const
  qualifiers to local governor pointers.
- Dropped `irq_enabled` tracking from struct qcom_wdt in patch 5 since
  watchdog_dev.c strictly pairs ops->start and ops->stop calls.
- Used disable_nmi() in qcom_wdt_disable_irq() for synchronous stop.
- Link to v1: https://lore.kernel.org/r/20260730-qcom-wdt-nmi-series-v1-0-3aa86d162914@google.com

---
Mayank Rungta (5):
      genirq: Synchronize in-flight handlers during NMI teardown
      genirq: Implement synchronous disable_nmi()
      genirq: Export NMI APIs
      watchdog: pretimeout: Protect governor access with RCU for NMI safety
      watchdog: qcom: Register pretimeout interrupt as NMI

 drivers/watchdog/qcom-wdt.c            | 33 +++++++++++++++++++---
 drivers/watchdog/watchdog_pretimeout.c | 45 +++++++++++++++++-------------
 include/linux/interrupt.h              |  1 +
 include/linux/watchdog.h               |  2 +-
 kernel/irq/manage.c                    | 51 ++++++++++++++++++++++++++++++----
 5 files changed, 101 insertions(+), 31 deletions(-)
---
base-commit: 77ae27fd98f3b548797c9f22c10ab5cf1c4ada53
change-id: 20260724-qcom-wdt-nmi-series-06a48da7b415

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