]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
crypto: talitos - use dma_sync_single_for_cpu() before reading descriptor header
authorPaul Louvel <paul.louvel@bootlin.com>
Thu, 7 May 2026 14:41:47 +0000 (16:41 +0200)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 15 May 2026 10:08:47 +0000 (18:08 +0800)
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>
drivers/crypto/talitos.c

index bd4cc06ee13c89010f22c402df3e62fc88aea45f..e7ef286f43061aaf544d7399a6d1d15997e47f92 100644 (file)
@@ -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;