]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Jul 2026 10:35:22 +0000 (12:35 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Jul 2026 10:35:22 +0000 (12:35 +0200)
added patches:
arm64-fpsimd-fix-type-mismatch-in-sme_-save-load-_state.patch
crypto-talitos-add-chaining-of-arbitrary-number-of-descriptor-for-the-sec1.patch
crypto-talitos-hash-drop-workqueue-mechanism-for-sec1.patch
crypto-talitos-hash-fix-sec2-64k-1-ahash-request-limitation.patch
crypto-talitos-hash-prepare-sec1-descriptor-chaining-remove-additional-descriptor.patch
crypto-talitos-hash-remove-useless-wrapper.patch
crypto-talitos-hash-rename-first_desc-last_desc-to-first_request-last_request.patch
crypto-talitos-hash-use-descriptor-chaining-for-sec1-instead-of-workqueue.patch
crypto-talitos-move-code-in-current_desc_hdr-into-a-standalone-function.patch
crypto-talitos-move-dma-mapping-code-in-talitos_submit-into-a-standalone-dma_map_request-function.patch
crypto-talitos-move-dma-unmapping-code-in-flush_channel-into-a-standalone-dma_unmap_request-function.patch
crypto-talitos-use-dma_sync_single_for_cpu-before-reading-descriptor-header.patch
edac-i10nm-don-t-fail-probing-if-adxl-is-missing.patch
i2c-core-fix-hang-on-adapter-registration-failure.patch
regulator-scmi-fix-of_node-refcount-leak-in-scmi_regulator_probe.patch
spi-fsl-lpspi-replace-dmaengine_terminate_all-with-dmaengine_terminate_sync.patch
spi-fsl-lpspi-terminate-the-rx-channel-on-tx-prepare-failure-path.patch
watchdog-apple-add-apple-t8103-wdt-compatible.patch
x86-mm-fix-freeing-of-pmd-sized-vmemmap-pages.patch

20 files changed:
queue-6.18/arm64-fpsimd-fix-type-mismatch-in-sme_-save-load-_state.patch [new file with mode: 0644]
queue-6.18/crypto-talitos-add-chaining-of-arbitrary-number-of-descriptor-for-the-sec1.patch [new file with mode: 0644]
queue-6.18/crypto-talitos-hash-drop-workqueue-mechanism-for-sec1.patch [new file with mode: 0644]
queue-6.18/crypto-talitos-hash-fix-sec2-64k-1-ahash-request-limitation.patch [new file with mode: 0644]
queue-6.18/crypto-talitos-hash-prepare-sec1-descriptor-chaining-remove-additional-descriptor.patch [new file with mode: 0644]
queue-6.18/crypto-talitos-hash-remove-useless-wrapper.patch [new file with mode: 0644]
queue-6.18/crypto-talitos-hash-rename-first_desc-last_desc-to-first_request-last_request.patch [new file with mode: 0644]
queue-6.18/crypto-talitos-hash-use-descriptor-chaining-for-sec1-instead-of-workqueue.patch [new file with mode: 0644]
queue-6.18/crypto-talitos-move-code-in-current_desc_hdr-into-a-standalone-function.patch [new file with mode: 0644]
queue-6.18/crypto-talitos-move-dma-mapping-code-in-talitos_submit-into-a-standalone-dma_map_request-function.patch [new file with mode: 0644]
queue-6.18/crypto-talitos-move-dma-unmapping-code-in-flush_channel-into-a-standalone-dma_unmap_request-function.patch [new file with mode: 0644]
queue-6.18/crypto-talitos-use-dma_sync_single_for_cpu-before-reading-descriptor-header.patch [new file with mode: 0644]
queue-6.18/edac-i10nm-don-t-fail-probing-if-adxl-is-missing.patch [new file with mode: 0644]
queue-6.18/i2c-core-fix-hang-on-adapter-registration-failure.patch [new file with mode: 0644]
queue-6.18/regulator-scmi-fix-of_node-refcount-leak-in-scmi_regulator_probe.patch [new file with mode: 0644]
queue-6.18/series
queue-6.18/spi-fsl-lpspi-replace-dmaengine_terminate_all-with-dmaengine_terminate_sync.patch [new file with mode: 0644]
queue-6.18/spi-fsl-lpspi-terminate-the-rx-channel-on-tx-prepare-failure-path.patch [new file with mode: 0644]
queue-6.18/watchdog-apple-add-apple-t8103-wdt-compatible.patch [new file with mode: 0644]
queue-6.18/x86-mm-fix-freeing-of-pmd-sized-vmemmap-pages.patch [new file with mode: 0644]

diff --git a/queue-6.18/arm64-fpsimd-fix-type-mismatch-in-sme_-save-load-_state.patch b/queue-6.18/arm64-fpsimd-fix-type-mismatch-in-sme_-save-load-_state.patch
new file mode 100644 (file)
index 0000000..5fbc256
--- /dev/null
@@ -0,0 +1,78 @@
+From 247bd153905085c18ff9006cca1ccb96dfd18e7f Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Wed, 3 Jun 2026 12:06:12 +0100
+Subject: arm64: fpsimd: Fix type mismatch in sme_{save,load}_state()
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit 247bd153905085c18ff9006cca1ccb96dfd18e7f upstream.
+
+The sme_save_state() and sme_load_state() functions take a 32-bit int
+argument that describes whether to save/restore ZT0. Their assembly
+implementations consume the entire 64-bit register containing this
+32-bit value, and will attempt to save/restore ZT0 if any bit of
+that 64-bit register is non-zero.
+
+Per the AAPCS64 parameter passing rules, the callee is responsible for
+any necessary widening, and the upper 32-bits are permitted to contain
+arbitrary values. If the upper 32 bits are non-zero, this could result
+in an unexpected attempt to save/restore ZT0, and consequently could
+lead to unexpected traps/undefs/faults.
+
+In practice compilers are very unlikely to generate code where the upper
+32-bits would be non-zero, but they are permitted to do so.
+
+Fix this by only consuming the low 32 bits of the register, and update
+comments accordingly.
+
+Fixes: 95fcec713259 ("arm64/sme: Implement context switching for ZT0")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Fuad Tabba <tabba@google.com>
+Cc: James Morse <james.morse@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Oliver Upton <oupton@kernel.org>
+Cc: Vladimir Murzin <vladimir.murzin@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kernel/entry-fpsimd.S |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/arm64/kernel/entry-fpsimd.S
++++ b/arch/arm64/kernel/entry-fpsimd.S
+@@ -103,13 +103,13 @@ SYM_FUNC_END(sme_set_vq)
+  * Save the ZA and ZT state
+  *
+  * x0 - pointer to buffer for state
+- * x1 - number of ZT registers to save
++ * w1 - number of ZT registers to save
+  */
+ SYM_FUNC_START(sme_save_state)
+       _sme_rdsvl      2, 1            // x2 = VL/8
+       sme_save_za 0, x2, 12           // Leaves x0 pointing to the end of ZA
+-      cbz     x1, 1f
++      cbz     w1, 1f
+       _str_zt 0
+ 1:
+       ret
+@@ -119,13 +119,13 @@ SYM_FUNC_END(sme_save_state)
+  * Load the ZA and ZT state
+  *
+  * x0 - pointer to buffer for state
+- * x1 - number of ZT registers to save
++ * w1 - number of ZT registers to save
+  */
+ SYM_FUNC_START(sme_load_state)
+       _sme_rdsvl      2, 1            // x2 = VL/8
+       sme_load_za 0, x2, 12           // Leaves x0 pointing to the end of ZA
+-      cbz     x1, 1f
++      cbz     w1, 1f
+       _ldr_zt 0
+ 1:
+       ret
diff --git a/queue-6.18/crypto-talitos-add-chaining-of-arbitrary-number-of-descriptor-for-the-sec1.patch b/queue-6.18/crypto-talitos-add-chaining-of-arbitrary-number-of-descriptor-for-the-sec1.patch
new file mode 100644 (file)
index 0000000..98c3fc2
--- /dev/null
@@ -0,0 +1,352 @@
+From f126384ed55279c3b676f89d5ab547b8de8df782 Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:48 +0200
+Subject: crypto: talitos - add chaining of arbitrary number of descriptor for the SEC1
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit f126384ed55279c3b676f89d5ab547b8de8df782 upstream.
+
+The SEC1 hardware can process a chain of descriptors without host
+intervention. Only the hash implementation currently use this feature,
+but with a chain of at most 2 descriptors added in commit 37b5e8897eb5
+("crypto: talitos - chain in buffered data for ahash on SEC1").
+
+Add supports for chaining an arbitrary number of descriptors in a chain.
+
+Adapt the ahash implementation to make it compatible.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c |  180 +++++++++++++++++++++++++++++++----------------
+ drivers/crypto/talitos.h |    2 
+ 2 files changed, 124 insertions(+), 58 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -273,7 +273,10 @@ static int talitos_submit(struct device
+                                          void *context, int error),
+                         void *context)
+ {
++      struct talitos_edesc *edesc = container_of(desc, struct talitos_edesc, desc);
+       struct talitos_private *priv = dev_get_drvdata(dev);
++      dma_addr_t dma_desc, prev_dma_desc;
++      struct talitos_edesc *prev_edesc = NULL;
+       struct talitos_request *request;
+       unsigned long flags;
+       int head;
+@@ -292,10 +295,31 @@ static int talitos_submit(struct device
+       /* map descriptor and save caller data */
+       if (is_sec1) {
+-              desc->hdr1 = desc->hdr;
+-              request->dma_desc = dma_map_single(dev, &desc->hdr1,
++              while (edesc) {
++                      edesc->desc.hdr1 = edesc->desc.hdr;
++
++                      dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
++                                                TALITOS_DESC_SIZE,
++                                                DMA_BIDIRECTIONAL);
++
++                      if (!prev_edesc) {
++                              request->dma_desc = dma_desc;
++                              goto next;
++                      }
++
++                      /* Chain in any previous descriptors. */
++
++                      prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
++
++                      dma_sync_single_for_device(dev, prev_dma_desc,
+                                                  TALITOS_DESC_SIZE,
+-                                                 DMA_BIDIRECTIONAL);
++                                                 DMA_TO_DEVICE);
++
++next:
++                      prev_edesc = edesc;
++                      prev_dma_desc = dma_desc;
++                      edesc = edesc->next_desc;
++              }
+       } else {
+               request->dma_desc = dma_map_single(dev, desc,
+                                                  TALITOS_DESC_SIZE,
+@@ -326,6 +350,7 @@ static __be32 get_request_hdr(struct dev
+                             struct talitos_request *request, bool is_sec1)
+ {
+       struct talitos_edesc *edesc;
++      dma_addr_t dma_desc;
+       if (!is_sec1) {
+               dma_sync_single_for_cpu(dev, request->dma_desc,
+@@ -334,19 +359,17 @@ static __be32 get_request_hdr(struct dev
+               return request->desc->hdr;
+       }
+-      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);
+-
+-              return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))
+-                      ->hdr1;
++      edesc = container_of(request->desc, struct talitos_edesc, desc);
++      dma_desc = request->dma_desc;
++      while (edesc->next_desc) {
++              dma_desc = be32_to_cpu(edesc->desc.next_desc);
++              edesc = edesc->next_desc;
+       }
++
++      dma_sync_single_for_cpu(dev, dma_desc, TALITOS_DESC_SIZE,
++                              DMA_BIDIRECTIONAL);
++
++      return edesc->desc.hdr1;
+ }
+ /*
+@@ -356,6 +379,7 @@ static void flush_channel(struct device
+ {
+       struct talitos_private *priv = dev_get_drvdata(dev);
+       struct talitos_request *request, saved_req;
++      struct talitos_edesc *edesc;
+       unsigned long flags;
+       int tail, status;
+       bool is_sec1 = has_ftr_sec1(priv);
+@@ -380,9 +404,22 @@ static void flush_channel(struct device
+                       else
+                               status = error;
+-              dma_unmap_single(dev, request->dma_desc,
+-                               TALITOS_DESC_SIZE,
+-                               DMA_BIDIRECTIONAL);
++              if (is_sec1) {
++                      dma_unmap_single(dev, request->dma_desc,
++                                       TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
++                      edesc = container_of(request->desc,
++                                           struct talitos_edesc, desc);
++                      while (edesc->next_desc) {
++                              dma_unmap_single(
++                                      dev, be32_to_cpu(edesc->desc.next_desc),
++                                      TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
++                              edesc = edesc->next_desc;
++                      }
++              } else {
++                      dma_unmap_single(dev, request->dma_desc,
++                                      TALITOS_DESC_SIZE,
++                                      DMA_BIDIRECTIONAL);
++              }
+               /* copy entries so we can call callback outside lock */
+               saved_req.desc = request->desc;
+@@ -477,8 +514,12 @@ DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH
+ static __be32 current_desc_hdr(struct device *dev, int ch)
+ {
+       struct talitos_private *priv = dev_get_drvdata(dev);
++      bool is_sec1 = has_ftr_sec1(priv);
++      struct talitos_request *request;
++      struct talitos_edesc *edesc;
+       int tail, iter;
+       dma_addr_t cur_desc;
++      __be32 hdr = 0;
+       cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32;
+       cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
+@@ -489,27 +530,35 @@ static __be32 current_desc_hdr(struct de
+       }
+       tail = priv->chan[ch].tail;
+-
+       iter = tail;
+-      while (priv->chan[ch].fifo[iter].dma_desc != cur_desc &&
+-             priv->chan[ch].fifo[iter].desc->next_desc != cpu_to_be32(cur_desc)) {
+-              iter = (iter + 1) & (priv->fifo_len - 1);
+-              if (iter == tail) {
+-                      dev_err(dev, "couldn't locate current descriptor\n");
+-                      return 0;
++      do {
++              request = &priv->chan[ch].fifo[iter];
++
++              if (request->dma_desc == cur_desc) {
++                      hdr = request->desc->hdr;
++              } else if (is_sec1) {
++                      edesc = container_of(request->desc,
++                                           struct talitos_edesc, desc);
++                      while (edesc->next_desc) {
++                              if (edesc->desc.next_desc ==
++                                  cpu_to_be32(cur_desc)) {
++                                      hdr = edesc->next_desc->desc.hdr1;
++                                      break;
++                              }
++                              edesc = edesc->next_desc;
++                      }
+               }
+-      }
+-      if (priv->chan[ch].fifo[iter].desc->next_desc == cpu_to_be32(cur_desc)) {
+-              struct talitos_edesc *edesc;
++              if (hdr)
++                      break;
+-              edesc = container_of(priv->chan[ch].fifo[iter].desc,
+-                                   struct talitos_edesc, desc);
+-              return ((struct talitos_desc *)
+-                      (edesc->buf + edesc->dma_len))->hdr;
+-      }
++              iter = (iter + 1) & (priv->fifo_len - 1);
++      } while (iter != tail);
++
++      if (!hdr)
++              dev_err(dev, "couldn't locate current descriptor\n");
+-      return priv->chan[ch].fifo[iter].desc->hdr;
++      return hdr;
+ }
+ /*
+@@ -1408,10 +1457,6 @@ static struct talitos_edesc *talitos_ede
+               dma_len = 0;
+       }
+       alloc_len += 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 += sizeof(struct talitos_desc);
+       alloc_len += ivsize;
+       edesc = kmalloc(ALIGN(alloc_len, dma_get_cache_alignment()), flags);
+@@ -1427,6 +1472,7 @@ static struct talitos_edesc *talitos_ede
+       edesc->dst_nents = dst_nents;
+       edesc->iv_dma = iv_dma;
+       edesc->dma_len = dma_len;
++      edesc->next_desc = NULL;
+       if (dma_len)
+               edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
+                                                    edesc->dma_len,
+@@ -1727,8 +1773,10 @@ static void common_nonsnoop_hash_unmap(s
+       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 = (struct talitos_desc *)
+-                                   (edesc->buf + edesc->dma_len);
++      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 &&
+@@ -1756,10 +1804,17 @@ static void common_nonsnoop_hash_unmap(s
+       if (edesc->dma_len)
+               dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
+                                DMA_BIDIRECTIONAL);
++}
+-      if (desc->next_desc)
+-              dma_unmap_single(dev, be32_to_cpu(desc->next_desc),
+-                               TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
++static void free_edesc_list_from(struct talitos_edesc *edesc)
++{
++      struct talitos_edesc *next;
++
++      while (edesc) {
++              next = edesc->next_desc;
++              kfree(edesc);
++              edesc = next;
++      }
+ }
+ static void ahash_done(struct device *dev,
+@@ -1778,7 +1833,7 @@ static void ahash_done(struct device *de
+       }
+       common_nonsnoop_hash_unmap(dev, edesc, areq);
+-      kfree(edesc);
++      free_edesc_list_from(edesc);
+       if (err) {
+               ahash_request_complete(areq, err);
+@@ -1894,14 +1949,23 @@ static int common_nonsnoop_hash(struct t
+               talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
+       if (is_sec1 && req_ctx->nbuf && length) {
+-              struct talitos_desc *desc2 = (struct talitos_desc *)
+-                                           (edesc->buf + edesc->dma_len);
+-              dma_addr_t next_desc;
++              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;
+-              memset(desc2, 0, sizeof(*desc2));
+               desc2->hdr = desc->hdr;
+               desc2->hdr &= ~DESC_HDR_MODE0_MDEU_INIT;
+-              desc2->hdr1 = desc2->hdr;
+               desc->hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
+               desc->hdr |= DESC_HDR_MODE0_MDEU_CONT;
+               desc->hdr &= ~DESC_HDR_DONE_NOTIFY;
+@@ -1925,21 +1989,21 @@ static int common_nonsnoop_hash(struct t
+                                                     req_ctx->hw_context_size,
+                                                     req_ctx->hw_context,
+                                                     DMA_FROM_DEVICE);
+-
+-              next_desc = dma_map_single(dev, &desc2->hdr1, TALITOS_DESC_SIZE,
+-                                         DMA_BIDIRECTIONAL);
+-              desc->next_desc = cpu_to_be32(next_desc);
+       }
+       if (sync_needed)
+               dma_sync_single_for_device(dev, edesc->dma_link_tbl,
+                                          edesc->dma_len, DMA_BIDIRECTIONAL);
+-      ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
+-      if (ret != -EINPROGRESS) {
+-              common_nonsnoop_hash_unmap(dev, edesc, areq);
+-              kfree(edesc);
+-      }
++      ret = talitos_submit(dev, ctx->ch, desc, callback,
++                           areq);
++      if (ret != -EINPROGRESS)
++              goto err;
++
++      return -EINPROGRESS;
++err:
++      common_nonsnoop_hash_unmap(dev, edesc, areq);
++      kfree(edesc);
+       return ret;
+ }
+--- a/drivers/crypto/talitos.h
++++ b/drivers/crypto/talitos.h
+@@ -49,6 +49,7 @@ struct talitos_desc {
+  * @iv_dma: dma address of iv for checking continuity and link table
+  * @dma_len: length of dma mapped link_tbl space
+  * @dma_link_tbl: bus physical address of link_tbl/buf
++ * @next_desc: next descriptor
+  * @desc: h/w descriptor
+  * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2)
+  * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1)
+@@ -63,6 +64,7 @@ struct talitos_edesc {
+       dma_addr_t iv_dma;
+       int dma_len;
+       dma_addr_t dma_link_tbl;
++      struct talitos_edesc *next_desc;
+       struct talitos_desc desc;
+       union {
+               DECLARE_FLEX_ARRAY(struct talitos_ptr, link_tbl);
diff --git a/queue-6.18/crypto-talitos-hash-drop-workqueue-mechanism-for-sec1.patch b/queue-6.18/crypto-talitos-hash-drop-workqueue-mechanism-for-sec1.patch
new file mode 100644 (file)
index 0000000..00bcf06
--- /dev/null
@@ -0,0 +1,173 @@
+From be4802afb1700534e48cb776d0d1e772c27de130 Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:54 +0200
+Subject: crypto: talitos/hash - drop workqueue mechanism for SEC1
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit be4802afb1700534e48cb776d0d1e772c27de130 upstream.
+
+Now that SEC1 hash uses hardware descriptor chaining instead of a
+workqueue to process requests exceeding TALITOS1_MAX_DATA_LEN, the
+workqueue code is no longer needed.
+
+Remove sec1_ahash_process_remaining(), the related fields from
+talitos_ahash_req_ctx (request_bufsl, areq, request_sl,
+remaining_ahash_request_bytes, current_ahash_request_bytes,
+sec1_ahash_process_remaining), the dead code in ahash_done(), and
+simplify ahash_process_req() to call ahash_process_req_one() directly
+with the original areq->src and areq->nbytes.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c |   80 ++++-------------------------------------------
+ 1 file changed, 7 insertions(+), 73 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -12,7 +12,6 @@
+  * All rights reserved.
+  */
+-#include <linux/workqueue.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/mod_devicetable.h>
+@@ -952,13 +951,6 @@ struct talitos_ahash_req_ctx {
+       unsigned int nbuf;
+       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;
+ };
+ struct talitos_export_state {
+@@ -1840,18 +1832,6 @@ static void ahash_done(struct device *de
+       free_edesc_list_from(areq, edesc);
+       ahash_request_complete(areq, err);
+-
+-      return;
+-
+-      req_ctx->remaining_ahash_request_bytes -=
+-              req_ctx->current_ahash_request_bytes;
+-
+-      if (!req_ctx->remaining_ahash_request_bytes) {
+-              ahash_request_complete(areq, 0);
+-              return;
+-      }
+-
+-      schedule_work(&req_ctx->sec1_ahash_process_remaining);
+ }
+ /*
+@@ -2044,12 +2024,12 @@ static int ahash_process_req_one(struct
+       if (!req_ctx->last_request && (nbytes + req_ctx->nbuf <= blocksize)) {
+               /* Buffer up to one whole block */
+-              nents = sg_nents_for_len(req_ctx->request_sl, nbytes);
++              nents = 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 += nbytes;
+               return 0;
+@@ -2076,18 +2056,18 @@ static int ahash_process_req_one(struct
+               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 = req_ctx->bufsl;
+       } else
+-              req_ctx->psrc = req_ctx->request_sl;
++              req_ctx->psrc = areq->src;
+       if (to_hash_later) {
+-              nents = sg_nents_for_len(req_ctx->request_sl, nbytes);
++              nents = 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);
+@@ -2106,54 +2086,9 @@ static int ahash_process_req_one(struct
+       return ret;
+ }
+-static void sec1_ahash_process_remaining(struct work_struct *work)
+-{
+-      struct talitos_ahash_req_ctx *req_ctx =
+-              container_of(work, struct talitos_ahash_req_ctx,
+-                           sec1_ahash_process_remaining);
+-      int err = 0;
+-
+-      req_ctx->request_sl = 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 = TALITOS1_MAX_DATA_LEN;
+-      else {
+-              req_ctx->current_ahash_request_bytes =
+-                      req_ctx->remaining_ahash_request_bytes;
+-
+-              if (req_ctx->last_request)
+-                      req_ctx->last_desc = 1;
+-      }
+-
+-      err = ahash_process_req_one(req_ctx->areq,
+-                                  req_ctx->current_ahash_request_bytes);
+-
+-      if (err != -EINPROGRESS)
+-              ahash_request_complete(req_ctx->areq, err);
+-}
+-
+ static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
+ {
+-      struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+-      struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+-      struct device *dev = ctx->dev;
+-      struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+-      struct talitos_private *priv = dev_get_drvdata(dev);
+-      bool is_sec1 = has_ftr_sec1(priv);
+-
+-      req_ctx->areq = areq;
+-      req_ctx->request_sl = areq->src;
+-      req_ctx->remaining_ahash_request_bytes = nbytes;
+-
+-      if (is_sec1) {
+-              if (req_ctx->last_request)
+-                      req_ctx->last_desc = 1;
+-      }
+-
+-      req_ctx->current_ahash_request_bytes = nbytes;
+-
+-      return ahash_process_req_one(req_ctx->areq, nbytes);
++      return ahash_process_req_one(areq, nbytes);
+ }
+ static int ahash_init(struct ahash_request *areq)
+@@ -2176,7 +2111,6 @@ static int ahash_init(struct ahash_reque
+       req_ctx->hw_context_size = size;
+       req_ctx->last_request = 0;
+       req_ctx->last_desc = 0;
+-      INIT_WORK(&req_ctx->sec1_ahash_process_remaining, sec1_ahash_process_remaining);
+       dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
+                            DMA_TO_DEVICE);
diff --git a/queue-6.18/crypto-talitos-hash-fix-sec2-64k-1-ahash-request-limitation.patch b/queue-6.18/crypto-talitos-hash-fix-sec2-64k-1-ahash-request-limitation.patch
new file mode 100644 (file)
index 0000000..3d95ebd
--- /dev/null
@@ -0,0 +1,95 @@
+From 6e12daff6ec125102a6fdcafc5aa7199f7ce8933 Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:57 +0200
+Subject: crypto: talitos/hash - fix SEC2 64k - 1 ahash request limitation
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit 6e12daff6ec125102a6fdcafc5aa7199f7ce8933 upstream.
+
+The problem described in commit 655ef638a2bc ("crypto: talitos - fix
+SEC1 32k ahash request limitation") also apply for the SEC2 hardware,
+but with a limitation of 64k - 1 bytes.
+
+Split ahash_done() into SEC1 and SEC2 paths: SEC1 continues to free the
+whole descriptor list at once, while SEC2 now iterates through
+descriptors one by one, submitting the next only after the previous
+completes, which is required since SEC2 cannot chain descriptors in
+hardware.
+
+Cc: stable@vger.kernel.org
+Fixes: c662b043cdca ("crypto: af_alg/hash: Support MSG_SPLICE_PAGES")
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c |   49 ++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 40 insertions(+), 9 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -1820,16 +1820,46 @@ static void ahash_done(struct device *de
+       struct talitos_edesc *edesc =
+                container_of(desc, struct talitos_edesc, desc);
+       struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
++      struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++      bool is_sec1 = has_ftr_sec1(dev_get_drvdata(dev));
++      struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
++      struct talitos_edesc *next;
+-      if (!req_ctx->last_request && req_ctx->to_hash_later) {
+-              /* Position any partial block for next update/final/finup */
+-              req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
+-              req_ctx->nbuf = req_ctx->to_hash_later;
++      if (is_sec1) {
++              if (!req_ctx->last_request && req_ctx->to_hash_later) {
++                      /* Position any partial block for next update/final/finup */
++                      req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
++                      req_ctx->nbuf = req_ctx->to_hash_later;
++              }
++
++              free_edesc_list_from(areq, edesc);
++              ahash_request_complete(areq, err);
++      } else {
++              next = edesc->next_desc;
++
++              common_nonsnoop_hash_unmap(dev, edesc, areq);
++              kfree(edesc);
++
++              if (err)
++                      goto out;
++
++              if (next) {
++                      err = talitos_submit(dev, ctx->ch, &next->desc,
++                                           ahash_done, areq);
++                      if (err != -EINPROGRESS)
++                              goto out;
++                      return;
++              }
++out:
++              if (!req_ctx->last_request && req_ctx->to_hash_later) {
++                      /* Position any partial block for next update/final/finup */
++                      req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
++                      req_ctx->nbuf = req_ctx->to_hash_later;
++              }
++              if (err && next)
++                      free_edesc_list_from(areq, next);
++              ahash_request_complete(areq, err);
+       }
+-
+-      free_edesc_list_from(areq, edesc);
+-
+-      ahash_request_complete(areq, err);
+ }
+ /*
+@@ -1940,7 +1970,8 @@ ahash_process_req_prepare(struct ahash_r
+       struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
+       struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+       struct talitos_edesc *first = NULL, *prev_edesc = NULL, *edesc;
+-      size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN : SIZE_MAX;
++      size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN :
++                                  TALITOS2_MAX_DATA_LEN;
+       struct scatterlist tmp[2];
+       size_t to_hash_this_desc;
+       struct scatterlist *src;
diff --git a/queue-6.18/crypto-talitos-hash-prepare-sec1-descriptor-chaining-remove-additional-descriptor.patch b/queue-6.18/crypto-talitos-hash-prepare-sec1-descriptor-chaining-remove-additional-descriptor.patch
new file mode 100644 (file)
index 0000000..999fc9b
--- /dev/null
@@ -0,0 +1,196 @@
+From 59b5d899e33701665f18abe6bebf987427876e3e Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:52 +0200
+Subject: crypto: talitos/hash - prepare SEC1 descriptor chaining, remove additional descriptor
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit 59b5d899e33701665f18abe6bebf987427876e3e upstream.
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c |  101 ++---------------------------------------------
+ 1 file changed, 6 insertions(+), 95 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -1788,15 +1788,9 @@ static void common_nonsnoop_hash_unmap(s
+       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(s
+       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 t
+               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 t
+       /*
+        * 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 t
+       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
+       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
+       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
+       }
+       /* 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;
diff --git a/queue-6.18/crypto-talitos-hash-remove-useless-wrapper.patch b/queue-6.18/crypto-talitos-hash-remove-useless-wrapper.patch
new file mode 100644 (file)
index 0000000..919fa03
--- /dev/null
@@ -0,0 +1,44 @@
+From 907ae6088c82c9abae2d26477fddd60df6ad003b Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:56 +0200
+Subject: crypto: talitos/hash - remove useless wrapper
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit 907ae6088c82c9abae2d26477fddd60df6ad003b upstream.
+
+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 <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c |    7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -2003,7 +2003,7 @@ ahash_process_req_prepare(struct ahash_r
+       return first;
+ }
+-static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes)
++static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
+ {
+       struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+       struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+@@ -2084,11 +2084,6 @@ static int ahash_process_req_one(struct
+       return ret;
+ }
+-static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
+-{
+-      return ahash_process_req_one(areq, nbytes);
+-}
+-
+ static int ahash_init(struct ahash_request *areq)
+ {
+       struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
diff --git a/queue-6.18/crypto-talitos-hash-rename-first_desc-last_desc-to-first_request-last_request.patch b/queue-6.18/crypto-talitos-hash-rename-first_desc-last_desc-to-first_request-last_request.patch
new file mode 100644 (file)
index 0000000..2932246
--- /dev/null
@@ -0,0 +1,129 @@
+From 8bcf00671400ac3b3a4cc3011e6c1496dbd880fd Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:55 +0200
+Subject: crypto: talitos/hash - rename first_desc/last_desc to first_request/last_request
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit 8bcf00671400ac3b3a4cc3011e6c1496dbd880fd upstream.
+
+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 <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c |   29 +++++++++++++----------------
+ 1 file changed, 13 insertions(+), 16 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -944,8 +944,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;
+@@ -957,8 +956,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;
+ };
+@@ -1822,8 +1821,7 @@ static void ahash_done(struct device *de
+                container_of(desc, struct talitos_edesc, desc);
+       struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+-
+-      if (!req_ctx->last_desc && req_ctx->to_hash_later) {
++      if (!req_ctx->last_request && req_ctx->to_hash_later) {
+               /* Position any partial block for next update/final/finup */
+               req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
+               req_ctx->nbuf = req_ctx->to_hash_later;
+@@ -1872,7 +1870,7 @@ static void common_nonsnoop_hash(struct
+       /* first DWORD empty */
+       /* 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,
+@@ -1880,7 +1878,7 @@ static void common_nonsnoop_hash(struct
+               req_ctx->swinit = 0;
+       }
+       /* Indicate next op is not the first. */
+-      req_ctx->first_desc = 0;
++      req_ctx->first_request = 0;
+       /* HMAC key */
+       if (ctx->keylen)
+@@ -1975,14 +1973,14 @@ ahash_process_req_prepare(struct ahash_r
+                       edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
+               /* 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 |= 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) ||
++              if (ctx->keylen && ((req_ctx->first_request && edesc->first) ||
+                                   (req_ctx->last_request && edesc->last)))
+                       edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
+@@ -2103,14 +2101,13 @@ static int ahash_init(struct ahash_reque
+       /* Initialize the context */
+       req_ctx->buf_idx = 0;
+       req_ctx->nbuf = 0;
+-      req_ctx->first_desc = 1; /* first_desc indicates h/w must init its context */
++      req_ctx->first_request = 1;
+       req_ctx->swinit = 0; /* assume h/w init of context */
+       size =  (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
+                       ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
+                       : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
+       req_ctx->hw_context_size = size;
+       req_ctx->last_request = 0;
+-      req_ctx->last_desc = 0;
+       dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
+                            DMA_TO_DEVICE);
+@@ -2202,8 +2199,8 @@ static int ahash_export(struct ahash_req
+              req_ctx->hw_context_size);
+       memcpy(export->buf, req_ctx->buf[req_ctx->buf_idx], req_ctx->nbuf);
+       export->swinit = req_ctx->swinit;
+-      export->first_desc = req_ctx->first_desc;
+-      export->last_desc = req_ctx->last_desc;
++      export->first_request = req_ctx->first_request;
++      export->last_request = req_ctx->last_request;
+       export->to_hash_later = req_ctx->to_hash_later;
+       export->nbuf = req_ctx->nbuf;
+@@ -2228,8 +2225,8 @@ static int ahash_import(struct ahash_req
+       memcpy(req_ctx->hw_context, export->hw_context, size);
+       memcpy(req_ctx->buf[0], export->buf, export->nbuf);
+       req_ctx->swinit = export->swinit;
+-      req_ctx->first_desc = export->first_desc;
+-      req_ctx->last_desc = export->last_desc;
++      req_ctx->first_request = export->first_request;
++      req_ctx->last_request = export->last_request;
+       req_ctx->to_hash_later = export->to_hash_later;
+       req_ctx->nbuf = export->nbuf;
diff --git a/queue-6.18/crypto-talitos-hash-use-descriptor-chaining-for-sec1-instead-of-workqueue.patch b/queue-6.18/crypto-talitos-hash-use-descriptor-chaining-for-sec1-instead-of-workqueue.patch
new file mode 100644 (file)
index 0000000..2f835ca
--- /dev/null
@@ -0,0 +1,393 @@
+From f1ede6d95d8ad3b32c6a552d2baab805bd00fc38 Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:53 +0200
+Subject: crypto: talitos/hash - use descriptor chaining for SEC1 instead of workqueue
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit f1ede6d95d8ad3b32c6a552d2baab805bd00fc38 upstream.
+
+Rework the SEC1 ahash implementation to build a chain of hardware
+descriptors, replacing the previous approach of submitting one
+descriptor at a time via a workqueue, introduced by commit 655ef638a2bc
+("crypto: talitos - fix SEC1 32k ahash request limitation").
+
+Introduce ahash_process_req_prepare() which iterates over the request
+data, allocating enough descriptors to cover the entire ahash request.
+The new fields (bufsl, src, first, last) are added to talitos_edesc for
+this purpose.
+
+common_nonsnoop_hash() no longer calls talitos_submit(); it only
+maps and sets up the descriptor.  Submission is now done by the caller
+after the chain is built.
+
+ahash_free_desc_list_from() takes over calling
+common_nonsnoop_hash_unmap() for each descriptor during cleanup.
+
+Compared to the workqueue based solution, request are slightly faster
+since there is no more scheduling latency induced by the workqueue, and
+only one interrupt is generated by the device at the end of a chain.
+
+Commit 655ef638a2bc ("crypto: talitos - fix SEC1 32k ahash request
+limitation") :
+
+$ /usr/libexec/libkcapi/sha256sum ./test_5M.bin
+013c5609d63c...  ./test_5M.bin
+real 0m 0.41s
+user 0m 0.01s
+sys  0m 0.07s
+
+Now :
+
+$ /usr/libexec/libkcapi/sha256sum ./test_5M.bin
+013c5609d63c...  ./test_5M.bin
+real 0m 0.33s
+user 0m 0.01s
+sys  0m 0.20s
+
+Tested on a system with an MPC885 SoC featuring the SEC1 Lite.
+
+The increase in sys time is due to the fact that commit 37b5e8897eb5
+("crypto: talitos - chain in buffered data for ahash on SEC1") can no
+longer be applied.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c |  168 +++++++++++++++++++++++++++++------------------
+ drivers/crypto/talitos.h |   10 ++
+ 2 files changed, 115 insertions(+), 63 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -1791,12 +1791,12 @@ static void common_nonsnoop_hash_unmap(s
+       unmap_single_talitos_ptr(dev, &desc->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));
+-      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);
+       /* When using hashctx-in, must unmap it. */
+       if (from_talitos_ptr_len(&desc->ptr[1], is_sec1))
+@@ -1808,12 +1808,14 @@ static void common_nonsnoop_hash_unmap(s
+                                DMA_BIDIRECTIONAL);
+ }
+-static void free_edesc_list_from(struct talitos_edesc *edesc)
++static void free_edesc_list_from(struct ahash_request *areq, struct talitos_edesc *edesc)
+ {
++      struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
+       struct talitos_edesc *next;
+       while (edesc) {
+               next = edesc->next_desc;
++              common_nonsnoop_hash_unmap(ctx->dev, edesc, areq);
+               kfree(edesc);
+               edesc = next;
+       }
+@@ -1828,19 +1830,18 @@ static void ahash_done(struct device *de
+                container_of(desc, struct talitos_edesc, desc);
+       struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
++
+       if (!req_ctx->last_desc && req_ctx->to_hash_later) {
+               /* Position any partial block for next update/final/finup */
+               req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
+               req_ctx->nbuf = req_ctx->to_hash_later;
+       }
+-      common_nonsnoop_hash_unmap(dev, edesc, areq);
+-      free_edesc_list_from(edesc);
++      free_edesc_list_from(areq, edesc);
+-      if (err) {
+-              ahash_request_complete(areq, err);
+-              return;
+-      }
++      ahash_request_complete(areq, err);
++
++      return;
+       req_ctx->remaining_ahash_request_bytes -=
+               req_ctx->current_ahash_request_bytes;
+@@ -1874,18 +1875,15 @@ static void talitos_handle_buggy_hash(st
+                              (char *)padded_hash, DMA_TO_DEVICE);
+ }
+-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 = crypto_ahash_reqtfm(areq);
+       struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+       struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+       struct device *dev = ctx->dev;
+       struct talitos_desc *desc = &edesc->desc;
+-      int ret;
+       bool sync_needed = false;
+       struct talitos_private *priv = dev_get_drvdata(dev);
+       bool is_sec1 = has_ftr_sec1(priv);
+@@ -1894,7 +1892,7 @@ static int common_nonsnoop_hash(struct t
+       /* first DWORD empty */
+       /* 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,
+@@ -1911,22 +1909,22 @@ static int common_nonsnoop_hash(struct t
+       sg_count = 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 = dma_map_sg(dev, req_ctx->psrc, sg_count,
+-                                    DMA_TO_DEVICE);
++              sg_count = dma_map_sg(dev, edesc->src, sg_count, DMA_TO_DEVICE);
++
+       /*
+        * data in
+        */
+-      sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
+-                                      &desc->ptr[3], sg_count, 0, 0);
++      sg_count = talitos_sg_map(dev, edesc->src, length, edesc, &desc->ptr[3],
++                                sg_count, 0, 0);
+       if (sg_count > 1)
+               sync_needed = true;
+       /* fifth DWORD empty */
+       /* 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);
+@@ -1944,30 +1942,89 @@ static int common_nonsnoop_hash(struct t
+       if (sync_needed)
+               dma_sync_single_for_device(dev, edesc->dma_link_tbl,
+                                          edesc->dma_len, DMA_BIDIRECTIONAL);
+-
+-      ret = talitos_submit(dev, ctx->ch, desc, callback,
+-                           areq);
+-      if (ret != -EINPROGRESS)
+-              goto err;
+-
+-      return -EINPROGRESS;
+-err:
+-      common_nonsnoop_hash_unmap(dev, edesc, areq);
+-      kfree(edesc);
+-      return ret;
+ }
+ static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
++                                             struct scatterlist *src,
+                                              unsigned int nbytes)
+ {
+       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);
+-      return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
++      return talitos_edesc_alloc(ctx->dev, src, NULL, NULL, 0,
+                                  nbytes, 0, 0, 0, areq->base.flags, false);
+ }
++static struct talitos_edesc *
++ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
++                        unsigned int blocksize, bool is_sec1)
++{
++      struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
++      struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
++      struct talitos_edesc *first = NULL, *prev_edesc = NULL, *edesc;
++      size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN : SIZE_MAX;
++      struct scatterlist tmp[2];
++      size_t to_hash_this_desc;
++      struct scatterlist *src;
++      size_t offset = 0;
++
++      do {
++              src = scatterwalk_ffwd(tmp, req_ctx->psrc, offset);
++
++              to_hash_this_desc =
++                      min(nbytes, ALIGN_DOWN(desc_max, blocksize));
++
++              /* Allocate extended descriptor */
++              edesc = ahash_edesc_alloc(areq, src, to_hash_this_desc);
++              if (IS_ERR(edesc)) {
++                      if (first)
++                              free_edesc_list_from(areq, first);
++                      return edesc;
++              }
++
++              edesc->src =
++                      scatterwalk_ffwd(edesc->bufsl, req_ctx->psrc, offset);
++              edesc->desc.hdr = ctx->desc_hdr_template;
++              edesc->first = offset == 0;
++              edesc->last = nbytes - to_hash_this_desc == 0;
++
++              /* On last one, request SEC to pad; otherwise continue */
++              if (req_ctx->last_request && edesc->last)
++                      edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
++              else
++                      edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
++
++              /* request SEC to INIT hash. */
++              if (req_ctx->first_desc && edesc->first && !req_ctx->swinit)
++                      edesc->desc.hdr |= 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 |= DESC_HDR_MODE0_MDEU_HMAC;
++
++              /* clear the DN bit  */
++              if (is_sec1 && !edesc->last)
++                      edesc->desc.hdr &= ~DESC_HDR_DONE_NOTIFY;
++
++              common_nonsnoop_hash(edesc, areq, to_hash_this_desc);
++
++              offset += to_hash_this_desc;
++              nbytes -= to_hash_this_desc;
++
++              if (!prev_edesc)
++                      first = edesc;
++              else
++                      prev_edesc->next_desc = edesc;
++              prev_edesc = edesc;
++      } while (nbytes);
++
++      return first;
++}
++
+ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes)
+ {
+       struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+@@ -1976,14 +2033,16 @@ static int ahash_process_req_one(struct
+       struct talitos_edesc *edesc;
+       unsigned int blocksize =
+                       crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
++      bool is_sec1 = has_ftr_sec1(dev_get_drvdata(ctx->dev));
+       unsigned int nbytes_to_hash;
+       unsigned int to_hash_later;
+       unsigned int nsg;
+       int nents;
+       struct device *dev = ctx->dev;
+       u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
++      int ret;
+-      if (!req_ctx->last_desc && (nbytes + req_ctx->nbuf <= blocksize)) {
++      if (!req_ctx->last_request && (nbytes + req_ctx->nbuf <= blocksize)) {
+               /* Buffer up to one whole block */
+               nents = sg_nents_for_len(req_ctx->request_sl, nbytes);
+               if (nents < 0) {
+@@ -2000,7 +2059,7 @@ static int ahash_process_req_one(struct
+       nbytes_to_hash = nbytes + req_ctx->nbuf;
+       to_hash_later = nbytes_to_hash & (blocksize - 1);
+-      if (req_ctx->last_desc)
++      if (req_ctx->last_request)
+               to_hash_later = 0;
+       else if (to_hash_later)
+               /* There is a partial block. Hash the full block(s) now */
+@@ -2035,30 +2094,16 @@ static int ahash_process_req_one(struct
+       }
+       req_ctx->to_hash_later = to_hash_later;
+-      /* Allocate extended descriptor */
+-      edesc = ahash_edesc_alloc(req_ctx->areq, nbytes_to_hash);
++      edesc = ahash_process_req_prepare(areq, nbytes_to_hash, blocksize,
++                                        is_sec1);
+       if (IS_ERR(edesc))
+               return PTR_ERR(edesc);
+-      edesc->desc.hdr = ctx->desc_hdr_template;
+-
+-      /* On last one, request SEC to pad; otherwise continue */
+-      if (req_ctx->last_desc)
+-              edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
+-      else
+-              edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
+-
+-      /* request SEC to INIT hash. */
+-      if (req_ctx->first_desc && !req_ctx->swinit)
+-              edesc->desc.hdr |= 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 || req_ctx->last_desc))
+-              edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
++      ret = talitos_submit(dev, ctx->ch, &edesc->desc, ahash_done, areq);
++      if (ret != -EINPROGRESS)
++              free_edesc_list_from(areq, edesc);
+-      return common_nonsnoop_hash(edesc, req_ctx->areq, nbytes_to_hash, ahash_done);
++      return ret;
+ }
+ static void sec1_ahash_process_remaining(struct work_struct *work)
+@@ -2102,16 +2147,13 @@ static int ahash_process_req(struct ahas
+       req_ctx->remaining_ahash_request_bytes = nbytes;
+       if (is_sec1) {
+-              if (nbytes > TALITOS1_MAX_DATA_LEN)
+-                      nbytes = TALITOS1_MAX_DATA_LEN;
+-              else if (req_ctx->last_request)
++              if (req_ctx->last_request)
+                       req_ctx->last_desc = 1;
+       }
+       req_ctx->current_ahash_request_bytes = nbytes;
+-      return ahash_process_req_one(req_ctx->areq,
+-                                   req_ctx->current_ahash_request_bytes);
++      return ahash_process_req_one(req_ctx->areq, nbytes);
+ }
+ static int ahash_init(struct ahash_request *areq)
+--- a/drivers/crypto/talitos.h
++++ b/drivers/crypto/talitos.h
+@@ -44,6 +44,11 @@ struct talitos_desc {
+ /*
+  * talitos_edesc - s/w-extended descriptor
++ * @bufsl: scatterlist buffer
++ * @src: pointer to input scatterlist
++ * @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
+@@ -59,6 +64,11 @@ struct talitos_desc {
+  * of link_tbl data
+  */
+ struct talitos_edesc {
++      struct scatterlist bufsl[2];
++      struct scatterlist *src;
++      int first;
++      int last;
++
+       int src_nents;
+       int dst_nents;
+       dma_addr_t iv_dma;
diff --git a/queue-6.18/crypto-talitos-move-code-in-current_desc_hdr-into-a-standalone-function.patch b/queue-6.18/crypto-talitos-move-code-in-current_desc_hdr-into-a-standalone-function.patch
new file mode 100644 (file)
index 0000000..7698fbd
--- /dev/null
@@ -0,0 +1,80 @@
+From f8713d9e6091755dd30f7f1cfa25f8440cddf81b Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:51 +0200
+Subject: crypto: talitos - move code in current_desc_hdr() into a standalone function
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit f8713d9e6091755dd30f7f1cfa25f8440cddf81b upstream.
+
+Previously added code in current_desc_hdr() in order to add support for
+searching an offending descriptor inside a descriptor chain.
+
+Move that code into a standalone function to improve readability.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c |   35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -520,6 +520,24 @@ DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0
+ DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
+ DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
++static __be32 search_desc_hdr_in_request(struct talitos_request *request,
++                                       dma_addr_t cur_desc, bool is_sec1)
++{
++      struct talitos_edesc *edesc;
++
++      if (request->dma_desc == cur_desc) {
++              return request->desc->hdr;
++      } else if (is_sec1) {
++              edesc = container_of(request->desc, struct talitos_edesc, desc);
++              while (edesc->next_desc) {
++                      if (edesc->desc.next_desc == cpu_to_be32(cur_desc))
++                              return edesc->next_desc->desc.hdr1;
++                      edesc = edesc->next_desc;
++              }
++      }
++      return 0;
++}
++
+ /*
+  * locate current (offending) descriptor
+  */
+@@ -528,7 +546,6 @@ static __be32 current_desc_hdr(struct de
+       struct talitos_private *priv = dev_get_drvdata(dev);
+       bool is_sec1 = has_ftr_sec1(priv);
+       struct talitos_request *request;
+-      struct talitos_edesc *edesc;
+       int tail, iter;
+       dma_addr_t cur_desc;
+       __be32 hdr = 0;
+@@ -546,21 +563,7 @@ static __be32 current_desc_hdr(struct de
+       do {
+               request = &priv->chan[ch].fifo[iter];
+-              if (request->dma_desc == cur_desc) {
+-                      hdr = request->desc->hdr;
+-              } else if (is_sec1) {
+-                      edesc = container_of(request->desc,
+-                                           struct talitos_edesc, desc);
+-                      while (edesc->next_desc) {
+-                              if (edesc->desc.next_desc ==
+-                                  cpu_to_be32(cur_desc)) {
+-                                      hdr = edesc->next_desc->desc.hdr1;
+-                                      break;
+-                              }
+-                              edesc = edesc->next_desc;
+-                      }
+-              }
+-
++              hdr = search_desc_hdr_in_request(request, cur_desc, is_sec1);
+               if (hdr)
+                       break;
diff --git a/queue-6.18/crypto-talitos-move-dma-mapping-code-in-talitos_submit-into-a-standalone-dma_map_request-function.patch b/queue-6.18/crypto-talitos-move-dma-mapping-code-in-talitos_submit-into-a-standalone-dma_map_request-function.patch
new file mode 100644 (file)
index 0000000..ff99b71
--- /dev/null
@@ -0,0 +1,121 @@
+From 5c0aa8cad7745505297103f05dda3fa06e8ac670 Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:50 +0200
+Subject: crypto: talitos - move dma mapping code in talitos_submit() into a standalone dma_map_request() function
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit 5c0aa8cad7745505297103f05dda3fa06e8ac670 upstream.
+
+Previously added code to talitos_submit() in order to map an entire
+descriptor chain.
+
+Move that code into a standalone function to improve readability.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c |   75 +++++++++++++++++++++++++----------------------
+ 1 file changed, 41 insertions(+), 34 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -255,6 +255,46 @@ static int init_device(struct device *de
+       return 0;
+ }
++static void dma_map_request(struct device *dev, struct talitos_request *request,
++                          struct talitos_desc *desc, bool is_sec1)
++{
++      struct talitos_edesc *edesc =
++              container_of(desc, struct talitos_edesc, desc);
++      dma_addr_t dma_desc, prev_dma_desc;
++      struct talitos_edesc *prev_edesc = NULL;
++
++      if (is_sec1) {
++              while (edesc) {
++                      edesc->desc.hdr1 = edesc->desc.hdr;
++
++                      dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
++                                                TALITOS_DESC_SIZE,
++                                                DMA_BIDIRECTIONAL);
++
++                      if (!prev_edesc) {
++                              request->dma_desc = dma_desc;
++                              goto next;
++                      }
++
++                      /* Chain in any previous descriptors. */
++
++                      prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
++
++                      dma_sync_single_for_device(dev, prev_dma_desc,
++                                                 TALITOS_DESC_SIZE,
++                                                 DMA_TO_DEVICE);
++
++next:
++                      prev_edesc = edesc;
++                      prev_dma_desc = dma_desc;
++                      edesc = edesc->next_desc;
++              }
++      } else {
++              request->dma_desc = dma_map_single(dev, desc, TALITOS_DESC_SIZE,
++                                                 DMA_BIDIRECTIONAL);
++      }
++}
++
+ /**
+  * talitos_submit - submits a descriptor to the device for processing
+  * @dev:      the SEC device to be used
+@@ -273,10 +313,7 @@ static int talitos_submit(struct device
+                                          void *context, int error),
+                         void *context)
+ {
+-      struct talitos_edesc *edesc = container_of(desc, struct talitos_edesc, desc);
+       struct talitos_private *priv = dev_get_drvdata(dev);
+-      dma_addr_t dma_desc, prev_dma_desc;
+-      struct talitos_edesc *prev_edesc = NULL;
+       struct talitos_request *request;
+       unsigned long flags;
+       int head;
+@@ -294,37 +331,7 @@ static int talitos_submit(struct device
+       request = &priv->chan[ch].fifo[head];
+       /* map descriptor and save caller data */
+-      if (is_sec1) {
+-              while (edesc) {
+-                      edesc->desc.hdr1 = edesc->desc.hdr;
+-
+-                      dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
+-                                                TALITOS_DESC_SIZE,
+-                                                DMA_BIDIRECTIONAL);
+-
+-                      if (!prev_edesc) {
+-                              request->dma_desc = dma_desc;
+-                              goto next;
+-                      }
+-
+-                      /* Chain in any previous descriptors. */
+-
+-                      prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
+-
+-                      dma_sync_single_for_device(dev, prev_dma_desc,
+-                                                 TALITOS_DESC_SIZE,
+-                                                 DMA_TO_DEVICE);
+-
+-next:
+-                      prev_edesc = edesc;
+-                      prev_dma_desc = dma_desc;
+-                      edesc = edesc->next_desc;
+-              }
+-      } else {
+-              request->dma_desc = dma_map_single(dev, desc,
+-                                                 TALITOS_DESC_SIZE,
+-                                                 DMA_BIDIRECTIONAL);
+-      }
++      dma_map_request(dev, request, desc, is_sec1);
+       request->callback = callback;
+       request->context = context;
diff --git a/queue-6.18/crypto-talitos-move-dma-unmapping-code-in-flush_channel-into-a-standalone-dma_unmap_request-function.patch b/queue-6.18/crypto-talitos-move-dma-unmapping-code-in-flush_channel-into-a-standalone-dma_unmap_request-function.patch
new file mode 100644 (file)
index 0000000..0dc4182
--- /dev/null
@@ -0,0 +1,84 @@
+From 4d9b0b7415b9e79a3d54d18b5ff230974ea78740 Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:49 +0200
+Subject: crypto: talitos - move dma unmapping code in flush_channel() into a standalone dma_unmap_request() function
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit 4d9b0b7415b9e79a3d54d18b5ff230974ea78740 upstream.
+
+Previously added code to flush_channel() in order to unmap an entire
+descriptor.
+
+Move that code into a standalone function to improve readability.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c |   39 ++++++++++++++++++++++-----------------
+ 1 file changed, 22 insertions(+), 17 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -372,6 +372,27 @@ static __be32 get_request_hdr(struct dev
+       return edesc->desc.hdr1;
+ }
++static void dma_unmap_request(struct device *dev,
++                            struct talitos_request *request, bool is_sec1)
++{
++      struct talitos_edesc *edesc;
++
++      if (is_sec1) {
++              dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
++                               DMA_BIDIRECTIONAL);
++              edesc = container_of(request->desc, struct talitos_edesc, desc);
++              while (edesc->next_desc) {
++                      dma_unmap_single(dev,
++                                       be32_to_cpu(edesc->desc.next_desc),
++                                       TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
++                      edesc = edesc->next_desc;
++              }
++      } else {
++              dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
++                               DMA_BIDIRECTIONAL);
++      }
++}
++
+ /*
+  * process what was done, notify callback of error if not
+  */
+@@ -379,7 +400,6 @@ static void flush_channel(struct device
+ {
+       struct talitos_private *priv = dev_get_drvdata(dev);
+       struct talitos_request *request, saved_req;
+-      struct talitos_edesc *edesc;
+       unsigned long flags;
+       int tail, status;
+       bool is_sec1 = has_ftr_sec1(priv);
+@@ -404,22 +424,7 @@ static void flush_channel(struct device
+                       else
+                               status = error;
+-              if (is_sec1) {
+-                      dma_unmap_single(dev, request->dma_desc,
+-                                       TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+-                      edesc = container_of(request->desc,
+-                                           struct talitos_edesc, desc);
+-                      while (edesc->next_desc) {
+-                              dma_unmap_single(
+-                                      dev, be32_to_cpu(edesc->desc.next_desc),
+-                                      TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+-                              edesc = edesc->next_desc;
+-                      }
+-              } else {
+-                      dma_unmap_single(dev, request->dma_desc,
+-                                      TALITOS_DESC_SIZE,
+-                                      DMA_BIDIRECTIONAL);
+-              }
++              dma_unmap_request(dev, request, is_sec1);
+               /* copy entries so we can call callback outside lock */
+               saved_req.desc = request->desc;
diff --git a/queue-6.18/crypto-talitos-use-dma_sync_single_for_cpu-before-reading-descriptor-header.patch b/queue-6.18/crypto-talitos-use-dma_sync_single_for_cpu-before-reading-descriptor-header.patch
new file mode 100644 (file)
index 0000000..f5ee51c
--- /dev/null
@@ -0,0 +1,77 @@
+From e17ff3d6ff907dc8406261e8fd3e1fc8a908f0f6 Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:47 +0200
+Subject: crypto: talitos - use dma_sync_single_for_cpu() before reading descriptor header
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit e17ff3d6ff907dc8406261e8fd3e1fc8a908f0f6 upstream.
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c |   28 ++++++++++++++++++++--------
+ 1 file changed, 20 insertions(+), 8 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -322,19 +322,31 @@ static int talitos_submit(struct device
+       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;
+-
+-      edesc = container_of(request->desc, struct talitos_edesc, desc);
+-
+-      return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))->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);
++
++              return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))
++                      ->hdr1;
++      }
+ }
+ /*
+@@ -358,7 +370,7 @@ static void flush_channel(struct device
+               /* 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;
diff --git a/queue-6.18/edac-i10nm-don-t-fail-probing-if-adxl-is-missing.patch b/queue-6.18/edac-i10nm-don-t-fail-probing-if-adxl-is-missing.patch
new file mode 100644 (file)
index 0000000..20b5fb1
--- /dev/null
@@ -0,0 +1,63 @@
+From e360a6d65bb46c527a5909430a31d640cdd5036e Mon Sep 17 00:00:00 2001
+From: Vasily Khoruzhick <vasilykh@arista.com>
+Date: Tue, 14 Apr 2026 11:17:16 -0700
+Subject: EDAC/i10nm: Don't fail probing if ADXL is missing
+
+From: Vasily Khoruzhick <vasilykh@arista.com>
+
+commit e360a6d65bb46c527a5909430a31d640cdd5036e upstream.
+
+ADXL is not present in Coreboot- or Slimbootloader-based BIOSes and as
+result, the driver fails to probe there.
+
+Since commit 2738c69a8813 ("EDAC/i10nm: Add driver decoder for Ice Lake
+and Tremont CPUs"), i10nm_edac supports driver decoder. Switch to driver
+decoding when ADXL is not present.
+
+Signed-off-by: Vasily Khoruzhick <vasilykh@arista.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Cc: stable@vger.kernel.org # v6.1+
+Link: https://patch.msgid.link/20260414181735.87023-1-anarsoul@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/edac/i10nm_base.c |   14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/drivers/edac/i10nm_base.c
++++ b/drivers/edac/i10nm_base.c
+@@ -79,6 +79,7 @@ static struct res_config *res_cfg;
+ static int retry_rd_err_log;
+ static int decoding_via_mca;
+ static bool mem_cfg_2lm;
++static bool no_adxl;
+ static struct reg_rrl icx_reg_rrl_ddr = {
+       .set_num = 2,
+@@ -1207,8 +1208,14 @@ static int __init i10nm_init(void)
+       }
+       rc = skx_adxl_get();
+-      if (rc)
+-              goto fail;
++      if (rc) {
++              /* Decoding errors via MCA banks for 2LM isn't supported yet */
++              if (rc != -ENODEV || mem_cfg_2lm)
++                      goto fail;
++              i10nm_printk(KERN_INFO, "ADXL not found, falling back to MCA-based decoding.\n");
++              no_adxl = true;
++              decoding_via_mca = true;
++      }
+       opstate_init();
+       mce_register_decode_chain(&i10nm_mce_dec);
+@@ -1242,7 +1249,8 @@ static void __exit i10nm_exit(void)
+       skx_teardown_debug();
+       mce_unregister_decode_chain(&i10nm_mce_dec);
+-      skx_adxl_put();
++      if (!no_adxl)
++              skx_adxl_put();
+       skx_remove();
+ }
diff --git a/queue-6.18/i2c-core-fix-hang-on-adapter-registration-failure.patch b/queue-6.18/i2c-core-fix-hang-on-adapter-registration-failure.patch
new file mode 100644 (file)
index 0000000..7e0c6b4
--- /dev/null
@@ -0,0 +1,109 @@
+From 3c7e164344e5bcf6f274bbf59a3274f5caad9bc1 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 11 May 2026 16:37:07 +0200
+Subject: i2c: core: fix hang on adapter registration failure
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 3c7e164344e5bcf6f274bbf59a3274f5caad9bc1 upstream.
+
+Clients may be registered from bus notifier callbacks when the adapter
+is registered. On a subsequent error during registration, the adapter
+references taken by such clients prevent the wait for the references to
+be released from ever completing.
+
+Fix this by refactoring client deregistration and deregistering also on
+late adapter registration failures.
+
+Fixes: f8756c67b3de ("i2c: core: call of_i2c_setup_smbus_alert in i2c_register_adapter")
+Cc: stable@vger.kernel.org     # 4.15
+Cc: Phil Reid <preid@electromag.com.au>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/i2c-core-base.c |   49 ++++++++++++++++++++++++++------------------
+ 1 file changed, 29 insertions(+), 20 deletions(-)
+
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -63,6 +63,7 @@
+ static DEFINE_MUTEX(core_lock);
+ static DEFINE_IDR(i2c_adapter_idr);
++static void i2c_deregister_clients(struct i2c_adapter *adap);
+ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
+ static DEFINE_STATIC_KEY_FALSE(i2c_trace_msg_key);
+@@ -1609,6 +1610,7 @@ static int i2c_register_adapter(struct i
+       return 0;
+ out_reg:
++      i2c_deregister_clients(adap);
+       debugfs_remove_recursive(adap->debugfs);
+       init_completion(&adap->dev_released);
+       device_unregister(&adap->dev);
+@@ -1748,29 +1750,10 @@ static int __process_removed_adapter(str
+       return 0;
+ }
+-/**
+- * i2c_del_adapter - unregister I2C adapter
+- * @adap: the adapter being unregistered
+- * Context: can sleep
+- *
+- * This unregisters an I2C adapter which was previously registered
+- * by @i2c_add_adapter or @i2c_add_numbered_adapter.
+- */
+-void i2c_del_adapter(struct i2c_adapter *adap)
++static void i2c_deregister_clients(struct i2c_adapter *adap)
+ {
+-      struct i2c_adapter *found;
+       struct i2c_client *client, *next;
+-      /* First make sure that this adapter was ever added */
+-      mutex_lock(&core_lock);
+-      found = idr_find(&i2c_adapter_idr, adap->nr);
+-      mutex_unlock(&core_lock);
+-      if (found != adap) {
+-              pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name);
+-              return;
+-      }
+-
+-      i2c_acpi_remove_space_handler(adap);
+       /* Tell drivers about this removal */
+       mutex_lock(&core_lock);
+       bus_for_each_drv(&i2c_bus_type, NULL, adap,
+@@ -1796,6 +1779,32 @@ void i2c_del_adapter(struct i2c_adapter
+        * them up properly, so we give them a chance to do that first. */
+       device_for_each_child(&adap->dev, NULL, __unregister_client);
+       device_for_each_child(&adap->dev, NULL, __unregister_dummy);
++}
++
++/**
++ * i2c_del_adapter - unregister I2C adapter
++ * @adap: the adapter being unregistered
++ * Context: can sleep
++ *
++ * This unregisters an I2C adapter which was previously registered
++ * by @i2c_add_adapter or @i2c_add_numbered_adapter.
++ */
++void i2c_del_adapter(struct i2c_adapter *adap)
++{
++      struct i2c_adapter *found;
++
++      /* First make sure that this adapter was ever added */
++      mutex_lock(&core_lock);
++      found = idr_find(&i2c_adapter_idr, adap->nr);
++      mutex_unlock(&core_lock);
++      if (found != adap) {
++              pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name);
++              return;
++      }
++
++      i2c_acpi_remove_space_handler(adap);
++
++      i2c_deregister_clients(adap);
+       /* device name is gone after device_unregister */
+       dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
diff --git a/queue-6.18/regulator-scmi-fix-of_node-refcount-leak-in-scmi_regulator_probe.patch b/queue-6.18/regulator-scmi-fix-of_node-refcount-leak-in-scmi_regulator_probe.patch
new file mode 100644 (file)
index 0000000..a903360
--- /dev/null
@@ -0,0 +1,41 @@
+From fa11039d6cdff84584a3ef8cc1f5e1b56e045da2 Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Wed, 27 May 2026 10:48:50 +0000
+Subject: regulator: scmi: fix of_node refcount leak in scmi_regulator_probe()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit fa11039d6cdff84584a3ef8cc1f5e1b56e045da2 upstream.
+
+scmi_regulator_probe() calls of_find_node_by_name() which takes a
+reference on the returned device node. On the error path where
+process_scmi_regulator_of_node() fails, the function returns without
+calling of_node_put() on the child node, leaking the reference.
+
+Add of_node_put(np) on the error path to properly release the
+reference.
+
+Cc: stable@vger.kernel.org
+Fixes: 0fbeae70ee7c ("regulator: add SCMI driver")
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Link: https://patch.msgid.link/20260527104850.872415-1-vulab@iscas.ac.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/regulator/scmi-regulator.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/regulator/scmi-regulator.c
++++ b/drivers/regulator/scmi-regulator.c
+@@ -345,8 +345,10 @@ static int scmi_regulator_probe(struct s
+       for_each_child_of_node_scoped(np, child) {
+               ret = process_scmi_regulator_of_node(sdev, ph, child, rinfo);
+               /* abort on any mem issue */
+-              if (ret == -ENOMEM)
++              if (ret == -ENOMEM) {
++                      of_node_put(np);
+                       return ret;
++              }
+       }
+       of_node_put(np);
+       /*
index a3a0884d055a4d7b9feef63f7234927af04ccdb1..da49ef64eaa0f0a1716a11267098cfe68e481886 100644 (file)
@@ -368,4 +368,23 @@ crypto-qat-protect-service-table-iterations-with-service_lock.patch
 crypto-qat-skip-restart-for-down-devices.patch
 crypto-qat-validate-rsa-crt-component-lengths.patch
 crypto-qat-factor-out-aer-reset-helpers.patch
+crypto-talitos-use-dma_sync_single_for_cpu-before-reading-descriptor-header.patch
+crypto-talitos-add-chaining-of-arbitrary-number-of-descriptor-for-the-sec1.patch
+crypto-talitos-move-dma-unmapping-code-in-flush_channel-into-a-standalone-dma_unmap_request-function.patch
+crypto-talitos-move-dma-mapping-code-in-talitos_submit-into-a-standalone-dma_map_request-function.patch
+crypto-talitos-move-code-in-current_desc_hdr-into-a-standalone-function.patch
+crypto-talitos-hash-prepare-sec1-descriptor-chaining-remove-additional-descriptor.patch
+crypto-talitos-hash-use-descriptor-chaining-for-sec1-instead-of-workqueue.patch
+crypto-talitos-hash-drop-workqueue-mechanism-for-sec1.patch
+crypto-talitos-hash-rename-first_desc-last_desc-to-first_request-last_request.patch
+crypto-talitos-hash-remove-useless-wrapper.patch
+crypto-talitos-hash-fix-sec2-64k-1-ahash-request-limitation.patch
+arm64-fpsimd-fix-type-mismatch-in-sme_-save-load-_state.patch
+spi-fsl-lpspi-replace-dmaengine_terminate_all-with-dmaengine_terminate_sync.patch
+spi-fsl-lpspi-terminate-the-rx-channel-on-tx-prepare-failure-path.patch
+x86-mm-fix-freeing-of-pmd-sized-vmemmap-pages.patch
+edac-i10nm-don-t-fail-probing-if-adxl-is-missing.patch
+watchdog-apple-add-apple-t8103-wdt-compatible.patch
+regulator-scmi-fix-of_node-refcount-leak-in-scmi_regulator_probe.patch
+i2c-core-fix-hang-on-adapter-registration-failure.patch
 crypto-loongson-remove-broken-and-unused-loongson-rng.patch
diff --git a/queue-6.18/spi-fsl-lpspi-replace-dmaengine_terminate_all-with-dmaengine_terminate_sync.patch b/queue-6.18/spi-fsl-lpspi-replace-dmaengine_terminate_all-with-dmaengine_terminate_sync.patch
new file mode 100644 (file)
index 0000000..5a83988
--- /dev/null
@@ -0,0 +1,77 @@
+From e703ce47691b967fe9b4057fb1d062273211afa9 Mon Sep 17 00:00:00 2001
+From: Carlos Song <carlos.song@nxp.com>
+Date: Mon, 25 May 2026 14:23:56 +0800
+Subject: spi: fsl-lpspi: replace dmaengine_terminate_all() with dmaengine_terminate_sync()
+
+From: Carlos Song <carlos.song@nxp.com>
+
+commit e703ce47691b967fe9b4057fb1d062273211afa9 upstream.
+
+dmaengine_terminate_all() has been deprecated, so replace it with
+dmaengine_terminate_sync().
+
+Fixes: 09c04466ce7e ("spi: lpspi: add dma mode support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Carlos Song <carlos.song@nxp.com>
+Link: https://patch.msgid.link/20260525062357.3191349-2-carlos.song@oss.nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-fsl-lpspi.c |   18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/drivers/spi/spi-fsl-lpspi.c
++++ b/drivers/spi/spi-fsl-lpspi.c
+@@ -619,7 +619,7 @@ static int fsl_lpspi_dma_transfer(struct
+                               tx->sgl, tx->nents, DMA_MEM_TO_DEV,
+                               DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+       if (!desc_tx) {
+-              dmaengine_terminate_all(controller->dma_tx);
++              dmaengine_terminate_sync(controller->dma_tx);
+               return -EINVAL;
+       }
+@@ -640,8 +640,8 @@ static int fsl_lpspi_dma_transfer(struct
+                                                       transfer_timeout);
+               if (!time_left) {
+                       dev_err(fsl_lpspi->dev, "I/O Error in DMA TX\n");
+-                      dmaengine_terminate_all(controller->dma_tx);
+-                      dmaengine_terminate_all(controller->dma_rx);
++                      dmaengine_terminate_sync(controller->dma_tx);
++                      dmaengine_terminate_sync(controller->dma_rx);
+                       fsl_lpspi_reset(fsl_lpspi);
+                       return -ETIMEDOUT;
+               }
+@@ -650,8 +650,8 @@ static int fsl_lpspi_dma_transfer(struct
+                                                       transfer_timeout);
+               if (!time_left) {
+                       dev_err(fsl_lpspi->dev, "I/O Error in DMA RX\n");
+-                      dmaengine_terminate_all(controller->dma_tx);
+-                      dmaengine_terminate_all(controller->dma_rx);
++                      dmaengine_terminate_sync(controller->dma_tx);
++                      dmaengine_terminate_sync(controller->dma_rx);
+                       fsl_lpspi_reset(fsl_lpspi);
+                       return -ETIMEDOUT;
+               }
+@@ -660,8 +660,8 @@ static int fsl_lpspi_dma_transfer(struct
+                       fsl_lpspi->target_aborted) {
+                       dev_dbg(fsl_lpspi->dev,
+                               "I/O Error in DMA TX interrupted\n");
+-                      dmaengine_terminate_all(controller->dma_tx);
+-                      dmaengine_terminate_all(controller->dma_rx);
++                      dmaengine_terminate_sync(controller->dma_tx);
++                      dmaengine_terminate_sync(controller->dma_rx);
+                       fsl_lpspi_reset(fsl_lpspi);
+                       return -EINTR;
+               }
+@@ -670,8 +670,8 @@ static int fsl_lpspi_dma_transfer(struct
+                       fsl_lpspi->target_aborted) {
+                       dev_dbg(fsl_lpspi->dev,
+                               "I/O Error in DMA RX interrupted\n");
+-                      dmaengine_terminate_all(controller->dma_tx);
+-                      dmaengine_terminate_all(controller->dma_rx);
++                      dmaengine_terminate_sync(controller->dma_tx);
++                      dmaengine_terminate_sync(controller->dma_rx);
+                       fsl_lpspi_reset(fsl_lpspi);
+                       return -EINTR;
+               }
diff --git a/queue-6.18/spi-fsl-lpspi-terminate-the-rx-channel-on-tx-prepare-failure-path.patch b/queue-6.18/spi-fsl-lpspi-terminate-the-rx-channel-on-tx-prepare-failure-path.patch
new file mode 100644 (file)
index 0000000..6e3295c
--- /dev/null
@@ -0,0 +1,39 @@
+From 01980b5da56e573d62798d0ff6c86bcaa2b22cbe Mon Sep 17 00:00:00 2001
+From: Carlos Song <carlos.song@nxp.com>
+Date: Mon, 25 May 2026 14:23:57 +0800
+Subject: spi: fsl-lpspi: terminate the RX channel on TX prepare failure path
+
+From: Carlos Song <carlos.song@nxp.com>
+
+commit 01980b5da56e573d62798d0ff6c86bcaa2b22cbe upstream.
+
+When dmaengine_prep_slave_sg() fails for the TX channel, the error path
+terminates the TX DMA channel but leaves the RX channel running. Since
+the RX channel was already submitted and issued prior to preparing
+the TX descriptor, returning -EINVAL causes the SPI core to unmap the
+DMA buffers while the RX DMA engine continues writing to them, leading
+to potential memory corruption or use-after-free.
+
+Terminate the RX channel before returning on the TX prepare failure path.
+
+Fixes: 09c04466ce7e ("spi: lpspi: add dma mode support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Carlos Song <carlos.song@nxp.com>
+Link: https://patch.msgid.link/20260525062357.3191349-3-carlos.song@oss.nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-fsl-lpspi.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-fsl-lpspi.c
++++ b/drivers/spi/spi-fsl-lpspi.c
+@@ -619,7 +619,7 @@ static int fsl_lpspi_dma_transfer(struct
+                               tx->sgl, tx->nents, DMA_MEM_TO_DEV,
+                               DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+       if (!desc_tx) {
+-              dmaengine_terminate_sync(controller->dma_tx);
++              dmaengine_terminate_sync(controller->dma_rx);
+               return -EINVAL;
+       }
diff --git a/queue-6.18/watchdog-apple-add-apple-t8103-wdt-compatible.patch b/queue-6.18/watchdog-apple-add-apple-t8103-wdt-compatible.patch
new file mode 100644 (file)
index 0000000..f77c3be
--- /dev/null
@@ -0,0 +1,37 @@
+From 14ca4868886f2188401fe06cd7bf01a330b3fb99 Mon Sep 17 00:00:00 2001
+From: Janne Grunau <j@jannau.net>
+Date: Wed, 31 Dec 2025 13:07:21 +0100
+Subject: watchdog: apple: Add "apple,t8103-wdt" compatible
+
+From: Janne Grunau <j@jannau.net>
+
+commit 14ca4868886f2188401fe06cd7bf01a330b3fb99 upstream.
+
+After discussion with the devicetree maintainers we agreed to not extend
+lists with the generic compatible "apple,wdt" anymore [1]. Use
+"apple,t8103-wdt" as base compatible as it is the SoC the driver and
+bindings were written for.
+
+[1]: https://lore.kernel.org/asahi/12ab93b7-1fc2-4ce0-926e-c8141cfe81bf@kernel.org/
+
+Fixes: 4ed224aeaf66 ("watchdog: Add Apple SoC watchdog driver")
+Cc: stable@vger.kernel.org
+Reviewed-by: Neal Gompa <neal@gompa.dev>
+Signed-off-by: Janne Grunau <j@jannau.net>
+Link: https://lore.kernel.org/r/20251231-watchdog-apple-t8103-base-compat-v1-1-1702a02e0c45@jannau.net
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/watchdog/apple_wdt.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/watchdog/apple_wdt.c
++++ b/drivers/watchdog/apple_wdt.c
+@@ -218,6 +218,7 @@ static int apple_wdt_suspend(struct devi
+ static DEFINE_SIMPLE_DEV_PM_OPS(apple_wdt_pm_ops, apple_wdt_suspend, apple_wdt_resume);
+ static const struct of_device_id apple_wdt_of_match[] = {
++      { .compatible = "apple,t8103-wdt" },
+       { .compatible = "apple,wdt" },
+       {},
+ };
diff --git a/queue-6.18/x86-mm-fix-freeing-of-pmd-sized-vmemmap-pages.patch b/queue-6.18/x86-mm-fix-freeing-of-pmd-sized-vmemmap-pages.patch
new file mode 100644 (file)
index 0000000..c99dd69
--- /dev/null
@@ -0,0 +1,128 @@
+From 39406c05f8f150f1685839acd38ffdd69ff92031 Mon Sep 17 00:00:00 2001
+From: "David Hildenbrand (Arm)" <david@kernel.org>
+Date: Wed, 29 Apr 2026 12:49:14 +0200
+Subject: x86/mm: Fix freeing of PMD-sized vmemmap pages
+
+From: David Hildenbrand (Arm) <david@kernel.org>
+
+commit 39406c05f8f150f1685839acd38ffdd69ff92031 upstream.
+
+Commit bf9e4e30f353 ("x86/mm: use pagetable_free()"), switched from
+freeing non-boot page tables through __free_pages() to
+pagetable_free().
+
+However, the function is also called to free vmemmap pages.
+
+Given that vmemmap pages are not page tables, already the page_ptdesc(page)
+is wrong. But worse, pagetable_free() calls:
+
+       __free_pages(page, compound_order(page));
+
+Since vmemmap pages are not compound pages (see vmemmap_alloc_block())
+-- except for HVO, which doesn't apply here -- only first page of a
+PMD-sized vmemmap page is freed, leaking the other ones.
+
+Fix it by properly decoupling pagetable and vmemmap freeing.
+free_pagetable() no longer has to mess with SECTION_INFO, as only the
+vmemmap is marked like that in register_page_bootmem_memmap().
+
+The indentation in remove_pmd_table() is messed up. Fix that while
+touching it.
+
+Bootmem info handling will soon be fixed up. For now, handle it
+similar to free_pagetable(), just avoiding the ifdef.
+
+[ dhansen: changelog munging. More imperative voice ]
+
+Fixes: bf9e4e30f353 ("x86/mm: use pagetable_free()")
+Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Tested-by: Lance Yang <lance.yang@linux.dev>
+Link: https://lore.kernel.org/20260429-vmemmap-v2-1-8dfcacffd877@kernel.org
+Link: https://patch.msgid.link/20260429-vmemmap-v2-1-8dfcacffd877@kernel.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/mm/init_64.c |   40 ++++++++++++++++++++++++++--------------
+ 1 file changed, 26 insertions(+), 14 deletions(-)
+
+--- a/arch/x86/mm/init_64.c
++++ b/arch/x86/mm/init_64.c
+@@ -1021,7 +1021,7 @@ static void __meminit free_pagetable(str
+ #ifdef CONFIG_HAVE_BOOTMEM_INFO_NODE
+               enum bootmem_type type = bootmem_type(page);
+-              if (type == SECTION_INFO || type == MIX_SECTION_INFO) {
++              if (type == MIX_SECTION_INFO) {
+                       while (nr_pages--)
+                               put_page_bootmem(page++);
+               } else {
+@@ -1035,13 +1035,24 @@ static void __meminit free_pagetable(str
+       }
+ }
+-static void __meminit free_hugepage_table(struct page *page,
++static void __meminit free_vmemmap_pages(struct page *page, unsigned int order,
+               struct vmem_altmap *altmap)
+ {
+-      if (altmap)
+-              vmem_altmap_free(altmap, PMD_SIZE / PAGE_SIZE);
+-      else
+-              free_pagetable(page, get_order(PMD_SIZE));
++      unsigned long nr_pages = 1u << order;
++
++      if (altmap) {
++              vmem_altmap_free(altmap, nr_pages);
++      } else if (PageReserved(page)) {
++              if (IS_ENABLED(CONFIG_HAVE_BOOTMEM_INFO_NODE) &&
++                  bootmem_type(page) == SECTION_INFO) {
++                      while (nr_pages--)
++                              put_page_bootmem(page++);
++              } else {
++                      free_reserved_pages(page, nr_pages);
++              }
++      } else {
++              __free_pages(page, order);
++      }
+ }
+ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
+@@ -1125,7 +1136,8 @@ remove_pte_table(pte_t *pte_start, unsig
+                       return;
+               if (!direct)
+-                      free_pagetable(pte_page(*pte), 0);
++                      /* We never populate base pages from the altmap. */
++                      free_vmemmap_pages(pte_page(*pte), 0, NULL);
+               spin_lock(&init_mm.page_table_lock);
+               pte_clear(&init_mm, addr, pte);
+@@ -1160,19 +1172,19 @@ remove_pmd_table(pmd_t *pmd_start, unsig
+                       if (IS_ALIGNED(addr, PMD_SIZE) &&
+                           IS_ALIGNED(next, PMD_SIZE)) {
+                               if (!direct)
+-                                      free_hugepage_table(pmd_page(*pmd),
+-                                                          altmap);
++                                      free_vmemmap_pages(pmd_page(*pmd),
++                                                         PMD_ORDER, altmap);
+                               spin_lock(&init_mm.page_table_lock);
+                               pmd_clear(pmd);
+                               spin_unlock(&init_mm.page_table_lock);
+                               pages++;
+                       } else if (vmemmap_pmd_is_unused(addr, next)) {
+-                                      free_hugepage_table(pmd_page(*pmd),
+-                                                          altmap);
+-                                      spin_lock(&init_mm.page_table_lock);
+-                                      pmd_clear(pmd);
+-                                      spin_unlock(&init_mm.page_table_lock);
++                              free_vmemmap_pages(pmd_page(*pmd), PMD_ORDER,
++                                                 altmap);
++                              spin_lock(&init_mm.page_table_lock);
++                              pmd_clear(pmd);
++                              spin_unlock(&init_mm.page_table_lock);
+                       }
+                       continue;
+               }