diff options
| author | Paul Louvel <paul.louvel@bootlin.com> | 2026-05-07 16:41:47 +0200 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2026-05-15 18:08:47 +0800 |
| commit | e17ff3d6ff907dc8406261e8fd3e1fc8a908f0f6 (patch) | |
| tree | 9871cbced53a77fa333831749816187beb12a6a8 /drivers/crypto/talitos.c | |
| parent | 930d9d36ea618a775985446a125aedeb401db522 (diff) | |
| download | linux-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.c | 26 |
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; |
