]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
crypto: talitos/hash - prepare SEC1 descriptor chaining, remove additional descriptor
authorPaul Louvel <paul.louvel@bootlin.com>
Thu, 7 May 2026 14:41:52 +0000 (16:41 +0200)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 15 May 2026 10:08:48 +0000 (18:08 +0800)
Currently, when SEC1 has buffered data (nbuf != 0), the ahash code
creates an additional descriptor on the fly inside
common_nonsnoop_hash() to handle the remainder of the data. This
approach is incompatible with the arbitrary-length descriptor chaining
that follows.

Remove the "additional descriptor" logic from common_nonsnoop_hash()
and common_nonsnoop_hash_unmap().

Also remove the nbytes adjustment for SEC1 in ahash_edesc_alloc()
that subtracted nbuf.

Cc: stable@vger.kernel.org
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/talitos.c

index c9c5d195b317f07b88aef0afc854dce24b4315aa..72d9c50b055e770183eff75ec3152b27a37281f6 100644 (file)
@@ -1788,15 +1788,9 @@ static void common_nonsnoop_hash_unmap(struct device *dev,
        struct talitos_private *priv = dev_get_drvdata(dev);
        bool is_sec1 = has_ftr_sec1(priv);
        struct talitos_desc *desc = &edesc->desc;
-       struct talitos_desc *desc2;
-
-       if (desc->next_desc)
-               desc2 = &edesc->next_desc->desc;
 
        unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
-       if (desc->next_desc &&
-           desc->ptr[5].ptr != desc2->ptr[5].ptr)
-               unmap_single_talitos_ptr(dev, &desc2->ptr[5], DMA_FROM_DEVICE);
+
        if (req_ctx->last_desc)
                memcpy(areq->result, req_ctx->hw_context,
                       crypto_ahash_digestsize(tfm));
@@ -1808,13 +1802,6 @@ static void common_nonsnoop_hash_unmap(struct device *dev,
        if (from_talitos_ptr_len(&desc->ptr[1], is_sec1))
                unmap_single_talitos_ptr(dev, &desc->ptr[1],
                                         DMA_TO_DEVICE);
-       else if (desc->next_desc)
-               unmap_single_talitos_ptr(dev, &desc2->ptr[1],
-                                        DMA_TO_DEVICE);
-
-       if (is_sec1 && req_ctx->nbuf)
-               unmap_single_talitos_ptr(dev, &desc->ptr[3],
-                                        DMA_TO_DEVICE);
 
        if (edesc->dma_len)
                dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
@@ -1922,9 +1909,6 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
                to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
                               is_sec1);
 
-       if (is_sec1 && req_ctx->nbuf)
-               length -= req_ctx->nbuf;
-
        sg_count = edesc->src_nents ?: 1;
        if (is_sec1 && sg_count > 1)
                sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length);
@@ -1934,16 +1918,10 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
        /*
         * data in
         */
-       if (is_sec1 && req_ctx->nbuf) {
-               map_single_talitos_ptr(dev, &desc->ptr[3], req_ctx->nbuf,
-                                      req_ctx->buf[req_ctx->buf_idx],
-                                      DMA_TO_DEVICE);
-       } else {
-               sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
-                                         &desc->ptr[3], sg_count, 0, 0);
-               if (sg_count > 1)
-                       sync_needed = true;
-       }
+       sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
+                                       &desc->ptr[3], sg_count, 0, 0);
+       if (sg_count > 1)
+               sync_needed = true;
 
        /* fifth DWORD empty */
 
@@ -1963,49 +1941,6 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
        if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
                talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
 
-       if (is_sec1 && req_ctx->nbuf && length) {
-               struct talitos_edesc *edesc2;
-               struct talitos_desc *desc2;
-
-               edesc2 = kzalloc(sizeof(*edesc2),
-                                areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
-                                        GFP_KERNEL :
-                                        GFP_ATOMIC);
-               if (!edesc2) {
-                       ret = -ENOMEM;
-                       goto err;
-               }
-               edesc->next_desc = edesc2;
-
-               desc2 = &edesc2->desc;
-
-               desc2->hdr = desc->hdr;
-               desc2->hdr &= ~DESC_HDR_MODE0_MDEU_INIT;
-               desc->hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
-               desc->hdr |= DESC_HDR_MODE0_MDEU_CONT;
-               desc->hdr &= ~DESC_HDR_DONE_NOTIFY;
-
-               if (desc->ptr[1].ptr)
-                       copy_talitos_ptr(&desc2->ptr[1], &desc->ptr[1],
-                                        is_sec1);
-               else
-                       map_single_talitos_ptr_nosync(dev, &desc2->ptr[1],
-                                                     req_ctx->hw_context_size,
-                                                     req_ctx->hw_context,
-                                                     DMA_TO_DEVICE);
-               copy_talitos_ptr(&desc2->ptr[2], &desc->ptr[2], is_sec1);
-               sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
-                                         &desc2->ptr[3], sg_count, 0, 0);
-               if (sg_count > 1)
-                       sync_needed = true;
-               copy_talitos_ptr(&desc2->ptr[5], &desc->ptr[5], is_sec1);
-               if (req_ctx->last_desc)
-                       map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
-                                                     req_ctx->hw_context_size,
-                                                     req_ctx->hw_context,
-                                                     DMA_FROM_DEVICE);
-       }
-
        if (sync_needed)
                dma_sync_single_for_device(dev, edesc->dma_link_tbl,
                                           edesc->dma_len, DMA_BIDIRECTIONAL);
@@ -2028,11 +1963,6 @@ static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
        struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
        struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
        struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-       struct talitos_private *priv = dev_get_drvdata(ctx->dev);
-       bool is_sec1 = has_ftr_sec1(priv);
-
-       if (is_sec1)
-               nbytes -= req_ctx->nbuf;
 
        return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
                                   nbytes, 0, 0, 0, areq->base.flags, false);
@@ -2051,8 +1981,6 @@ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes
        unsigned int nsg;
        int nents;
        struct device *dev = ctx->dev;
-       struct talitos_private *priv = dev_get_drvdata(dev);
-       bool is_sec1 = has_ftr_sec1(priv);
        u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
 
        if (!req_ctx->last_desc && (nbytes + req_ctx->nbuf <= blocksize)) {
@@ -2084,30 +2012,13 @@ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes
        }
 
        /* Chain in any previously buffered data */
-       if (!is_sec1 && req_ctx->nbuf) {
+       if (req_ctx->nbuf) {
                nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
                sg_init_table(req_ctx->bufsl, nsg);
                sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
                if (nsg > 1)
                        sg_chain(req_ctx->bufsl, 2, req_ctx->request_sl);
                req_ctx->psrc = req_ctx->bufsl;
-       } else if (is_sec1 && req_ctx->nbuf && req_ctx->nbuf < blocksize) {
-               int offset;
-
-               if (nbytes_to_hash > blocksize)
-                       offset = blocksize - req_ctx->nbuf;
-               else
-                       offset = nbytes_to_hash - req_ctx->nbuf;
-               nents = sg_nents_for_len(req_ctx->request_sl, offset);
-               if (nents < 0) {
-                       dev_err(dev, "Invalid number of src SG.\n");
-                       return nents;
-               }
-               sg_copy_to_buffer(req_ctx->request_sl, nents,
-                                 ctx_buf + req_ctx->nbuf, offset);
-               req_ctx->nbuf += offset;
-               req_ctx->psrc = scatterwalk_ffwd(req_ctx->bufsl, req_ctx->request_sl,
-                                                offset);
        } else
                req_ctx->psrc = req_ctx->request_sl;