[PATCH v1] watchdog: qcom: Add max timeout check to prevent overflow

Gopinath Sekar gopinath.sekar at oss.qualcomm.com
Tue Jun 24 08:19:07 CEST 2025


Added a check to ensure the requested timeout does not exceed the
hardware's maximum supported value. This prevents register overflow
and ensures watchdog reliability.

So, added a check in qcom_wdt_start() to ensure the requested timeout
does not exceed the hardware-supported maximum value.

The timeout is first converted to watchdog ticks and then compared
against QCOM_WDT_MAX_TIMEOUT. This helps prevent misconfiguration
and potential watchdog misbehavior due to overflow.

QCOM_WDT_MAX_TIMEOUT is set to 0xFFFFF, as Qualcomm SoCs typically
use 20 bits to store bark/bite timeout values.

This work builds upon the previous submission:
https://lore.kernel.org/u-boot/20250527124926.128413-1-balaji.selvanathan@oss.qualcomm.com/

Signed-off-by: Gopinath Sekar <gopinath.sekar at oss.qualcomm.com>
---
 drivers/watchdog/qcom-wdt.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index adbb5aacdc3..eeeea4c24b7 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -17,6 +17,9 @@
 
 #include <asm/io.h>
 
+/* Maximum allowed timeout value in Qcom SoCs*/
+#define QCOM_WDT_MAX_TIMEOUT	0xfffff
+
 enum wdt_reg {
 	WDT_RST,
 	WDT_EN,
@@ -55,8 +58,20 @@ static void __iomem *wdt_addr(struct qcom_wdt *wdt, enum wdt_reg reg)
 int qcom_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
 {
 	struct qcom_wdt *wdt = dev_get_priv(dev);
-	ulong bark_timeout_s = ((timeout_ms - 1)  * wdt->clk_rate) / 1000;
-	ulong bite_timeout_s = (timeout_ms * wdt->clk_rate) / 1000;
+	u64 tmp_timeout;
+	u32 bark_timeout_s, bite_timeout_s;
+
+	/* Compute timeout in watchdog ticks */
+	tmp_timeout = (timeout_ms * (u64)wdt->clk_rate) / 1000;
+	if (tmp_timeout > QCOM_WDT_MAX_TIMEOUT) {
+		dev_err(dev, "Requested timeout (%llu ms) exceeds maximum allowed value (%llu ms).\n",
+			timeout_ms, ((u64)QCOM_WDT_MAX_TIMEOUT * 1000) / wdt->clk_rate);
+		return -EINVAL;
+	}
+	bite_timeout_s = (u32)tmp_timeout;
+
+	tmp_timeout = ((timeout_ms - 1) * (u64)wdt->clk_rate) / 1000;
+	bark_timeout_s = (u32)tmp_timeout;
 
 	writel(0, wdt_addr(wdt, WDT_EN));
 	writel(BIT(0), wdt_addr(wdt, WDT_RST));
-- 
2.34.1



More information about the U-Boot mailing list