* [PATCH] crypto: cesa: manage SRAM teardown with devm
@ 2026-07-17 23:17 Rosen Penev
2026-07-30 7:39 ` Herbert Xu
0 siblings, 1 reply; 2+ messages in thread
From: Rosen Penev @ 2026-07-17 23:17 UTC (permalink / raw)
To: linux-crypto
Cc: Srujana Challa, Bharat Bhushan, Herbert Xu, David S. Miller,
open list
mv_cesa_put_sram() is called explicitly from both the probe error path
and mv_cesa_remove(). The non-pool ioremap is already devm-managed, but
dma_map_resource() and gen_pool_dma_alloc() have no devm helpers, so the
mapping is released by hand. This is error-prone: the error path iterates
over every engine and can dma_unmap_resource() an uninitialized/zero
address for engines that were never set up.
Convert the teardown into a devm_add_action_or_reset() callback registered
only after a mapping is successfully established. The callback fires
automatically on probe failure (devres rollback) and on device detach,
after mv_cesa_remove() has already stopped the engine and freed the IRQ,
so the unmap still happens in a safe order. This deletes the explicit
mv_cesa_put_sram() calls and the uninitialized-engine bug at once.
Add a struct mv_cesa_dev back-pointer to struct mv_cesa_engine so the
callback can reach cesa->dev and cesa->sram_size from the engine alone.
Assisted-by: opencode:hy3-free
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/crypto/marvell/cesa/cesa.c | 55 ++++++++++++------------------
drivers/crypto/marvell/cesa/cesa.h | 2 ++
2 files changed, 24 insertions(+), 33 deletions(-)
diff --git a/drivers/crypto/marvell/cesa/cesa.c b/drivers/crypto/marvell/cesa/cesa.c
index 75d8ba23d9a2..4859ad2e86b4 100644
--- a/drivers/crypto/marvell/cesa/cesa.c
+++ b/drivers/crypto/marvell/cesa/cesa.c
@@ -366,6 +366,8 @@ static int mv_cesa_dev_dma_init(struct mv_cesa_dev *cesa)
return 0;
}
+static void mv_cesa_release_sram(void *data);
+
static int mv_cesa_get_sram(struct platform_device *pdev, int idx)
{
struct mv_cesa_dev *cesa = platform_get_drvdata(pdev);
@@ -378,11 +380,13 @@ static int mv_cesa_get_sram(struct platform_device *pdev, int idx)
engine->sram_pool = gen_pool_dma_alloc(engine->pool,
cesa->sram_size,
&engine->sram_dma);
- if (engine->sram_pool)
- return 0;
+ if (!engine->sram_pool) {
+ engine->pool = NULL;
+ return -ENOMEM;
+ }
- engine->pool = NULL;
- return -ENOMEM;
+ return devm_add_action_or_reset(cesa->dev, mv_cesa_release_sram,
+ engine);
}
engine->sram = devm_platform_get_and_ioremap_resource(pdev, idx, &res);
@@ -395,13 +399,13 @@ static int mv_cesa_get_sram(struct platform_device *pdev, int idx)
if (dma_mapping_error(cesa->dev, engine->sram_dma))
return -ENOMEM;
- return 0;
+ return devm_add_action_or_reset(cesa->dev, mv_cesa_release_sram, engine);
}
-static void mv_cesa_put_sram(struct platform_device *pdev, int idx)
+static void mv_cesa_release_sram(void *data)
{
- struct mv_cesa_dev *cesa = platform_get_drvdata(pdev);
- struct mv_cesa_engine *engine = &cesa->engines[idx];
+ struct mv_cesa_engine *engine = data;
+ struct mv_cesa_dev *cesa = engine->cesa;
if (engine->pool)
gen_pool_free(engine->pool, (unsigned long)engine->sram_pool,
@@ -465,17 +469,16 @@ static int mv_cesa_probe(struct platform_device *pdev)
char res_name[16];
engine->id = i;
+ engine->cesa = cesa;
spin_lock_init(&engine->lock);
ret = mv_cesa_get_sram(pdev, i);
if (ret)
- goto err_cleanup;
+ return ret;
irq = platform_get_irq(pdev, i);
- if (irq < 0) {
- ret = irq;
- goto err_cleanup;
- }
+ if (irq < 0)
+ return irq;
engine->irq = irq;
@@ -487,18 +490,14 @@ static int mv_cesa_probe(struct platform_device *pdev)
engine->clk = devm_clk_get_optional_enabled(dev, res_name);
if (IS_ERR(engine->clk)) {
engine->clk = devm_clk_get_optional_enabled(dev, NULL);
- if (IS_ERR(engine->clk)) {
- ret = PTR_ERR(engine->clk);
- goto err_cleanup;
- }
+ if (IS_ERR(engine->clk))
+ return PTR_ERR(engine->clk);
}
snprintf(res_name, sizeof(res_name), "cesaz%u", i);
engine->zclk = devm_clk_get_optional_enabled(dev, res_name);
- if (IS_ERR(engine->zclk)) {
- ret = PTR_ERR(engine->zclk);
- goto err_cleanup;
- }
+ if (IS_ERR(engine->zclk))
+ return PTR_ERR(engine->zclk);
engine->regs = cesa->regs + CESA_ENGINE_OFF(i);
@@ -516,7 +515,7 @@ static int mv_cesa_probe(struct platform_device *pdev)
dev_name(&pdev->dev),
engine);
if (ret)
- goto err_cleanup;
+ return ret;
/* Set affinity */
cpu = cpumask_local_spread(engine->id, NUMA_NO_NODE);
@@ -532,29 +531,19 @@ static int mv_cesa_probe(struct platform_device *pdev)
ret = mv_cesa_add_algs(cesa);
if (ret) {
cesa_dev = NULL;
- goto err_cleanup;
+ return ret;
}
dev_info(dev, "CESA device successfully registered\n");
return 0;
-
-err_cleanup:
- for (i = 0; i < caps->nengines; i++)
- mv_cesa_put_sram(pdev, i);
-
- return ret;
}
static void mv_cesa_remove(struct platform_device *pdev)
{
struct mv_cesa_dev *cesa = platform_get_drvdata(pdev);
- int i;
mv_cesa_remove_algs(cesa);
-
- for (i = 0; i < cesa->caps->nengines; i++)
- mv_cesa_put_sram(pdev, i);
}
static const struct platform_device_id mv_cesa_plat_id_table[] = {
diff --git a/drivers/crypto/marvell/cesa/cesa.h b/drivers/crypto/marvell/cesa/cesa.h
index 18f9f28040a6..44351b252861 100644
--- a/drivers/crypto/marvell/cesa/cesa.h
+++ b/drivers/crypto/marvell/cesa/cesa.h
@@ -415,6 +415,7 @@ struct mv_cesa_dev_dma {
* @zclk: engine zclk
* @max_req_len: maximum chunk length (useful to create the TDMA chain)
* @int_mask: interrupt mask cache
+ * @cesa: back-pointer to the parent CESA device
* @pool: memory pool pointing to the memory region reserved in
* SRAM
* @queue: fifo of the pending crypto requests
@@ -441,6 +442,7 @@ struct mv_cesa_engine {
struct clk *zclk;
size_t max_req_len;
u32 int_mask;
+ struct mv_cesa_dev *cesa;
struct gen_pool *pool;
struct crypto_queue queue;
atomic_t load;
--
2.55.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] crypto: cesa: manage SRAM teardown with devm
2026-07-17 23:17 [PATCH] crypto: cesa: manage SRAM teardown with devm Rosen Penev
@ 2026-07-30 7:39 ` Herbert Xu
0 siblings, 0 replies; 2+ messages in thread
From: Herbert Xu @ 2026-07-30 7:39 UTC (permalink / raw)
To: Rosen Penev
Cc: linux-crypto, Srujana Challa, Bharat Bhushan, David S. Miller,
open list
On Fri, Jul 17, 2026 at 04:17:42PM -0700, Rosen Penev wrote:
> mv_cesa_put_sram() is called explicitly from both the probe error path
> and mv_cesa_remove(). The non-pool ioremap is already devm-managed, but
> dma_map_resource() and gen_pool_dma_alloc() have no devm helpers, so the
> mapping is released by hand. This is error-prone: the error path iterates
> over every engine and can dma_unmap_resource() an uninitialized/zero
> address for engines that were never set up.
>
> Convert the teardown into a devm_add_action_or_reset() callback registered
> only after a mapping is successfully established. The callback fires
> automatically on probe failure (devres rollback) and on device detach,
> after mv_cesa_remove() has already stopped the engine and freed the IRQ,
> so the unmap still happens in a safe order. This deletes the explicit
> mv_cesa_put_sram() calls and the uninitialized-engine bug at once.
>
> Add a struct mv_cesa_dev back-pointer to struct mv_cesa_engine so the
> callback can reach cesa->dev and cesa->sram_size from the engine alone.
>
> Assisted-by: opencode:hy3-free
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
> drivers/crypto/marvell/cesa/cesa.c | 55 ++++++++++++------------------
> drivers/crypto/marvell/cesa/cesa.h | 2 ++
> 2 files changed, 24 insertions(+), 33 deletions(-)
Patch applied. Thanks.
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-30 7:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-17 23:17 [PATCH] crypto: cesa: manage SRAM teardown with devm Rosen Penev
2026-07-30 7:39 ` Herbert Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox