Linux cryptographic layer development
 help / color / mirror / Atom feed
From: Rosen Penev <rosenp@gmail.com>
To: linux-crypto@vger.kernel.org
Cc: Srujana Challa <schalla@marvell.com>,
	Bharat Bhushan <bbhushan2@marvell.com>,
	Herbert Xu <herbert@gondor.apana.org.au>,
	"David S. Miller" <davem@davemloft.net>,
	linux-kernel@vger.kernel.org (open list)
Subject: [PATCH] crypto: cesa: manage SRAM teardown with devm
Date: Fri, 17 Jul 2026 16:17:42 -0700	[thread overview]
Message-ID: <20260717231742.1174221-1-rosenp@gmail.com> (raw)

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


             reply	other threads:[~2026-07-17 23:17 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-17 23:17 Rosen Penev [this message]
2026-07-30  7:39 ` [PATCH] crypto: cesa: manage SRAM teardown with devm Herbert Xu

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=20260717231742.1174221-1-rosenp@gmail.com \
    --to=rosenp@gmail.com \
    --cc=bbhushan2@marvell.com \
    --cc=davem@davemloft.net \
    --cc=herbert@gondor.apana.org.au \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=schalla@marvell.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox