[PATCH 3/4] hwrng: starfive - Fix runtime PM leak in starfive_trng_read()
From: Wentao Liang
Date: Tue Sep 15 2026 - 00:00:22 EST
starfive_trng_read() takes a runtime PM reference with
pm_runtime_get_sync(trng->dev), which leaves the device's usage
count incremented even when it fails, and balances it with
pm_runtime_put_sync_autosuspend() on the success path only. If
starfive_trng_wait_idle() times out or starfive_trng_cmd() fails,
the function returns early without dropping the reference, leaking
it on every failed read.
Convert the pm_runtime_get_sync() call to
pm_runtime_resume_and_get(), which drops the reference again on
failure, and release the reference with
pm_runtime_put_sync_autosuspend() before the two early returns.
Fixes: c388f458bc34 ("hwrng: starfive - Add TRNG driver for StarFive SoC")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/char/hw_random/jh7110-trng.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/char/hw_random/jh7110-trng.c b/drivers/char/hw_random/jh7110-trng.c
index 9776f4daa044..01024145afb5 100644
--- a/drivers/char/hw_random/jh7110-trng.c
+++ b/drivers/char/hw_random/jh7110-trng.c
@@ -247,7 +247,9 @@ static int starfive_trng_read(struct hwrng *rng, void *buf, size_t max, bool wai
struct starfive_trng *trng = to_trng(rng);
int ret;
- pm_runtime_get_sync(trng->dev);
+ ret = pm_runtime_resume_and_get(trng->dev);
+ if (ret)
+ return ret;
if (trng->mode == PRNG_256BIT)
max = min_t(size_t, max, (STARFIVE_RAND_LEN * 8));
@@ -256,13 +258,17 @@ static int starfive_trng_read(struct hwrng *rng, void *buf, size_t max, bool wai
if (wait) {
ret = starfive_trng_wait_idle(trng);
- if (ret)
+ if (ret) {
+ pm_runtime_put_sync_autosuspend(trng->dev);
return -ETIMEDOUT;
+ }
}
ret = starfive_trng_cmd(trng, STARFIVE_CTRL_GENE_RANDNUM, wait);
- if (ret)
+ if (ret) {
+ pm_runtime_put_sync_autosuspend(trng->dev);
return ret;
+ }
memcpy_fromio(buf, trng->base + STARFIVE_RAND0, max);
--
2.34.1