From 51443c9a499989f698a2921e72156713fe1a6bc2 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 27 Sep 2022 09:45:44 +0200 Subject: watchdog: gpio_wdt: use __udelay() to avoid recursion The udelay() function in lib/time.c contains a WATCHDOG_RESET() call. The only reason this doesn't lead to a catastrophic infinite recursion is due to the rate-limiting in wdt-uclass.c: if (time_after_eq(now, priv->next_reset)) { priv->next_reset = now + priv->reset_period; wdt_reset(dev); } But this would fall apart if ->next_reset was updated after calling the device's reset method. This is needlessly fragile, and it's easy enough to avoid that recursion in the first place by just using __udelay() directly. Signed-off-by: Rasmus Villemoes Reviewed-by: Stefan Roese --- drivers/watchdog/gpio_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c index fe06ec8..2920c2c 100644 --- a/drivers/watchdog/gpio_wdt.c +++ b/drivers/watchdog/gpio_wdt.c @@ -31,7 +31,7 @@ static int gpio_wdt_reset(struct udevice *dev) case HW_ALGO_LEVEL: /* Pulse */ dm_gpio_set_value(&priv->gpio, 1); - udelay(1); + __udelay(1); dm_gpio_set_value(&priv->gpio, 0); break; } -- cgit v1.1 From c5f5ee373267d8a73b44ffa0de0d0a1a08115d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 27 Sep 2022 12:19:19 +0200 Subject: watchdog: max6370: use __udelay() to avoid recursion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The udelay() function in lib/time.c contains a WATCHDOG_RESET() call. So use __udelay() in max6370_wdt.c to prevent recursion. Fixes: 0a095fc53b15 ("watchdog: Add MAX6370 watchdog timer driver") Signed-off-by: Pali Rohár Reviewed-by: Stefan Roese --- drivers/watchdog/max6370_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/max6370_wdt.c b/drivers/watchdog/max6370_wdt.c index e59cbb2..584a4ed 100644 --- a/drivers/watchdog/max6370_wdt.c +++ b/drivers/watchdog/max6370_wdt.c @@ -72,7 +72,7 @@ static int max6370_wdt_reset(struct udevice *dev) if (dm_gpio_is_valid(&wdt->gpio_wdi)) { dm_gpio_set_value(&wdt->gpio_wdi, 1); - udelay(1); + __udelay(1); dm_gpio_set_value(&wdt->gpio_wdi, 0); } else { val = readb(wdt->reg); -- cgit v1.1 From c11cedc876631c1753427a68db4efaa00f700a79 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 27 Sep 2022 11:54:02 +0200 Subject: autoboot: make sure watchdog device(s) are handled with keyed autoboot Currently, AUTOBOOT_KEYED and its variant AUTOBOOT_ENCRYPTION are broken when one has an external always-running watchdog device with a timeout shorter than the configured boot delay (in my case, I have a gpio-wdt one with a timeout of 1 second), because we fail to call WATCHDOG_RESET() in the loops where we wait for the bootdelay to elapse. This is done implicitly in the !AUTOBOOT_KEYED case, i.e. abortboot_single_key(), because that loop contains a udelay(10000), and udelay() does a WATCHDOG_RESET(). To fix this, simply add similar udelay() calls in the other loops. Signed-off-by: Rasmus Villemoes Reviewed-by: Stefan Roese --- common/autoboot.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/autoboot.c b/common/autoboot.c index 63f2587..cdafe76 100644 --- a/common/autoboot.c +++ b/common/autoboot.c @@ -115,6 +115,7 @@ static int passwd_abort_crypt(uint64_t etime) presskey_len++; } } + udelay(10000); } while (never_timeout || get_ticks() <= etime); return abort; @@ -206,6 +207,7 @@ static int passwd_abort_sha256(uint64_t etime) if (slow_equals(sha, sha_env, SHA256_SUM_LEN)) abort = 1; } + udelay(10000); } while (!abort && get_ticks() <= etime); free(presskey); @@ -293,6 +295,7 @@ static int passwd_abort_key(uint64_t etime) abort = 1; } } + udelay(10000); } while (!abort && get_ticks() <= etime); return abort; -- cgit v1.1