From nobody Sun Jun 14 02:38:26 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 243C21ADC83; Mon, 4 May 2026 15:39:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777909183; cv=none; b=X+NTgGYoWp7NL+fpCiFj6fiC2m0eMIsXQ5GvlNWvAfsHPP/xmX+4Sz5qUjh6XxtjXgoEVepPYPJ2++9OJUJgDQMynOn0u2qa27vQGEvHBLffQY3sGENHhNshSfVgI3J/9NltFpBv1Fiz6erPcz3y+OU895jPtYYFXqjS/4rCAWw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777909183; c=relaxed/simple; bh=apFmhEO/cUDEV7PQ1yNLjuu39N3a7AyxGDS+MflG8mM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Knk0HYGY7kRlThaqB8IdWHqY6cl21wLmEVvPDX3cf4fuAUyqJ+Q5HT4SpV7zINQbsDNvr1AiUiacYYCStKVe+25+62btMCBZbIqfKDiWyfzSv3SYRXoonu8yFDODoVBhxqq89JwZfZK13h1fbCfQgBViKsO3CsrtIfS31hFL5Qk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=dODzHycf; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="dODzHycf" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 9326A1A350D; Mon, 4 May 2026 15:39:38 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 682ED5FD5F; Mon, 4 May 2026 15:39:38 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B439E11AD2BCF; Mon, 4 May 2026 17:39:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1777909177; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=vKri8qzuHSFOAgsOHzYu1EBqQXOaekQs4V9gLkHEBno=; b=dODzHycfiGtmC0XM7Tl8Nenwm6p+/cKgV0dZ9L9AaXUKkk/IySfERTgp3PtRnl2zOhVTxn U3Uqv06ofeXsVOfsPH2TCXOSbgMB05JNRad7/ZYgiKDpD+8m2Nk3Cw4U0kOuWZyjPiwiKo 2lYR8uUzneVpALvefmt5N4GLY97yrOBULdPmTGvToWDFjUy9j4LVzQjrFkhRaiqibyRTLM 1LlcXgqTSmosa6rP0o2NnDYmHEyoCC6QeHoIVXT8Np6Nk4LmhCw+8x+1YV9vWDZaUqECU+ 9GVldO6hSV7JMWB2T5c5YeoSlAbHPMJvBE/wNupWOW4bV0qv71EyDPbLX9mrrQ== From: Paul Louvel Date: Mon, 04 May 2026 17:38:27 +0200 Subject: [PATCH 1/4] crypto: talitos - use hardware facilities for large ahash requests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-1-c97c641976f5@bootlin.com> References: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5@bootlin.com> In-Reply-To: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5@bootlin.com> To: Herbert Xu , "David S. Miller" , Paolo Abeni , David Howells , Kim Phillips Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Thomas Petazzoni , Herve Codina , Paul Louvel , Christophe Leroy , stable@vger.kernel.org X-Mailer: b4 0.15.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1777909177; l=29493; i=paul.louvel@bootlin.com; s=20260313; h=from:subject:message-id; bh=apFmhEO/cUDEV7PQ1yNLjuu39N3a7AyxGDS+MflG8mM=; b=3tFMCx3O0aCtLL/m9pKH+WGU+T/jtTVNA9ezez6Ykn3wjNNHWyRX4aFhSihL4DjXNyiU9BsGt KzUHhB4MsMhC2/cNi9r7s6fQL1Ij3hK35H+qZKhbambV5DIZ5IO7UcB X-Developer-Key: i=paul.louvel@bootlin.com; a=ed25519; pk=eLW50NT18UAvUT5cAcYf88zNbBCZDLFXuptpyLVhVIU= X-Last-TLS-Session-Version: TLSv1.3 Commit 655ef638a2bc ("crypto: talitos - fix SEC1 32k ahash request limitation") works around the SEC1 per-descriptor data limit by scheduling remaining work on the system workqueue, incurring scheduling latency and one interrupt per descriptor. SEC2 hardware also suffers from the same per-descriptor limitation, but instead of a limit of 32k, it has a limit of 64k - 1 bytes. Replace the previous approach by implementing support for hardware backed multi descriptors handling : - SEC1: Use descriptor chaining. Descriptors are linked via their Next Descriptor field; only the DONE bit on the last descriptor is set, so the engine raises a single interrupt per request. Only submit the first descriptor of the chain, the hardware will fetch the next one without host intervention. - SEC2: Use the per-channel fetch FIFO (up to 24 entries). Unlike the SEC1, each descriptor has its DONE bit set to preserve flush_channel() semantics, and each descriptor is submitted. This removes the workqueue-based splitting entirely and mitigates the (64k - 1) byte ahash request limit on SEC2. Cc: stable@vger.kernel.org Fixes: c662b043cdca ("crypto: af_alg/hash: Support MSG_SPLICE_PAGES") Signed-off-by: Paul Louvel --- drivers/crypto/talitos.c | 558 +++++++++++++++++++++++++------------------= ---- drivers/crypto/talitos.h | 14 ++ 2 files changed, 313 insertions(+), 259 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index bc61d0fe3514..458a6a56d65b 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -12,8 +12,8 @@ * All rights reserved. */ =20 -#include #include +#include #include #include #include @@ -255,6 +255,55 @@ static int init_device(struct device *dev) return 0; } =20 +static void sec1_map_descriptor(struct device *dev, + struct talitos_request *request, + struct talitos_desc *desc) +{ + struct talitos_edesc *edesc =3D + container_of(desc, struct talitos_edesc, desc); + struct talitos_edesc *prev_edesc =3D NULL; + dma_addr_t dma_desc, prev_dma_desc; + + /* + * Since the first descriptor in the chain is the one passed to this func= tion, + * the prev ptr is guaranteed to be the descriptor list head. + */ + + request->desc_chain =3D edesc->node.prev; + + list_for_each_entry(edesc, request->desc_chain, node) { + edesc->desc.hdr1 =3D edesc->desc.hdr; + + dma_desc =3D dma_map_single(dev, &edesc->desc.hdr1, + TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL); + + if (!prev_edesc) { + request->dma_desc =3D dma_desc; + goto next; + } + + /* chain in any previous descriptors */ + + prev_edesc->desc.next_desc =3D cpu_to_be32(dma_desc); + + dma_sync_single_for_device(dev, prev_dma_desc, + TALITOS_DESC_SIZE, DMA_TO_DEVICE); + +next: + prev_edesc =3D edesc; + prev_dma_desc =3D dma_desc; + } +} + +static void sec2_map_descriptor(struct device *dev, + struct talitos_request *request, + struct talitos_desc *desc) +{ + request->dma_desc =3D + dma_map_single(dev, desc, TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL); + request->desc_chain =3D NULL; +} + /** * talitos_submit - submits a descriptor to the device for processing * @dev: the SEC device to be used @@ -291,16 +340,10 @@ static int talitos_submit(struct device *dev, int ch,= struct talitos_desc *desc, request =3D &priv->chan[ch].fifo[head]; =20 /* map descriptor and save caller data */ - if (is_sec1) { - desc->hdr1 =3D desc->hdr; - request->dma_desc =3D dma_map_single(dev, &desc->hdr1, - TALITOS_DESC_SIZE, - DMA_BIDIRECTIONAL); - } else { - request->dma_desc =3D dma_map_single(dev, desc, - TALITOS_DESC_SIZE, - DMA_BIDIRECTIONAL); - } + if (is_sec1) + sec1_map_descriptor(dev, request, desc); + else + sec2_map_descriptor(dev, request, desc); request->callback =3D callback; request->context =3D context; =20 @@ -326,15 +369,33 @@ static __be32 get_request_hdr(struct talitos_request = *request, bool is_sec1) { struct talitos_edesc *edesc; =20 - if (!is_sec1) + if (is_sec1) { + edesc =3D list_last_entry(request->desc_chain, + struct talitos_edesc, node); + return edesc->desc.hdr1; + } else { return request->desc->hdr; + } +} =20 - if (!request->desc->next_desc) - return request->desc->hdr1; +static void dma_unmap_request(struct device *dev, + struct talitos_request *request, bool is_sec1) +{ + struct talitos_edesc *edesc; =20 - edesc =3D container_of(request->desc, struct talitos_edesc, desc); + dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE, + DMA_BIDIRECTIONAL); =20 - return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))->hdr1; + if (is_sec1) { + list_for_each_entry(edesc, request->desc_chain, node) { + if (!edesc->desc.next_desc) + break; + + dma_unmap_single(dev, + be32_to_cpu(edesc->desc.next_desc), + TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL); + } + } } =20 /* @@ -358,6 +419,8 @@ static void flush_channel(struct device *dev, int ch, i= nt error, int reset_ch) =20 /* descriptors with their done bits set don't get the error */ rmb(); + + dma_unmap_request(dev, request, is_sec1); hdr =3D get_request_hdr(request, is_sec1); =20 if ((hdr & DESC_HDR_DONE) =3D=3D DESC_HDR_DONE) @@ -368,10 +431,6 @@ static void flush_channel(struct device *dev, int ch, = int error, int reset_ch) else status =3D error; =20 - dma_unmap_single(dev, request->dma_desc, - TALITOS_DESC_SIZE, - DMA_BIDIRECTIONAL); - /* copy entries so we can call callback outside lock */ saved_req.desc =3D request->desc; saved_req.callback =3D request->callback; @@ -459,14 +518,42 @@ DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE) DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE) DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE) =20 +static __be32 sec1_current_desc_hdr(struct talitos_request *request, + dma_addr_t cpdr) +{ + struct talitos_edesc *edesc; + + /* if the descriptor is the first of the chain */ + if (request->dma_desc =3D=3D cpdr) + return request->desc->hdr1; + + /* otherwise iterate through the chain */ + list_for_each_entry(edesc, request->desc_chain, node) + if (edesc->desc.next_desc =3D=3D cpu_to_be32(cpdr)) + return list_next_entry(edesc, node)->desc.hdr1; + + return 0; +} + +static __be32 sec2_current_desc_hdr(struct talitos_request *request, + dma_addr_t cpdr) +{ + if (request->dma_desc =3D=3D cpdr) + return request->desc->hdr; + + return 0; +} + /* * locate current (offending) descriptor */ static __be32 current_desc_hdr(struct device *dev, int ch) { struct talitos_private *priv =3D dev_get_drvdata(dev); + bool is_sec1 =3D has_ftr_sec1(priv); int tail, iter; dma_addr_t cur_desc; + __be32 hdr =3D 0; =20 cur_desc =3D ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32; cur_desc |=3D in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO); @@ -477,27 +564,25 @@ static __be32 current_desc_hdr(struct device *dev, in= t ch) } =20 tail =3D priv->chan[ch].tail; - iter =3D tail; - while (priv->chan[ch].fifo[iter].dma_desc !=3D cur_desc && - priv->chan[ch].fifo[iter].desc->next_desc !=3D cpu_to_be32(cur_des= c)) { - iter =3D (iter + 1) & (priv->fifo_len - 1); - if (iter =3D=3D tail) { - dev_err(dev, "couldn't locate current descriptor\n"); - return 0; - } - } + do { + if (is_sec1) + hdr =3D sec1_current_desc_hdr(&priv->chan[ch].fifo[iter], + cur_desc); + else + hdr =3D sec2_current_desc_hdr(&priv->chan[ch].fifo[iter], + cur_desc); =20 - if (priv->chan[ch].fifo[iter].desc->next_desc =3D=3D cpu_to_be32(cur_desc= )) { - struct talitos_edesc *edesc; + if (hdr) + break; =20 - edesc =3D container_of(priv->chan[ch].fifo[iter].desc, - struct talitos_edesc, desc); - return ((struct talitos_desc *) - (edesc->buf + edesc->dma_len))->hdr; - } + iter =3D (iter + 1) & (priv->fifo_len - 1); + } while (iter !=3D tail); =20 - return priv->chan[ch].fifo[iter].desc->hdr; + if (!hdr) + dev_err(dev, "couldn't locate current descriptor\n"); + + return hdr; } =20 /* @@ -874,15 +959,9 @@ struct talitos_ahash_req_ctx { unsigned int last_request; unsigned int to_hash_later; unsigned int nbuf; + struct list_head desc_list; struct scatterlist bufsl[2]; struct scatterlist *psrc; - - struct scatterlist request_bufsl[2]; - struct ahash_request *areq; - struct scatterlist *request_sl; - unsigned int remaining_ahash_request_bytes; - unsigned int current_ahash_request_bytes; - struct work_struct sec1_ahash_process_remaining; }; =20 struct talitos_export_state { @@ -1396,10 +1475,6 @@ static struct talitos_edesc *talitos_edesc_alloc(str= uct device *dev, dma_len =3D 0; } alloc_len +=3D icv_stashing ? authsize : 0; - - /* if its a ahash, add space for a second desc next to the first one */ - if (is_sec1 && !dst) - alloc_len +=3D sizeof(struct talitos_desc); alloc_len +=3D ivsize; =20 edesc =3D kmalloc(ALIGN(alloc_len, dma_get_cache_alignment()), flags); @@ -1411,6 +1486,7 @@ static struct talitos_edesc *talitos_edesc_alloc(stru= ct device *dev, } memset(&edesc->desc, 0, sizeof(edesc->desc)); =20 + INIT_LIST_HEAD(&edesc->node); edesc->src_nents =3D src_nents; edesc->dst_nents =3D dst_nents; edesc->iv_dma =3D iv_dma; @@ -1715,73 +1791,106 @@ static void common_nonsnoop_hash_unmap(struct devi= ce *dev, struct talitos_private *priv =3D dev_get_drvdata(dev); bool is_sec1 =3D has_ftr_sec1(priv); struct talitos_desc *desc =3D &edesc->desc; - struct talitos_desc *desc2 =3D (struct talitos_desc *) - (edesc->buf + edesc->dma_len); =20 unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE); - if (desc->next_desc && - desc->ptr[5].ptr !=3D desc2->ptr[5].ptr) - unmap_single_talitos_ptr(dev, &desc2->ptr[5], DMA_FROM_DEVICE); - if (req_ctx->last_desc) + if (edesc->last && req_ctx->last_request) memcpy(areq->result, req_ctx->hw_context, crypto_ahash_digestsize(tfm)); =20 - if (req_ctx->psrc) - talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0); + if (edesc->src) + talitos_sg_unmap(dev, edesc, edesc->src, NULL, 0, 0); =20 /* When using hashctx-in, must unmap it. */ 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); =20 if (edesc->dma_len) dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len, DMA_BIDIRECTIONAL); +} + +static void ahash_free_desc_list_from(struct ahash_request *areq, + struct talitos_edesc *edesc) +{ + struct talitos_ctx *ctx =3D crypto_ahash_ctx(crypto_ahash_reqtfm(areq)); + struct talitos_ahash_req_ctx *req_ctx =3D ahash_request_ctx(areq); + struct talitos_edesc *tmp; =20 - if (desc->next_desc) - dma_unmap_single(dev, be32_to_cpu(desc->next_desc), - TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL); + list_for_each_entry_safe_from(edesc, tmp, &req_ctx->desc_list, node) { + list_del(&edesc->node); + common_nonsnoop_hash_unmap(ctx->dev, edesc, areq); + kfree(edesc); + } } =20 -static void ahash_done(struct device *dev, - struct talitos_desc *desc, void *context, - int err) +static void sec1_ahash_done(struct device *dev, struct talitos_desc *desc, + void *context, int err) { + struct talitos_ahash_req_ctx *req_ctx =3D ahash_request_ctx(context); struct ahash_request *areq =3D context; - struct talitos_edesc *edesc =3D - container_of(desc, struct talitos_edesc, desc); - struct talitos_ahash_req_ctx *req_ctx =3D ahash_request_ctx(areq); =20 - if (!req_ctx->last_desc && req_ctx->to_hash_later) { + req_ctx->first_desc =3D 0; + + ahash_free_desc_list_from(areq, + list_first_entry(&req_ctx->desc_list, + struct talitos_edesc, node)); + + if (!req_ctx->last_request && req_ctx->to_hash_later) { /* Position any partial block for next update/final/finup */ req_ctx->buf_idx =3D (req_ctx->buf_idx + 1) & 1; req_ctx->nbuf =3D req_ctx->to_hash_later; } - common_nonsnoop_hash_unmap(dev, edesc, areq); =20 + ahash_request_complete(areq, err); +} + +static void sec2_ahash_done(struct device *dev, struct talitos_desc *desc, + void *context, int err) +{ + struct ahash_request *areq =3D context; + struct talitos_ahash_req_ctx *req_ctx =3D ahash_request_ctx(areq); + struct crypto_ahash *tfm =3D crypto_ahash_reqtfm(areq); + struct talitos_ctx *ctx =3D crypto_ahash_ctx(tfm); + struct talitos_edesc *edesc, *next; + bool is_last; + + req_ctx->first_desc =3D 0; + + edesc =3D container_of(desc, struct talitos_edesc, desc); + is_last =3D edesc->last; + if (!is_last) + next =3D list_next_entry(edesc, node); + + list_del(&edesc->node); + common_nonsnoop_hash_unmap(ctx->dev, edesc, areq); kfree(edesc); =20 - if (err) { - ahash_request_complete(areq, err); - return; - } + if (err) + goto err_out; =20 - req_ctx->remaining_ahash_request_bytes -=3D - req_ctx->current_ahash_request_bytes; + if (!is_last) { + err =3D talitos_submit(dev, ctx->ch, &next->desc, sec2_ahash_done, + areq); + if (err !=3D -EINPROGRESS) + goto err_out; =20 - if (!req_ctx->remaining_ahash_request_bytes) { - ahash_request_complete(areq, 0); return; } =20 - schedule_work(&req_ctx->sec1_ahash_process_remaining); + if (!req_ctx->last_request && req_ctx->to_hash_later) { + /* Position any partial block for next update/final/finup */ + req_ctx->buf_idx =3D (req_ctx->buf_idx + 1) & 1; + req_ctx->nbuf =3D req_ctx->to_hash_later; + } + + ahash_request_complete(areq, 0); + + return; +err_out: + if (!is_last) + ahash_free_desc_list_from(areq, next); + ahash_request_complete(areq, err); } =20 /* @@ -1805,18 +1914,14 @@ static void talitos_handle_buggy_hash(struct talito= s_ctx *ctx, (char *)padded_hash, DMA_TO_DEVICE); } =20 -static int common_nonsnoop_hash(struct talitos_edesc *edesc, - struct ahash_request *areq, unsigned int length, - void (*callback) (struct device *dev, - struct talitos_desc *desc, - void *context, int error)) +static void common_nonsnoop_hash(struct talitos_edesc *edesc, + struct ahash_request *areq, unsigned int length) { struct crypto_ahash *tfm =3D crypto_ahash_reqtfm(areq); struct talitos_ctx *ctx =3D crypto_ahash_ctx(tfm); struct talitos_ahash_req_ctx *req_ctx =3D ahash_request_ctx(areq); struct device *dev =3D ctx->dev; struct talitos_desc *desc =3D &edesc->desc; - int ret; bool sync_needed =3D false; struct talitos_private *priv =3D dev_get_drvdata(dev); bool is_sec1 =3D has_ftr_sec1(priv); @@ -1825,48 +1930,35 @@ static int common_nonsnoop_hash(struct talitos_edes= c *edesc, /* first DWORD empty */ =20 /* hash context in */ - if (!req_ctx->first_desc || req_ctx->swinit) { + if (!edesc->first || !req_ctx->first_desc || req_ctx->swinit) { map_single_talitos_ptr_nosync(dev, &desc->ptr[1], req_ctx->hw_context_size, req_ctx->hw_context, DMA_TO_DEVICE); req_ctx->swinit =3D 0; } - /* Indicate next op is not the first. */ - req_ctx->first_desc =3D 0; =20 /* HMAC key */ if (ctx->keylen) to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, is_sec1); =20 - if (is_sec1 && req_ctx->nbuf) - length -=3D req_ctx->nbuf; - sg_count =3D edesc->src_nents ?: 1; if (is_sec1 && sg_count > 1) - sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length); + sg_copy_to_buffer(edesc->src, sg_count, edesc->buf, length); else if (length) - sg_count =3D dma_map_sg(dev, req_ctx->psrc, sg_count, + sg_count =3D dma_map_sg(dev, edesc->src, sg_count, DMA_TO_DEVICE); - /* - * 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 =3D talitos_sg_map(dev, req_ctx->psrc, length, edesc, - &desc->ptr[3], sg_count, 0, 0); - if (sg_count > 1) - sync_needed =3D true; - } + + sg_count =3D talitos_sg_map(dev, edesc->src, length, edesc, + &desc->ptr[3], sg_count, 0, 0); + if (sg_count > 1) + sync_needed =3D true; =20 /* fifth DWORD empty */ =20 /* hash/HMAC out -or- hash context out */ - if (req_ctx->last_desc) + if (edesc->last && req_ctx->last_request) map_single_talitos_ptr(dev, &desc->ptr[5], crypto_ahash_digestsize(tfm), req_ctx->hw_context, DMA_FROM_DEVICE); @@ -1881,70 +1973,93 @@ static int common_nonsnoop_hash(struct talitos_edes= c *edesc, if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) =3D=3D 0) talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]); =20 - if (is_sec1 && req_ctx->nbuf && length) { - struct talitos_desc *desc2 =3D (struct talitos_desc *) - (edesc->buf + edesc->dma_len); - dma_addr_t next_desc; - - memset(desc2, 0, sizeof(*desc2)); - desc2->hdr =3D desc->hdr; - desc2->hdr &=3D ~DESC_HDR_MODE0_MDEU_INIT; - desc2->hdr1 =3D desc2->hdr; - desc->hdr &=3D ~DESC_HDR_MODE0_MDEU_PAD; - desc->hdr |=3D DESC_HDR_MODE0_MDEU_CONT; - desc->hdr &=3D ~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 =3D talitos_sg_map(dev, req_ctx->psrc, length, edesc, - &desc2->ptr[3], sg_count, 0, 0); - if (sg_count > 1) - sync_needed =3D 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); - - next_desc =3D dma_map_single(dev, &desc2->hdr1, TALITOS_DESC_SIZE, - DMA_BIDIRECTIONAL); - desc->next_desc =3D cpu_to_be32(next_desc); - } - if (sync_needed) dma_sync_single_for_device(dev, edesc->dma_link_tbl, edesc->dma_len, DMA_BIDIRECTIONAL); - - ret =3D talitos_submit(dev, ctx->ch, desc, callback, areq); - if (ret !=3D -EINPROGRESS) { - common_nonsnoop_hash_unmap(dev, edesc, areq); - kfree(edesc); - } - return ret; } =20 static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq, + struct scatterlist *src, unsigned int nbytes) { struct crypto_ahash *tfm =3D crypto_ahash_reqtfm(areq); struct talitos_ctx *ctx =3D crypto_ahash_ctx(tfm); + + return talitos_edesc_alloc(ctx->dev, src, NULL, NULL, 0, + nbytes, 0, 0, 0, areq->base.flags, false); +} + +static int ahash_process_req_prepare(struct ahash_request *areq, + unsigned int nbytes, + unsigned int blocksize, bool is_sec1) +{ + struct talitos_ctx *ctx =3D crypto_ahash_ctx(crypto_ahash_reqtfm(areq)); struct talitos_ahash_req_ctx *req_ctx =3D ahash_request_ctx(areq); - struct talitos_private *priv =3D dev_get_drvdata(ctx->dev); - bool is_sec1 =3D has_ftr_sec1(priv); + size_t desc_max =3D is_sec1 ? TALITOS1_MAX_DATA_LEN : + TALITOS2_MAX_DATA_LEN; + struct talitos_edesc *edesc; + struct scatterlist tmp[2]; + size_t to_hash_this_desc; + struct scatterlist *src; + size_t offset =3D 0; + + INIT_LIST_HEAD(&req_ctx->desc_list); + do { + src =3D scatterwalk_ffwd(tmp, req_ctx->psrc, offset); + + to_hash_this_desc =3D + min(nbytes, ALIGN_DOWN(desc_max, blocksize)); + + /* Allocate extended descriptor */ + edesc =3D ahash_edesc_alloc(areq, src, to_hash_this_desc); + if (IS_ERR(edesc)) { + if (!list_empty(&req_ctx->desc_list)) { + edesc =3D list_first_entry(&req_ctx->desc_list, + struct talitos_edesc, + node); + ahash_free_desc_list_from(areq, edesc); + } =20 - if (is_sec1) - nbytes -=3D req_ctx->nbuf; + return PTR_ERR(edesc); + } =20 - return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0, - nbytes, 0, 0, 0, areq->base.flags, false); + edesc->src =3D + scatterwalk_ffwd(edesc->bufsl, req_ctx->psrc, offset); + edesc->desc.hdr =3D ctx->desc_hdr_template; + edesc->first =3D offset =3D=3D 0; + edesc->last =3D nbytes - to_hash_this_desc =3D=3D 0; + + /* On last one, request SEC to pad; otherwise continue */ + if (req_ctx->last_request && edesc->last) + edesc->desc.hdr |=3D DESC_HDR_MODE0_MDEU_PAD; + else + edesc->desc.hdr |=3D DESC_HDR_MODE0_MDEU_CONT; + + /* request SEC to INIT hash. */ + if (req_ctx->first_desc && edesc->first && !req_ctx->swinit) + edesc->desc.hdr |=3D DESC_HDR_MODE0_MDEU_INIT; + + /* + * When the tfm context has a keylen, it's an HMAC. + * A first or last (ie. not middle) descriptor must request HMAC. + */ + if (ctx->keylen && ((req_ctx->first_desc && edesc->first) || + (req_ctx->last_request && edesc->last))) + edesc->desc.hdr |=3D DESC_HDR_MODE0_MDEU_HMAC; + + /* clear the DN bit */ + if (is_sec1 && !edesc->last) + edesc->desc.hdr &=3D ~DESC_HDR_DONE_NOTIFY; + + list_add_tail(&edesc->node, &req_ctx->desc_list); + + common_nonsnoop_hash(edesc, areq, to_hash_this_desc); + + offset +=3D to_hash_this_desc; + nbytes -=3D to_hash_this_desc; + } while (nbytes); + + return 0; } =20 static int ahash_process_req_one(struct ahash_request *areq, unsigned int = nbytes) @@ -1963,15 +2078,16 @@ static int ahash_process_req_one(struct ahash_reque= st *areq, unsigned int nbytes struct talitos_private *priv =3D dev_get_drvdata(dev); bool is_sec1 =3D has_ftr_sec1(priv); u8 *ctx_buf =3D req_ctx->buf[req_ctx->buf_idx]; + int ret; =20 - if (!req_ctx->last_desc && (nbytes + req_ctx->nbuf <=3D blocksize)) { + if (!req_ctx->last_request && (nbytes + req_ctx->nbuf <=3D blocksize)) { /* Buffer up to one whole block */ - nents =3D sg_nents_for_len(req_ctx->request_sl, nbytes); + nents =3D sg_nents_for_len(areq->src, nbytes); if (nents < 0) { dev_err(dev, "Invalid number of src SG.\n"); return nents; } - sg_copy_to_buffer(req_ctx->request_sl, nents, + sg_copy_to_buffer(areq->src, nents, ctx_buf + req_ctx->nbuf, nbytes); req_ctx->nbuf +=3D nbytes; return 0; @@ -1981,7 +2097,7 @@ static int ahash_process_req_one(struct ahash_request= *areq, unsigned int nbytes nbytes_to_hash =3D nbytes + req_ctx->nbuf; to_hash_later =3D nbytes_to_hash & (blocksize - 1); =20 - if (req_ctx->last_desc) + if (req_ctx->last_request) to_hash_later =3D 0; else if (to_hash_later) /* There is a partial block. Hash the full block(s) now */ @@ -1993,123 +2109,48 @@ static int ahash_process_req_one(struct ahash_requ= est *areq, unsigned int nbytes } =20 /* Chain in any previously buffered data */ - if (!is_sec1 && req_ctx->nbuf) { + if (req_ctx->nbuf) { nsg =3D (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); + sg_chain(req_ctx->bufsl, 2, areq->src); req_ctx->psrc =3D req_ctx->bufsl; - } else if (is_sec1 && req_ctx->nbuf && req_ctx->nbuf < blocksize) { - int offset; - - if (nbytes_to_hash > blocksize) - offset =3D blocksize - req_ctx->nbuf; - else - offset =3D nbytes_to_hash - req_ctx->nbuf; - nents =3D 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 +=3D offset; - req_ctx->psrc =3D scatterwalk_ffwd(req_ctx->bufsl, req_ctx->request_sl, - offset); } else - req_ctx->psrc =3D req_ctx->request_sl; + req_ctx->psrc =3D areq->src; =20 if (to_hash_later) { - nents =3D sg_nents_for_len(req_ctx->request_sl, nbytes); + nents =3D sg_nents_for_len(areq->src, nbytes); if (nents < 0) { dev_err(dev, "Invalid number of src SG.\n"); return nents; } - sg_pcopy_to_buffer(req_ctx->request_sl, nents, + sg_pcopy_to_buffer(areq->src, nents, req_ctx->buf[(req_ctx->buf_idx + 1) & 1], to_hash_later, nbytes - to_hash_later); } req_ctx->to_hash_later =3D to_hash_later; =20 - /* Allocate extended descriptor */ - edesc =3D ahash_edesc_alloc(req_ctx->areq, nbytes_to_hash); - if (IS_ERR(edesc)) - return PTR_ERR(edesc); - - edesc->desc.hdr =3D ctx->desc_hdr_template; + ret =3D ahash_process_req_prepare(areq, nbytes_to_hash, blocksize, + is_sec1); + if (ret) + return ret; =20 - /* On last one, request SEC to pad; otherwise continue */ - if (req_ctx->last_desc) - edesc->desc.hdr |=3D DESC_HDR_MODE0_MDEU_PAD; - else - edesc->desc.hdr |=3D DESC_HDR_MODE0_MDEU_CONT; - - /* request SEC to INIT hash. */ - if (req_ctx->first_desc && !req_ctx->swinit) - edesc->desc.hdr |=3D DESC_HDR_MODE0_MDEU_INIT; + edesc =3D list_first_entry(&req_ctx->desc_list, struct talitos_edesc, + node); =20 - /* When the tfm context has a keylen, it's an HMAC. - * A first or last (ie. not middle) descriptor must request HMAC. - */ - if (ctx->keylen && (req_ctx->first_desc || req_ctx->last_desc)) - edesc->desc.hdr |=3D DESC_HDR_MODE0_MDEU_HMAC; + ret =3D talitos_submit(dev, ctx->ch, &edesc->desc, + is_sec1 ? sec1_ahash_done : sec2_ahash_done, areq); + if (ret !=3D -EINPROGRESS) + ahash_free_desc_list_from(areq, edesc); =20 - return common_nonsnoop_hash(edesc, req_ctx->areq, nbytes_to_hash, ahash_d= one); -} - -static void sec1_ahash_process_remaining(struct work_struct *work) -{ - struct talitos_ahash_req_ctx *req_ctx =3D - container_of(work, struct talitos_ahash_req_ctx, - sec1_ahash_process_remaining); - int err =3D 0; - - req_ctx->request_sl =3D scatterwalk_ffwd(req_ctx->request_bufsl, - req_ctx->request_sl, TALITOS1_MAX_DATA_LEN); - - if (req_ctx->remaining_ahash_request_bytes > TALITOS1_MAX_DATA_LEN) - req_ctx->current_ahash_request_bytes =3D TALITOS1_MAX_DATA_LEN; - else { - req_ctx->current_ahash_request_bytes =3D - req_ctx->remaining_ahash_request_bytes; - - if (req_ctx->last_request) - req_ctx->last_desc =3D 1; - } - - err =3D ahash_process_req_one(req_ctx->areq, - req_ctx->current_ahash_request_bytes); - - if (err !=3D -EINPROGRESS) - ahash_request_complete(req_ctx->areq, err); + return ret; } =20 static int ahash_process_req(struct ahash_request *areq, unsigned int nbyt= es) { - struct crypto_ahash *tfm =3D crypto_ahash_reqtfm(areq); - struct talitos_ctx *ctx =3D crypto_ahash_ctx(tfm); - struct device *dev =3D ctx->dev; - struct talitos_ahash_req_ctx *req_ctx =3D ahash_request_ctx(areq); - struct talitos_private *priv =3D dev_get_drvdata(dev); - bool is_sec1 =3D has_ftr_sec1(priv); - - req_ctx->areq =3D areq; - req_ctx->request_sl =3D areq->src; - req_ctx->remaining_ahash_request_bytes =3D nbytes; - - if (is_sec1) { - if (nbytes > TALITOS1_MAX_DATA_LEN) - nbytes =3D TALITOS1_MAX_DATA_LEN; - else if (req_ctx->last_request) - req_ctx->last_desc =3D 1; - } - - req_ctx->current_ahash_request_bytes =3D nbytes; - - return ahash_process_req_one(req_ctx->areq, - req_ctx->current_ahash_request_bytes); + return ahash_process_req_one(areq, nbytes); } =20 static int ahash_init(struct ahash_request *areq) @@ -2132,7 +2173,6 @@ static int ahash_init(struct ahash_request *areq) req_ctx->hw_context_size =3D size; req_ctx->last_request =3D 0; req_ctx->last_desc =3D 0; - INIT_WORK(&req_ctx->sec1_ahash_process_remaining, sec1_ahash_process_rema= ining); =20 dma =3D dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size, DMA_TO_DEVICE); diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h index 1a93ee355929..f6dbcf00e675 100644 --- a/drivers/crypto/talitos.h +++ b/drivers/crypto/talitos.h @@ -44,6 +44,12 @@ struct talitos_desc { =20 /* * talitos_edesc - s/w-extended descriptor + * @bufsl: scatterlist buffer + * @src: pointer to input scatterlist + * @node: list node for descriptor chaining + * @first: first descriptor of a chain + * @last: last descriptor of a chain + * * @src_nents: number of segments in input scatterlist * @dst_nents: number of segments in output scatterlist * @iv_dma: dma address of iv for checking continuity and link table @@ -58,6 +64,12 @@ struct talitos_desc { * of link_tbl data */ struct talitos_edesc { + struct scatterlist bufsl[2]; + struct scatterlist *src; + struct list_head node; + int first; + int last; + int src_nents; int dst_nents; dma_addr_t iv_dma; @@ -72,12 +84,14 @@ struct talitos_edesc { =20 /** * talitos_request - descriptor submission request + * @desc_chain: descriptor chain (SEC1) * @desc: descriptor pointer (kernel virtual) * @dma_desc: descriptor's physical bus address * @callback: whom to call when descriptor processing is done * @context: caller context (optional) */ struct talitos_request { + struct list_head *desc_chain; struct talitos_desc *desc; dma_addr_t dma_desc; void (*callback) (struct device *dev, struct talitos_desc *desc, --=20 2.53.0 From nobody Sun Jun 14 02:38:26 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85BC23E025C; Mon, 4 May 2026 15:39:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777909183; cv=none; b=Tx2I/PZ9KdOSUYX8gmNxSsFVClGJBHfl6avWWdIfCS2T51f9BU23Wz53QjNJBLCKu/O8BEAi8CEatN289A58m2NArgYEPvD1EAlbjUJghPbyMd0qNmJWW4oUACoEOKvJMlad4R1cbfMMNwo0/Z5anKGIqNzGDi+eV+mHB8diArc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777909183; c=relaxed/simple; bh=q4MZ+La159R2EqSHOQ0B8f2cDTsmyvN1X83sSLb5MKU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gteL/3qwitsqvEU4Yx33WLfztFescCty6rw8Ek8ceZ8L3l87GRDG2q4F/ii0goRjdEsr0ad3NREzsx+uW0VzbKrV02QfgWUdbNIYNTtZqsqLgn1KkV8tz4yBBNStOSoYkLfFDUuWiliTDf7CeZ3JGpiMoyYftOeN/a8BwpJiDBA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=rwoGylUq; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="rwoGylUq" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 2F5F44E42BB4; Mon, 4 May 2026 15:39:40 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 051AD5FD5F; Mon, 4 May 2026 15:39:40 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 0CD9211AD2BCC; Mon, 4 May 2026 17:39:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1777909178; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=31DNmP7BbqxxwmafcensuC/+auDTPsXFUOPjvKgF2Uw=; b=rwoGylUqCany6IvNRjSEGXmxM2siBJjAsaQSFzzj2S5eLnP4v1yK0fHMn2uMJ3n5GN5U+b L61sXjKaEmgAJY4CDU5ay0v6e8gDW6wSuyQezYyqTabLZE4yorIX6SdQTShplajC8Y6ojT gmueOPK8Q7BOR1xtqUZctQmNslir6pYWO/5o0fvqowJM80XDLTOqvdcYH2hB3JdOK6kqRs PoAwRifAHsG6d5/dW4i8//iAEmNd76FmAgxAb8WwRPfPQmlsbvXuYCEWKe0VyYLxJHOqxS MMAY8AqIVG5Udyu9grN1vnllB35DY8AJdJSEAkfZQ0IUOZlTvzrLWw7egOipmA== From: Paul Louvel Date: Mon, 04 May 2026 17:38:28 +0200 Subject: [PATCH 2/4] crypto: talitos - rename first_desc/last_desc to first_request/last_request Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-2-c97c641976f5@bootlin.com> References: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5@bootlin.com> In-Reply-To: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5@bootlin.com> To: Herbert Xu , "David S. Miller" , Paolo Abeni , David Howells , Kim Phillips Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Thomas Petazzoni , Herve Codina , Paul Louvel , Christophe Leroy , stable@vger.kernel.org X-Mailer: b4 0.15.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1777909177; l=4824; i=paul.louvel@bootlin.com; s=20260313; h=from:subject:message-id; bh=q4MZ+La159R2EqSHOQ0B8f2cDTsmyvN1X83sSLb5MKU=; b=GqMLY7uq3gAFs1VMtxAF6a/t/QIJZKiol7P3taZWogGNtXSIIPMKdH0IjjR79W8Wl9ozRrFh+ fwIKWKj+PEkAWAK//sS8Mc9wNp+/vSTJ11T/ZcQa+vp69DnEVRcfz1Z X-Developer-Key: i=paul.louvel@bootlin.com; a=ed25519; pk=eLW50NT18UAvUT5cAcYf88zNbBCZDLFXuptpyLVhVIU= X-Last-TLS-Session-Version: TLSv1.3 In talitos_ahash_req_ctx and talitos_export_state, the fields first_desc and last_desc describe request-level (not descriptor-level) state. Rename them to first_request and last_request for clarity. last_desc is also removed from talitos_ahash_req_ctx as it is no longer used. Cc: stable@vger.kernel.org Signed-off-by: Paul Louvel --- drivers/crypto/talitos.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 458a6a56d65b..6ada42d8aa32 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -954,8 +954,7 @@ struct talitos_ahash_req_ctx { u8 buf[2][HASH_MAX_BLOCK_SIZE]; int buf_idx; unsigned int swinit; - unsigned int first_desc; - unsigned int last_desc; + unsigned int first_request; unsigned int last_request; unsigned int to_hash_later; unsigned int nbuf; @@ -968,8 +967,8 @@ struct talitos_export_state { u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)]; u8 buf[HASH_MAX_BLOCK_SIZE]; unsigned int swinit; - unsigned int first_desc; - unsigned int last_desc; + unsigned int first_request; + unsigned int last_request; unsigned int to_hash_later; unsigned int nbuf; }; @@ -1830,7 +1829,7 @@ static void sec1_ahash_done(struct device *dev, struc= t talitos_desc *desc, struct talitos_ahash_req_ctx *req_ctx =3D ahash_request_ctx(context); struct ahash_request *areq =3D context; =20 - req_ctx->first_desc =3D 0; + req_ctx->first_request =3D 0; =20 ahash_free_desc_list_from(areq, list_first_entry(&req_ctx->desc_list, @@ -1855,7 +1854,7 @@ static void sec2_ahash_done(struct device *dev, struc= t talitos_desc *desc, struct talitos_edesc *edesc, *next; bool is_last; =20 - req_ctx->first_desc =3D 0; + req_ctx->first_request =3D 0; =20 edesc =3D container_of(desc, struct talitos_edesc, desc); is_last =3D edesc->last; @@ -1930,7 +1929,7 @@ static void common_nonsnoop_hash(struct talitos_edesc= *edesc, /* first DWORD empty */ =20 /* hash context in */ - if (!edesc->first || !req_ctx->first_desc || req_ctx->swinit) { + if (!edesc->first || !req_ctx->first_request || req_ctx->swinit) { map_single_talitos_ptr_nosync(dev, &desc->ptr[1], req_ctx->hw_context_size, req_ctx->hw_context, @@ -2036,14 +2035,14 @@ static int ahash_process_req_prepare(struct ahash_r= equest *areq, edesc->desc.hdr |=3D DESC_HDR_MODE0_MDEU_CONT; =20 /* request SEC to INIT hash. */ - if (req_ctx->first_desc && edesc->first && !req_ctx->swinit) + if (req_ctx->first_request && edesc->first && !req_ctx->swinit) edesc->desc.hdr |=3D DESC_HDR_MODE0_MDEU_INIT; =20 /* * When the tfm context has a keylen, it's an HMAC. * A first or last (ie. not middle) descriptor must request HMAC. */ - if (ctx->keylen && ((req_ctx->first_desc && edesc->first) || + if (ctx->keylen && ((req_ctx->first_request && edesc->first) || (req_ctx->last_request && edesc->last))) edesc->desc.hdr |=3D DESC_HDR_MODE0_MDEU_HMAC; =20 @@ -2165,14 +2164,13 @@ static int ahash_init(struct ahash_request *areq) /* Initialize the context */ req_ctx->buf_idx =3D 0; req_ctx->nbuf =3D 0; - req_ctx->first_desc =3D 1; /* first_desc indicates h/w must init its cont= ext */ + req_ctx->first_request =3D 1; req_ctx->swinit =3D 0; /* assume h/w init of context */ size =3D (crypto_ahash_digestsize(tfm) <=3D SHA256_DIGEST_SIZE) ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512; req_ctx->hw_context_size =3D size; req_ctx->last_request =3D 0; - req_ctx->last_desc =3D 0; =20 dma =3D dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size, DMA_TO_DEVICE); @@ -2264,8 +2262,8 @@ static int ahash_export(struct ahash_request *areq, v= oid *out) req_ctx->hw_context_size); memcpy(export->buf, req_ctx->buf[req_ctx->buf_idx], req_ctx->nbuf); export->swinit =3D req_ctx->swinit; - export->first_desc =3D req_ctx->first_desc; - export->last_desc =3D req_ctx->last_desc; + export->first_request =3D req_ctx->first_request; + export->last_request =3D req_ctx->last_request; export->to_hash_later =3D req_ctx->to_hash_later; export->nbuf =3D req_ctx->nbuf; =20 @@ -2290,8 +2288,8 @@ static int ahash_import(struct ahash_request *areq, c= onst void *in) memcpy(req_ctx->hw_context, export->hw_context, size); memcpy(req_ctx->buf[0], export->buf, export->nbuf); req_ctx->swinit =3D export->swinit; - req_ctx->first_desc =3D export->first_desc; - req_ctx->last_desc =3D export->last_desc; + req_ctx->first_request =3D export->first_request; + req_ctx->last_request =3D export->last_request; req_ctx->to_hash_later =3D export->to_hash_later; req_ctx->nbuf =3D export->nbuf; =20 --=20 2.53.0 From nobody Sun Jun 14 02:38:26 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 972DF3E0251; Mon, 4 May 2026 15:39:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777909184; cv=none; b=iNt8dpcp4FWS6Ji074hoF0HK5kQ7pFCMCF8RLpv5/VI5pTUVn5vZY0KVX+a5stZ++V4kO7i/WHR2GB3DAdCDz+s+o5ln7BSsiyjbGsW3fdGlqg2806KEubp85U8y9sOMndsC1oAOynlxzyTJxmkdQ4KoZcSiDl9e4ZI+RoTcvl8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777909184; c=relaxed/simple; bh=wXA66UJbIpzCtYdtcAzvfSpEKu6C0MJtApWKi6F4YDw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WKEyjSOjNOSqNmTy3WDI/uedKn9U9M7H7tSEUb/SJ8kXLNqePE1va3e+uLjFmMRLbzKioUBZyF+0z7Mkw5tVdGni9jyAZZO9MURCXpawOOwL8u5LYTNlo90QQDS77WKo9AjYFg4c/fVMUkHIEKuyrSV7vTLJlnDco+z/c1T69cY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=hE2n0h+h; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="hE2n0h+h" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 48B3E1A350F; Mon, 4 May 2026 15:39:41 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 1F7F45FD5F; Mon, 4 May 2026 15:39:41 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 77AA611AD2BCD; Mon, 4 May 2026 17:39:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1777909180; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=uvBvHYQc9incdS4pyRWWg39JHb2lfMzCeMd1O03d4MU=; b=hE2n0h+h8wPjrWHv0ilOuElgq3KHEGllQ0NiWDSwf7ced0kGiaHaeP65NtB21xt9+ITwSW e7iOa91bcUwyjlKsuUJi159XmjoZcRvdRahgPA0ZWxUt/uuVRF5JwycGPDXIdYii7ssFDw NQLRVrjC1CgzcXOlS723LFh9X0vyi+DRdASzQfjEORdVXs2u2ayxDQdbb1ammNwFARkQfV JMPMJ7dYvAAvK1Prz2oVpEsspm8+pn7v9IWuBK8kzvcZk1AsrUVq0VBdaOx6yyWDzWTHSe zA+EuZjaWUzv8OKJVj6dlSgSqACmfIiU9FwTC9xeUXFzLGZ+xsTdICqRMjS1vQ== From: Paul Louvel Date: Mon, 04 May 2026 17:38:29 +0200 Subject: [PATCH 3/4] crypto: talitos - remove useless wrapper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-3-c97c641976f5@bootlin.com> References: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5@bootlin.com> In-Reply-To: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5@bootlin.com> To: Herbert Xu , "David S. Miller" , Paolo Abeni , David Howells , Kim Phillips Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Thomas Petazzoni , Herve Codina , Paul Louvel , Christophe Leroy , stable@vger.kernel.org X-Mailer: b4 0.15.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1777909177; l=1332; i=paul.louvel@bootlin.com; s=20260313; h=from:subject:message-id; bh=wXA66UJbIpzCtYdtcAzvfSpEKu6C0MJtApWKi6F4YDw=; b=8ca7UXY81DLfirE2MjD+496dbqAgpBfv/+Z7OYhyOE5WBf6N5LvBWIr0o+IbYYSW89QlqfNxQ OmVT20gym0fD5mhm+Le0WyX5J49pIUQ7hPHZRnDkxR+F/6W+/1v9vMq X-Developer-Key: i=paul.louvel@bootlin.com; a=ed25519; pk=eLW50NT18UAvUT5cAcYf88zNbBCZDLFXuptpyLVhVIU= X-Last-TLS-Session-Version: TLSv1.3 ahash_process_req() was a wrapper used in commit 655ef638a2bc ("crypto: talitos - fix SEC1 32k ahash request limitation"). Rename ahash_process_req_one() to ahash_process_req() and remove the wrapper. Cc: stable@vger.kernel.org Signed-off-by: Paul Louvel --- drivers/crypto/talitos.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 6ada42d8aa32..8d063ad5639c 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -2061,7 +2061,7 @@ static int ahash_process_req_prepare(struct ahash_req= uest *areq, return 0; } =20 -static int ahash_process_req_one(struct ahash_request *areq, unsigned int = nbytes) +static int ahash_process_req(struct ahash_request *areq, unsigned int nbyt= es) { struct crypto_ahash *tfm =3D crypto_ahash_reqtfm(areq); struct talitos_ctx *ctx =3D crypto_ahash_ctx(tfm); @@ -2147,11 +2147,6 @@ static int ahash_process_req_one(struct ahash_reques= t *areq, unsigned int nbytes return ret; } =20 -static int ahash_process_req(struct ahash_request *areq, unsigned int nbyt= es) -{ - return ahash_process_req_one(areq, nbytes); -} - static int ahash_init(struct ahash_request *areq) { struct crypto_ahash *tfm =3D crypto_ahash_reqtfm(areq); --=20 2.53.0 From nobody Sun Jun 14 02:38:26 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C907A3E0C51; Mon, 4 May 2026 15:39:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777909188; cv=none; b=orkOQ5HHhVufynHVR4y9B9a3dOSnv4aAGICJ1f5LPJJGjcKvUf5SFL6dJZb1y31MEPGeisL2/Zn+8HJLpH3vTA5niMWpH5h6HCQaD+kmE6T5SH61FSy6lm9ilCvwVWIgJ4KwWQyIG/DPQMrTLS35K3kodmGS1yiXLWTIbJrPnw0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777909188; c=relaxed/simple; bh=AEH4Fq0siKNTVEACtsyUHL32qVGD6A5nC1XUA2IdHZ0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HExGzM/i97AhBn9eg/TfvbEr9DiQCyccVys01eat/7iE8DOjHf8iG4zV6ow7RKmqhfjLotNYjQl3sujGqSITfRG7BvwFeSDxG2LIo6yvb8UVwI6MS0UAwuCzwVKC8VfE5x5swJ8P0ZWMICv/J/kpEuNgtFmQ4Zj1yb9U6DrDRNE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=mrK6vOjV; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="mrK6vOjV" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 751874E42BBC; Mon, 4 May 2026 15:39:42 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 4B8055FD5F; Mon, 4 May 2026 15:39:42 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9A97F11AD2BA5; Mon, 4 May 2026 17:39:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1777909181; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=bwhElTLpoPeu4nxk9VnwUqKbxxQ2g2S7oxle4dtyMlE=; b=mrK6vOjVS6tGJb24NxflSwNQeykZklcuChS8YtAMJByoV5PblLa1wXvv8RrvXnqqDQ3Q4a fxLVcw9ugnzZCcdT4NmNh1KKxJMim31NhhZNoXHY15vjWWtBW7h4iNYEYcaqxyonsKZXxr gFNoaPwg1ckpuH1DcAg7A5Ij9yQ4bO3O74rE/SlFnVlaKf26s5sqjaA891bs8rY/O+Ay7j +DBdMFEFanjki7x7DfZmirb6PuLEFqT3nkph/vrr/MIF4UJlljpD2xDGRmqIHlJ0cPMxdj 1lsSrFZOG5zj/M2VvnWp5Dz/wiwppiBdQlqp6/K/T2xaUEcYDjuGx9BdhRVyCQ== From: Paul Louvel Date: Mon, 04 May 2026 17:38:30 +0200 Subject: [PATCH 4/4] crypto: talitos - fix invalid submit_count initial value Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-4-c97c641976f5@bootlin.com> References: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5@bootlin.com> In-Reply-To: <20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5@bootlin.com> To: Herbert Xu , "David S. Miller" , Paolo Abeni , David Howells , Kim Phillips Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Thomas Petazzoni , Herve Codina , Paul Louvel , Christophe Leroy , stable@vger.kernel.org X-Mailer: b4 0.15.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1777909177; l=1086; i=paul.louvel@bootlin.com; s=20260313; h=from:subject:message-id; bh=AEH4Fq0siKNTVEACtsyUHL32qVGD6A5nC1XUA2IdHZ0=; b=ZksKLsqHf0MDCXf2RZ4SRYvim1JYyVXgEG/5XrffuuWSy6RL4NDlLzkUU94RaUvGsUXzP3Kc/ dV+xxTGxyWIB6wUP/qlshD0wnrzdA4tHhypXMP+PgXqvFzqgVRedX8n X-Developer-Key: i=paul.louvel@bootlin.com; a=ed25519; pk=eLW50NT18UAvUT5cAcYf88zNbBCZDLFXuptpyLVhVIU= X-Last-TLS-Session-Version: TLSv1.3 The submit_count atomic counter is initialized to -(chfifo_len - 1), but since atomic_inc_not_zero() rejects increments when the value is zero, one FIFO slot is always wasted. With chfifo_len =3D 24, only 23 descriptors can be submitted before getting -EAGAIN in talitos_submit(). Fix by initializing submit_count to -chfifo_len so that the counter reaches zero only after all chfifo_len slots are occupied. Cc: stable@vger.kernel.org Fixes: 4b99262881213 ("crypto: talitos - align locks on cache lines") Signed-off-by: Paul Louvel --- drivers/crypto/talitos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 8d063ad5639c..429db3ee9123 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -3575,7 +3575,7 @@ static int talitos_probe(struct platform_device *ofde= v) } =20 atomic_set(&priv->chan[i].submit_count, - -(priv->chfifo_len - 1)); + -priv->chfifo_len); } =20 dma_set_mask(dev, DMA_BIT_MASK(36)); --=20 2.53.0