All of lore.kernel.org
 help / color / mirror / Atom feed
From: Harini T <harini.t@amd.com>
To: <linux@roeck-us.net>, <michal.simek@amd.com>,
	<srinivas.neeli@amd.com>, <shubhrajyoti.datta@amd.com>
Cc: <srinivas.goud@amd.com>, <wim@linux-watchdog.org>,
	<linux-watchdog@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>, <git@amd.com>,
	Harini T <harini.t@amd.com>
Subject: [PATCH] watchdog: xilinx_wwdt: Add check for timeout limit and set maximum value if exceeded
Date: Tue, 19 Mar 2024 16:42:19 +0530	[thread overview]
Message-ID: <20240319111219.21094-1-harini.t@amd.com> (raw)

Current implementation fails to verify if the user input such as timeout
or closed window percentage exceeds the maximum value that the hardware
supports.

Maximum timeout is derived based on input clock frequency.
If the user input timeout exceeds the maximum timeout supported, limit
the timeout to maximum supported value.
Limit the close and open window percent to hardware supported value.

Signed-off-by: Harini T <harini.t@amd.com>
---
 drivers/watchdog/xilinx_wwdt.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/xilinx_wwdt.c b/drivers/watchdog/xilinx_wwdt.c
index d271e2e8d6e2..86e2edc4f3c7 100644
--- a/drivers/watchdog/xilinx_wwdt.c
+++ b/drivers/watchdog/xilinx_wwdt.c
@@ -36,6 +36,12 @@
 
 #define XWWDT_CLOSE_WINDOW_PERCENT	50
 
+/* Maximum count value of each 32 bit window */
+#define XWWDT_MAX_COUNT_WINDOW		GENMASK(31, 0)
+
+/* Maximum count value of closed and open window combined*/
+#define XWWDT_MAX_COUNT_WINDOW_COMBINED GENMASK_ULL(32, 1)
+
 static int wwdt_timeout;
 static int closed_window_percent;
 
@@ -73,6 +79,24 @@ static int xilinx_wwdt_start(struct watchdog_device *wdd)
 	/* Calculate timeout count */
 	time_out = xdev->freq * wdd->timeout;
 	closed_timeout = div_u64(time_out * xdev->close_percent, 100);
+
+	if (time_out > XWWDT_MAX_COUNT_WINDOW) {
+		u64 min_close_timeout = time_out - XWWDT_MAX_COUNT_WINDOW;
+		u64 max_close_timeout = XWWDT_MAX_COUNT_WINDOW;
+
+		if (closed_timeout > max_close_timeout) {
+			dev_info(xilinx_wwdt_wdd->parent,
+				 "Closed window cannot be set to %d%%. Using maximum supported value.\n",
+				 xdev->close_percent);
+			closed_timeout = max_close_timeout;
+		} else if (closed_timeout < min_close_timeout) {
+			dev_info(xilinx_wwdt_wdd->parent,
+				 "Closed window cannot be set to %d%%. Using minimum supported value.\n",
+				 xdev->close_percent);
+			closed_timeout = min_close_timeout;
+		}
+	}
+
 	open_timeout = time_out - closed_timeout;
 	wdd->min_hw_heartbeat_ms = xdev->close_percent * 10 * wdd->timeout;
 
@@ -132,6 +156,7 @@ static int xwwdt_probe(struct platform_device *pdev)
 {
 	struct watchdog_device *xilinx_wwdt_wdd;
 	struct device *dev = &pdev->dev;
+	unsigned int max_hw_heartbeat;
 	struct xwwdt_device *xdev;
 	struct clk *clk;
 	int ret;
@@ -157,9 +182,11 @@ static int xwwdt_probe(struct platform_device *pdev)
 	if (!xdev->freq)
 		return -EINVAL;
 
+	max_hw_heartbeat = div64_u64(XWWDT_MAX_COUNT_WINDOW_COMBINED, xdev->freq);
+
 	xilinx_wwdt_wdd->min_timeout = XWWDT_MIN_TIMEOUT;
 	xilinx_wwdt_wdd->timeout = XWWDT_DEFAULT_TIMEOUT;
-	xilinx_wwdt_wdd->max_hw_heartbeat_ms = 1000 * xilinx_wwdt_wdd->timeout;
+	xilinx_wwdt_wdd->max_hw_heartbeat_ms = 1000 * max_hw_heartbeat;
 
 	if (closed_window_percent == 0 || closed_window_percent >= 100)
 		xdev->close_percent = XWWDT_CLOSE_WINDOW_PERCENT;
@@ -167,6 +194,7 @@ static int xwwdt_probe(struct platform_device *pdev)
 		xdev->close_percent = closed_window_percent;
 
 	watchdog_init_timeout(xilinx_wwdt_wdd, wwdt_timeout, &pdev->dev);
+	xilinx_wwdt_wdd->timeout = min_not_zero(xilinx_wwdt_wdd->timeout, max_hw_heartbeat);
 	spin_lock_init(&xdev->spinlock);
 	watchdog_set_drvdata(xilinx_wwdt_wdd, xdev);
 	watchdog_set_nowayout(xilinx_wwdt_wdd, 1);
-- 
2.17.1


WARNING: multiple messages have this Message-ID (diff)
From: Harini T <harini.t@amd.com>
To: <linux@roeck-us.net>, <michal.simek@amd.com>,
	<srinivas.neeli@amd.com>, <shubhrajyoti.datta@amd.com>
Cc: <srinivas.goud@amd.com>, <wim@linux-watchdog.org>,
	<linux-watchdog@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>, <git@amd.com>,
	Harini T <harini.t@amd.com>
Subject: [PATCH] watchdog: xilinx_wwdt: Add check for timeout limit and set maximum value if exceeded
Date: Tue, 19 Mar 2024 16:42:19 +0530	[thread overview]
Message-ID: <20240319111219.21094-1-harini.t@amd.com> (raw)

Current implementation fails to verify if the user input such as timeout
or closed window percentage exceeds the maximum value that the hardware
supports.

Maximum timeout is derived based on input clock frequency.
If the user input timeout exceeds the maximum timeout supported, limit
the timeout to maximum supported value.
Limit the close and open window percent to hardware supported value.

Signed-off-by: Harini T <harini.t@amd.com>
---
 drivers/watchdog/xilinx_wwdt.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/xilinx_wwdt.c b/drivers/watchdog/xilinx_wwdt.c
index d271e2e8d6e2..86e2edc4f3c7 100644
--- a/drivers/watchdog/xilinx_wwdt.c
+++ b/drivers/watchdog/xilinx_wwdt.c
@@ -36,6 +36,12 @@
 
 #define XWWDT_CLOSE_WINDOW_PERCENT	50
 
+/* Maximum count value of each 32 bit window */
+#define XWWDT_MAX_COUNT_WINDOW		GENMASK(31, 0)
+
+/* Maximum count value of closed and open window combined*/
+#define XWWDT_MAX_COUNT_WINDOW_COMBINED GENMASK_ULL(32, 1)
+
 static int wwdt_timeout;
 static int closed_window_percent;
 
@@ -73,6 +79,24 @@ static int xilinx_wwdt_start(struct watchdog_device *wdd)
 	/* Calculate timeout count */
 	time_out = xdev->freq * wdd->timeout;
 	closed_timeout = div_u64(time_out * xdev->close_percent, 100);
+
+	if (time_out > XWWDT_MAX_COUNT_WINDOW) {
+		u64 min_close_timeout = time_out - XWWDT_MAX_COUNT_WINDOW;
+		u64 max_close_timeout = XWWDT_MAX_COUNT_WINDOW;
+
+		if (closed_timeout > max_close_timeout) {
+			dev_info(xilinx_wwdt_wdd->parent,
+				 "Closed window cannot be set to %d%%. Using maximum supported value.\n",
+				 xdev->close_percent);
+			closed_timeout = max_close_timeout;
+		} else if (closed_timeout < min_close_timeout) {
+			dev_info(xilinx_wwdt_wdd->parent,
+				 "Closed window cannot be set to %d%%. Using minimum supported value.\n",
+				 xdev->close_percent);
+			closed_timeout = min_close_timeout;
+		}
+	}
+
 	open_timeout = time_out - closed_timeout;
 	wdd->min_hw_heartbeat_ms = xdev->close_percent * 10 * wdd->timeout;
 
@@ -132,6 +156,7 @@ static int xwwdt_probe(struct platform_device *pdev)
 {
 	struct watchdog_device *xilinx_wwdt_wdd;
 	struct device *dev = &pdev->dev;
+	unsigned int max_hw_heartbeat;
 	struct xwwdt_device *xdev;
 	struct clk *clk;
 	int ret;
@@ -157,9 +182,11 @@ static int xwwdt_probe(struct platform_device *pdev)
 	if (!xdev->freq)
 		return -EINVAL;
 
+	max_hw_heartbeat = div64_u64(XWWDT_MAX_COUNT_WINDOW_COMBINED, xdev->freq);
+
 	xilinx_wwdt_wdd->min_timeout = XWWDT_MIN_TIMEOUT;
 	xilinx_wwdt_wdd->timeout = XWWDT_DEFAULT_TIMEOUT;
-	xilinx_wwdt_wdd->max_hw_heartbeat_ms = 1000 * xilinx_wwdt_wdd->timeout;
+	xilinx_wwdt_wdd->max_hw_heartbeat_ms = 1000 * max_hw_heartbeat;
 
 	if (closed_window_percent == 0 || closed_window_percent >= 100)
 		xdev->close_percent = XWWDT_CLOSE_WINDOW_PERCENT;
@@ -167,6 +194,7 @@ static int xwwdt_probe(struct platform_device *pdev)
 		xdev->close_percent = closed_window_percent;
 
 	watchdog_init_timeout(xilinx_wwdt_wdd, wwdt_timeout, &pdev->dev);
+	xilinx_wwdt_wdd->timeout = min_not_zero(xilinx_wwdt_wdd->timeout, max_hw_heartbeat);
 	spin_lock_init(&xdev->spinlock);
 	watchdog_set_drvdata(xilinx_wwdt_wdd, xdev);
 	watchdog_set_nowayout(xilinx_wwdt_wdd, 1);
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

             reply	other threads:[~2024-03-19 11:12 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-19 11:12 Harini T [this message]
2024-03-19 11:12 ` [PATCH] watchdog: xilinx_wwdt: Add check for timeout limit and set maximum value if exceeded Harini T
2024-03-19 14:07 ` Guenter Roeck
2024-03-19 14:07   ` Guenter Roeck
2024-05-08 15:17   ` T, Harini
2024-05-08 15:17     ` T, Harini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240319111219.21094-1-harini.t@amd.com \
    --to=harini.t@amd.com \
    --cc=git@amd.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-watchdog@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=michal.simek@amd.com \
    --cc=shubhrajyoti.datta@amd.com \
    --cc=srinivas.goud@amd.com \
    --cc=srinivas.neeli@amd.com \
    --cc=wim@linux-watchdog.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.