Re: [PATCH v3] watchdog: sbsa_gwdt: add early_enable module parameter
Guenter Roeck <[email protected]>
| Newsgroups | org.kernel.vger.linux-watchdog,org.infradead.lists.linux-arm-kernel,org.infradead.lists.linux-mediatek,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Thu, Aug 13, 2026 at 12:12:18PM +0800, Zexin Wang wrote: > On SBSA platforms using standard UEFI firmware (such as EDK II), the > watchdog timer is often enabled during early boot stages but explicitly > disabled by the firmware before handing over control to the OS (e.g., > during ExitBootServices). This is done to prevent unintended resets > while the OS is loading, assuming the OS watchdog driver will take over. > > However, this leaves a protection gap. If the system hangs between the > firmware handover and the userspace watchdog daemon startup, the hardware > watchdog will not fire to recover the system. For safety-critical systems > that require continuous hardware watchdog protection from the earliest > possible moment, this gap is problematic. > > Add an 'early_enable' module parameter to allow the kernel driver to > re-enable the watchdog immediately during probe if it was left disabled > by the firmware. By setting the WDOG_HW_RUNNING status bit, the watchdog > core is instructed that the hardware is active. As a result, the core's > pre-userspace handler (controlled by 'handle_boot_enabled') will > automatically issue periodic keepalives until userspace opens the device. > > This bridges the protection gap seamlessly without requiring firmware > modifications and without risking unintended resets during kernel boot. > > The parameter defaults to false to preserve the traditional behavior. > > Signed-off-by: Zexin Wang <[email protected]> You might want to wait a few minutes before sending new versions of a patch. > --- > Changes in v3: > - Fix indentation of `early_enable` in watchdog-parameters.rst to ensure > it renders as a separate parameter rather than part of `nowayout`'s > description. > > Changes in v2: > - Rename `force_enable` to `early_enable` as suggested by Guenter. > - Update commit message to explain the UEFI handover gap motivation. > - Add documentation for the new parameter. > > .../watchdog/watchdog-parameters.rst | 2 ++ > drivers/watchdog/sbsa_gwdt.c | 23 +++++++++++++++++-- > 2 files changed, 23 insertions(+), 2 deletions(-) > > diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst > index 502cb6adbeda..348229ffcb43 100644 > --- a/Documentation/watchdog/watchdog-parameters.rst > +++ b/Documentation/watchdog/watchdog-parameters.rst > @@ -515,6 +515,8 @@ sbsa_gwdt: > nowayout: > Watchdog cannot be stopped once started > (default=kernel config parameter) > + early_enable: > + Watchdog is started on module insertion (default=0) > > ------------------------------------------------- > > diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c > index e04d42cc7774..ed913be3d1cb 100644 > --- a/drivers/watchdog/sbsa_gwdt.c > +++ b/drivers/watchdog/sbsa_gwdt.c > @@ -122,6 +122,11 @@ MODULE_PARM_DESC(nowayout, > "Watchdog cannot be stopped once started (default=" > __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); > > +static bool early_enable; > +module_param(early_enable, bool, 0); > +MODULE_PARM_DESC(early_enable, > + "Watchdog is started on module insertion (default=0)"); > + > /* > * Arm Base System Architecture 1.0 introduces watchdog v1 which > * increases the length watchdog offset register to 48 bits. > @@ -296,6 +301,7 @@ static int sbsa_gwdt_probe(struct platform_device *pdev) > struct sbsa_gwdt *gwdt; > int ret, irq; > u32 status; > + bool early_action; > > gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL); > if (!gwdt) > @@ -386,14 +392,27 @@ static int sbsa_gwdt_probe(struct platform_device *pdev) > */ > sbsa_gwdt_set_timeout(wdd, wdd->timeout); > > + early_action = early_enable && !(status & SBSA_GWDT_WCS_EN); > + if (early_action) { > + sbsa_gwdt_start(wdd); > + set_bit(WDOG_HW_RUNNING, &wdd->status); > + dev_info(dev, "Watchdog early enabled.\n"); Still unnecessary noise. > + } > + > watchdog_stop_on_reboot(wdd); > ret = devm_watchdog_register_device(dev, wdd); > - if (ret) > + if (ret) { > + dev_err(dev, "Failed to register watchdog: %d\n", ret); Still unrelated. > + if (early_action) { > + clear_bit(WDOG_HW_RUNNING, &wdd->status); Still pointless / unnecessary. > + sbsa_gwdt_stop(wdd); > + } > return ret; > + } > > dev_info(dev, "Initialized with %ds timeout @ %u Hz, action=%d.%s\n", > wdd->timeout, gwdt->clk, action, > - status & SBSA_GWDT_WCS_EN ? " [enabled]" : ""); > + watchdog_hw_running(wdd) ? " [enabled]" : ""); > > return 0; > }