summaryrefslogtreecommitdiff
path: root/drivers/crypto/talitos.c
diff options
context:
space:
mode:
authorPaul Louvel <paul.louvel@bootlin.com>2026-05-07 16:41:47 +0200
committerHerbert Xu <herbert@gondor.apana.org.au>2026-05-15 18:08:47 +0800
commite17ff3d6ff907dc8406261e8fd3e1fc8a908f0f6 (patch)
tree9871cbced53a77fa333831749816187beb12a6a8 /drivers/crypto/talitos.c
parent930d9d36ea618a775985446a125aedeb401db522 (diff)
downloadlinux-next-e17ff3d6ff907dc8406261e8fd3e1fc8a908f0f6.tar.gz
linux-next-e17ff3d6ff907dc8406261e8fd3e1fc8a908f0f6.zip
crypto: talitos - use dma_sync_single_for_cpu() before reading descriptor header
In order to know if a descriptor has been processed by the device, the driver polls the FIFO to see if DESC_HDR_DONE is set on a descriptor header to confirm completion. The current code does not make sure that the CPU gets up to date data before reading the descriptor. Fix this by calling dma_sync_single_for_cpu() before reading memory written by the device. Cc: stable@vger.kernel.org Fixes: 58cdbc6d2263 ("crypto: talitos - fix hash on SEC1.") Signed-off-by: Paul Louvel <paul.louvel@bootlin.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/talitos.c')
-rw-r--r--drivers/crypto/talitos.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index bd4cc06ee13c..e7ef286f4306 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -322,19 +322,31 @@ static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
return -EINPROGRESS;
}
-static __be32 get_request_hdr(struct talitos_request *request, bool is_sec1)
+static __be32 get_request_hdr(struct device *dev,
+ struct talitos_request *request, bool is_sec1)
{
struct talitos_edesc *edesc;
- if (!is_sec1)
+ if (!is_sec1) {
+ dma_sync_single_for_cpu(dev, request->dma_desc,
+ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+
return request->desc->hdr;
+ }
- if (!request->desc->next_desc)
+ if (!request->desc->next_desc) {
+ dma_sync_single_for_cpu(dev, request->dma_desc,
+ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
return request->desc->hdr1;
+ } else {
+ dma_sync_single_for_cpu(dev,
+ be32_to_cpu(request->desc->next_desc),
+ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+ edesc = container_of(request->desc, struct talitos_edesc, desc);
- edesc = container_of(request->desc, struct talitos_edesc, desc);
-
- return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))->hdr1;
+ return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))
+ ->hdr1;
+ }
}
/*
@@ -358,7 +370,7 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
/* descriptors with their done bits set don't get the error */
rmb();
- hdr = get_request_hdr(request, is_sec1);
+ hdr = get_request_hdr(dev, request, is_sec1);
if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
status = 0;