* [PATCH] crypto: eip93: fix IRQ teardown ordering in remove path
@ 2026-09-09 21:12 Rosen Penev
0 siblings, 0 replies; only message in thread
From: Rosen Penev @ 2026-09-09 21:12 UTC (permalink / raw)
To: linux-crypto
Cc: Christian Marangi, Antoine Tenart, Herbert Xu, David S. Miller,
open list
Switch from devm_request_threaded_irq() to request_threaded_irq() so
that free_irq() can be called at the correct position in the remove
path. Move the IRQ registration after tasklet_init() in probe to
ensure the tasklet is ready before the handler can fire.
Reorder eip93_cleanup() to:
1. disable device interrupts (HW)
2. free_irq() - synchronizes and removes the handler
3. tasklet_kill() - safe, no new IRQs can arrive
The previous order (tasklet_kill before interrupt disable) could race:
an IRQ arriving after tasklet_kill() would schedule the already-killed
tasklet. With devm_request_threaded_irq(), free_irq() ran after the
remove callback returned, leaving the handler registered while device
state was being torn down.
Assisted-by: opencode:big-pickle
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
.../crypto/inside-secure/eip93/eip93-main.c | 27 ++++++++++++-------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/crypto/inside-secure/eip93/eip93-main.c b/drivers/crypto/inside-secure/eip93/eip93-main.c
index e62785952b0d..4cfddfd1935b 100644
--- a/drivers/crypto/inside-secure/eip93/eip93-main.c
+++ b/drivers/crypto/inside-secure/eip93/eip93-main.c
@@ -395,12 +395,16 @@ static int eip93_desc_init(struct eip93_device *eip93)
static void eip93_cleanup(struct eip93_device *eip93)
{
- tasklet_kill(&eip93->ring->done_task);
-
- /* Clear/ack all interrupts before disable all */
+ /* Stop HW from asserting IRQ first */
eip93_irq_clear(eip93, EIP93_INT_ALL);
eip93_irq_disable(eip93, EIP93_INT_ALL);
+ /* Synchronize and unregister the IRQ handler */
+ free_irq(eip93->irq, eip93);
+
+ /* No new IRQs can arrive - safe to kill the tasklet */
+ tasklet_kill(&eip93->ring->done_task);
+
writel(0, eip93->base + EIP93_REG_PE_CLOCK_CTRL);
eip93_desc_free(eip93);
@@ -430,12 +434,6 @@ static int eip93_crypto_probe(struct platform_device *pdev)
if (eip93->irq < 0)
return eip93->irq;
- ret = devm_request_threaded_irq(eip93->dev, eip93->irq, eip93_irq_handler,
- NULL, IRQF_ONESHOT,
- dev_name(eip93->dev), eip93);
- if (ret)
- return ret;
-
ret = eip93_desc_init(eip93);
if (ret)
return ret;
@@ -448,6 +446,11 @@ static int eip93_crypto_probe(struct platform_device *pdev)
spin_lock_init(&eip93->ring->idr_lock);
idr_init(&eip93->ring->crypto_async_idr);
+ ret = request_threaded_irq(eip93->irq, eip93_irq_handler, NULL,
+ IRQF_ONESHOT, dev_name(eip93->dev), eip93);
+ if (ret)
+ goto err_free_tasklet;
+
algo_flags = readl(eip93->base + EIP93_REG_PE_OPTION_1);
eip93_initialize(eip93, algo_flags);
@@ -472,6 +475,12 @@ static int eip93_crypto_probe(struct platform_device *pdev)
readl(eip93->base + EIP93_REG_PE_OPTION_0));
return 0;
+
+err_free_tasklet:
+ idr_destroy(&eip93->ring->crypto_async_idr);
+ tasklet_kill(&eip93->ring->done_task);
+ eip93_desc_free(eip93);
+ return ret;
}
static void eip93_crypto_remove(struct platform_device *pdev)
--
2.55.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-09 21:12 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-09 21:12 [PATCH] crypto: eip93: fix IRQ teardown ordering in remove path Rosen Penev
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.