[PATCH v3 11/12] crypto: ti - Terminate DMA on all error paths in AEAD to clear descriptors

From: T Pratham

Date: Thu Sep 10 2026 - 06:55:29 EST


dmaengine_prep_slave_sg() allocates a DMA descriptor which is freed on
either successful dmaengine_submit() or on dmaengine_terminate_sync().

The error paths after descriptor allocation was not clearing them,
leaving the descriptors orphaned and leaking memory in case of failure.
Add terminate calls in dthe_aead_run() to appropriately clean the DMA
descriptors.

Fixes: 37b902c603042 ("crypto: ti - Add support for AES-GCM in DTHEv2 driver")
Signed-off-by: T Pratham <t-pratham@xxxxxx>
---
drivers/crypto/ti/dthev2-aes.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/ti/dthev2-aes.c b/drivers/crypto/ti/dthev2-aes.c
index 10073bbeca113..a034c1c8f20ed 100644
--- a/drivers/crypto/ti/dthev2-aes.c
+++ b/drivers/crypto/ti/dthev2-aes.c
@@ -912,6 +912,7 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)

struct device *tx_dev, *rx_dev;
struct dma_async_tx_descriptor *desc_in, *desc_out, *desc_aad_out;
+ bool cleanup_tx_chan = false;

int ret;
int err;
@@ -1012,13 +1013,15 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
src_nents = sg_nents_for_len(src, cryptlen);
if (src_nents < 0) {
ret = src_nents;
- goto aead_dma_prep_aad_err;
+ cleanup_tx_chan = (assoclen != 0);
+ goto aead_dma_map_src_err;
}
src_mapped_nents = dma_map_sg(tx_dev, src, src_nents, src_dir);
if (src_mapped_nents == 0) {
dev_err(dev_data->dev, "Failed to map ciphertext src for TX\n");
ret = -EINVAL;
- goto aead_dma_prep_aad_err;
+ cleanup_tx_chan = (assoclen != 0);
+ goto aead_dma_map_src_err;
}

/* Prepare DMA descriptors for ciphertext TX */
@@ -1028,6 +1031,7 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
if (!desc_out) {
dev_err(dev_data->dev, "Ciphertext TX prep_slave_sg() failed\n");
ret = -EINVAL;
+ cleanup_tx_chan = (assoclen != 0);
goto aead_dma_prep_src_err;
}

@@ -1036,12 +1040,14 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
dst_nents = sg_nents_for_len(dst, cryptlen);
if (dst_nents < 0) {
ret = dst_nents;
+ cleanup_tx_chan = true;
goto aead_dma_prep_src_err;
}
dst_mapped_nents = dma_map_sg(rx_dev, dst, dst_nents, dst_dir);
if (dst_mapped_nents == 0) {
dev_err(dev_data->dev, "Failed to map ciphertext dst for RX\n");
ret = -EINVAL;
+ cleanup_tx_chan = true;
goto aead_dma_prep_src_err;
}
} else {
@@ -1056,6 +1062,7 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
if (!desc_in) {
dev_err(dev_data->dev, "Ciphertext RX prep_slave_sg() failed\n");
ret = -EINVAL;
+ cleanup_tx_chan = true;
goto aead_dma_prep_dst_err;
}

@@ -1145,6 +1152,10 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
aead_dma_prep_src_err:
if (cryptlen != 0)
dma_unmap_sg(tx_dev, src, src_nents, src_dir);
+aead_dma_map_src_err:
+ /* Free any descriptor prepared on dma_aes_tx but never submitted */
+ if (cleanup_tx_chan)
+ dmaengine_terminate_sync(dev_data->dma_aes_tx);
aead_dma_prep_aad_err:
if (assoclen != 0)
dma_unmap_sg(tx_dev, aad_sg, aad_nents, aad_dir);
--
2.34.1