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: [PATCHv2] crypto: cesa: complete pending requests on device remove
Date: Thu, 24 Sep 2026 16:59:37 -0700 [thread overview]
Message-ID: <20260924235937.148475-1-rosenp@gmail.com> (raw)
mv_cesa_remove() unregisters the algorithms but never drains the engine
queues. Each engine can still hold outstanding requests in three
places: engine->req (currently in flight), engine->queue (queued but
not started), and engine->complete_queue (processed but not yet
reported). After unregistration those waiters never receive their
completion callback and block indefinitely, leaking the request and its
scatterlist buffers.
In mv_cesa_remove() stop each engine (mask interrupts, clear the CMD and
TDMA control registers, then wait for the engine to report idle), quiesce
the threaded IRQ with disable_irq()/synchronize_irq(), and drain the
three queues, completing every outstanding request with -ENOENT. The
completion callbacks unmap DMA buffers through the global cesa_dev
pointer, so keep it valid until the engines are drained, and mark the
engines aborted under their lock so a racing submitter cannot restart a
halted engine.
Assisted-by: LLM
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
v2: fix a bunch of sashiko errors
drivers/crypto/marvell/cesa/cesa.c | 80 ++++++++++++++++++++++++++++++
drivers/crypto/marvell/cesa/cesa.h | 4 ++
2 files changed, 84 insertions(+)
diff --git a/drivers/crypto/marvell/cesa/cesa.c b/drivers/crypto/marvell/cesa/cesa.c
index 564b09773507..d91e1af0fe9c 100644
--- a/drivers/crypto/marvell/cesa/cesa.c
+++ b/drivers/crypto/marvell/cesa/cesa.c
@@ -52,6 +52,14 @@ static void mv_cesa_rearm_engine(struct mv_cesa_engine *engine)
spin_lock_bh(&engine->lock);
if (!engine->req) {
+ if (engine->aborted) {
+ /*
+ * The device is being removed: do not restart the
+ * engine nor fetch any new request.
+ */
+ spin_unlock_bh(&engine->lock);
+ return;
+ }
req = mv_cesa_dequeue_req_locked(engine, &backlog);
engine->req = req;
}
@@ -542,9 +550,81 @@ static int mv_cesa_probe(struct platform_device *pdev)
static void mv_cesa_remove(struct platform_device *pdev)
{
struct mv_cesa_dev *cesa = platform_get_drvdata(pdev);
+ struct mv_cesa_engine *engine;
+ struct crypto_async_request *req;
+ unsigned int i;
+ unsigned int timeout;
mv_cesa_remove_algs(cesa);
+ for (i = 0; i < cesa->caps->nengines; i++) {
+ engine = &cesa->engines[i];
+
+ /*
+ * Stop the engine so it no longer issues DMA to the SRAM
+ * region or to request scatterlists that are about to be
+ * unmapped.
+ */
+ writel(0, engine->regs + CESA_SA_INT_MSK);
+ writel(0, engine->regs + CESA_SA_CMD);
+ writel(0, engine->regs + CESA_TDMA_CONTROL);
+
+ /*
+ * Flush the posted writes above and wait for the engine to
+ * report that it is stopped before any buffer is released.
+ */
+ timeout = CESA_ENGINE_STOP_TIMEOUT_US;
+ while ((readl(engine->regs + CESA_SA_CMD) &
+ CESA_SA_CMD_EN_CESA_SA_ACCL0) && --timeout)
+ udelay(1);
+
+ /*
+ * Synchronize with the threaded IRQ handler so that it cannot
+ * run while the queues below are drained.
+ */
+ disable_irq(engine->irq);
+ synchronize_irq(engine->irq);
+
+ spin_lock_bh(&engine->lock);
+ engine->aborted = true;
+
+ /*
+ * Complete the request currently in flight and drain the
+ * pending and already-processed queues with an error so that
+ * waiters do not block indefinitely when the device is unbound
+ * while requests are still outstanding.
+ */
+ if (engine->req) {
+ req = engine->req;
+ engine->req = NULL;
+ spin_unlock_bh(&engine->lock);
+ mv_cesa_complete_req(crypto_tfm_ctx(req->tfm), req,
+ -ENOENT);
+ spin_lock_bh(&engine->lock);
+ }
+
+ while ((req = crypto_dequeue_request(&engine->queue)) != NULL) {
+ spin_unlock_bh(&engine->lock);
+ mv_cesa_complete_req(crypto_tfm_ctx(req->tfm), req,
+ -ENOENT);
+ spin_lock_bh(&engine->lock);
+ }
+
+ while ((req = mv_cesa_engine_dequeue_complete_request(engine))
+ != NULL) {
+ spin_unlock_bh(&engine->lock);
+ mv_cesa_complete_req(crypto_tfm_ctx(req->tfm), req,
+ -ENOENT);
+ spin_lock_bh(&engine->lock);
+ }
+ spin_unlock_bh(&engine->lock);
+ }
+
+ /*
+ * The completion callbacks above (and any concurrent submitter) rely
+ * on the global cesa_dev pointer: only clear it once the engines are
+ * fully drained.
+ */
cesa_dev = NULL;
}
diff --git a/drivers/crypto/marvell/cesa/cesa.h b/drivers/crypto/marvell/cesa/cesa.h
index 44351b252861..56c0dd6f5772 100644
--- a/drivers/crypto/marvell/cesa/cesa.h
+++ b/drivers/crypto/marvell/cesa/cesa.h
@@ -10,6 +10,9 @@
#define CESA_ENGINE_OFF(i) (((i) * 0x2000))
+/* Max time in microseconds to wait for the engine to stop */
+#define CESA_ENGINE_STOP_TIMEOUT_US 1000
+
#define CESA_TDMA_BYTE_CNT 0x800
#define CESA_TDMA_SRC_ADDR 0x810
#define CESA_TDMA_DST_ADDR 0x820
@@ -450,6 +453,7 @@ struct mv_cesa_engine {
struct mv_cesa_tdma_chain chain_sw;
struct list_head complete_queue;
int irq;
+ bool aborted;
};
/**
--
2.55.0
next reply other threads:[~2026-09-24 23:59 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 23:59 Rosen Penev [this message]
2026-09-25 0:15 ` Robert Lovrinovic
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=20260924235937.148475-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
all inboxes | Powered by JetHome®