]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Jul 2026 10:26:04 +0000 (12:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Jul 2026 10:26:04 +0000 (12:26 +0200)
added patches:
crypto-qat-keep-vfs-enabled-during-reset.patch
crypto-qat-notify-fatal-error-before-aer-reset-preparation.patch
crypto-qat-protect-service-table-iterations-with-service_lock.patch
crypto-qat-validate-rsa-crt-component-lengths.patch

queue-6.12/crypto-qat-keep-vfs-enabled-during-reset.patch [new file with mode: 0644]
queue-6.12/crypto-qat-notify-fatal-error-before-aer-reset-preparation.patch [new file with mode: 0644]
queue-6.12/crypto-qat-protect-service-table-iterations-with-service_lock.patch [new file with mode: 0644]
queue-6.12/crypto-qat-validate-rsa-crt-component-lengths.patch [new file with mode: 0644]
queue-6.12/series

diff --git a/queue-6.12/crypto-qat-keep-vfs-enabled-during-reset.patch b/queue-6.12/crypto-qat-keep-vfs-enabled-during-reset.patch
new file mode 100644 (file)
index 0000000..e3687ef
--- /dev/null
@@ -0,0 +1,68 @@
+From 57518500053987672050dc2f7bf8a774d5d52fd9 Mon Sep 17 00:00:00 2001
+From: Ahsan Atta <ahsan.atta@intel.com>
+Date: Wed, 13 May 2026 17:16:54 +0200
+Subject: crypto: qat - keep VFs enabled during reset
+
+From: Ahsan Atta <ahsan.atta@intel.com>
+
+commit 57518500053987672050dc2f7bf8a774d5d52fd9 upstream.
+
+When a reset is triggered via sysfs, the PCI core invokes the
+reset_prepare() callback while holding pci_dev_lock(), which includes
+the PCI configuration space access semaphore. If reset_prepare() calls
+adf_dev_down(), the call chain adf_dev_stop() -> adf_disable_sriov()
+-> pci_disable_sriov() attempts to acquire the same semaphore,
+resulting in a deadlock.
+
+Avoid this by skipping pci_disable_sriov() when ADF_STATUS_RESTARTING
+is set. During reset the PCI topology is preserved, so VF devices
+remain valid and enumerated across the reset. VF notification and the
+quiesce handshake via adf_pf2vf_notify_restarting() are still
+performed unconditionally so that VFs stop submitting work before the
+PF shuts down.
+
+Correspondingly, skip pci_enable_sriov() in adf_enable_sriov() when
+VFs are already present, since their PCI devices were preserved from
+before the restart.
+
+This is in preparation for adding reset_prepare() and reset_done()
+callbacks in adf_aer.c.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Ahsan Atta <ahsan.atta@intel.com>
+Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Damian Muszynski <damian.muszynski@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/intel/qat/qat_common/adf_sriov.c |   12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/crypto/intel/qat/qat_common/adf_sriov.c
++++ b/drivers/crypto/intel/qat/qat_common/adf_sriov.c
+@@ -77,6 +77,10 @@ static int adf_enable_sriov(struct adf_a
+       /* Enable VF to PF interrupts for all VFs */
+       adf_enable_vf2pf_interrupts(accel_dev, BIT_ULL(totalvfs) - 1);
++      /* Do not enable SR-IOV if already enabled */
++      if (pci_num_vf(pdev))
++              return 0;
++
+       /*
+        * Due to the hardware design, when SR-IOV and the ring arbiter
+        * are enabled all the VFs supported in hardware must be enabled in
+@@ -247,7 +251,13 @@ void adf_disable_sriov(struct adf_accel_
+       adf_pf2vf_notify_restarting(accel_dev);
+       adf_pf2vf_wait_for_restarting_complete(accel_dev);
+-      pci_disable_sriov(accel_to_pci_dev(accel_dev));
++      /*
++       * When the device is restarting, preserve VF PCI devices across
++       * the reset by skipping pci_disable_sriov(). VFs are notified to
++       * quiesce regardless so the PF can safely shut down.
++       */
++      if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
++              pci_disable_sriov(accel_to_pci_dev(accel_dev));
+       /* Disable VF to PF interrupts */
+       adf_disable_all_vf2pf_interrupts(accel_dev);
diff --git a/queue-6.12/crypto-qat-notify-fatal-error-before-aer-reset-preparation.patch b/queue-6.12/crypto-qat-notify-fatal-error-before-aer-reset-preparation.patch
new file mode 100644 (file)
index 0000000..13b8afc
--- /dev/null
@@ -0,0 +1,45 @@
+From 6931835f2fdd0cb9b1c7791748d7e67d0749056a Mon Sep 17 00:00:00 2001
+From: Ahsan Atta <ahsan.atta@intel.com>
+Date: Wed, 13 May 2026 17:16:55 +0200
+Subject: crypto: qat - notify fatal error before AER reset preparation
+
+From: Ahsan Atta <ahsan.atta@intel.com>
+
+commit 6931835f2fdd0cb9b1c7791748d7e67d0749056a upstream.
+
+Send fatal error notifications to subsystems and VFs as soon as
+AER error detection starts, before entering the reset preparation
+shutdown sequence.
+
+This reduces notification latency and ensures peers are informed
+immediately on fatal detection, rather than after restart-state setup
+and arbitration teardown.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Ahsan Atta <ahsan.atta@intel.com>
+Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Damian Muszynski <damian.muszynski@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/intel/qat/qat_common/adf_aer.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/crypto/intel/qat/qat_common/adf_aer.c
++++ b/drivers/crypto/intel/qat/qat_common/adf_aer.c
+@@ -33,13 +33,13 @@ static pci_ers_result_t adf_error_detect
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
++      adf_error_notifier(accel_dev);
++      adf_pf2vf_notify_fatal_error(accel_dev);
+       set_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+       if (accel_dev->hw_device->exit_arb) {
+               dev_dbg(&pdev->dev, "Disabling arbitration\n");
+               accel_dev->hw_device->exit_arb(accel_dev);
+       }
+-      adf_error_notifier(accel_dev);
+-      adf_pf2vf_notify_fatal_error(accel_dev);
+       adf_dev_restarting_notify(accel_dev);
+       pci_clear_master(pdev);
+       adf_dev_down(accel_dev);
diff --git a/queue-6.12/crypto-qat-protect-service-table-iterations-with-service_lock.patch b/queue-6.12/crypto-qat-protect-service-table-iterations-with-service_lock.patch
new file mode 100644 (file)
index 0000000..843c647
--- /dev/null
@@ -0,0 +1,156 @@
+From 5c6f845e77ec35f9b7b047cc8f9789bf397cdd3e Mon Sep 17 00:00:00 2001
+From: Ahsan Atta <ahsan.atta@intel.com>
+Date: Wed, 20 May 2026 13:41:55 +0100
+Subject: crypto: qat - protect service table iterations with service_lock
+
+From: Ahsan Atta <ahsan.atta@intel.com>
+
+commit 5c6f845e77ec35f9b7b047cc8f9789bf397cdd3e upstream.
+
+The service_table list is protected by service_lock when entries are
+added or removed (in adf_service_add() and adf_service_remove()), but
+several functions iterate over the list without holding this lock.
+
+A concurrent adf_service_register() or adf_service_unregister() call
+could modify the list during traversal, leading to list corruption or
+a use-after-free.
+
+Fix this by holding service_lock across all list_for_each_entry()
+iterations of service_table in adf_dev_init(), adf_dev_start(),
+adf_dev_stop(), adf_dev_shutdown(), adf_dev_restarting_notify(),
+adf_dev_restarted_notify(), and adf_error_notifier().
+
+The lock ordering is safe: callers of the static helpers (adf_dev_up()
+and adf_dev_down()) acquire state_lock before service_lock, and no
+event_hld callback or service_lock holder ever acquires state_lock in
+the reverse order.
+
+Cc: stable@vger.kernel.org
+Fixes: d8cba25d2c68 ("crypto: qat - Intel(R) QAT driver framework")
+Signed-off-by: Ahsan Atta <ahsan.atta@intel.com>
+Co-developed-by: Maksim Lukoshkov <maksim.lukoshkov@intel.com>
+Signed-off-by: Maksim Lukoshkov <maksim.lukoshkov@intel.com>
+Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/intel/qat/qat_common/adf_init.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/crypto/intel/qat/qat_common/adf_init.c
++++ b/drivers/crypto/intel/qat/qat_common/adf_init.c
+@@ -152,15 +152,18 @@ static int adf_dev_init(struct adf_accel
+        * This is to facilitate any ordering dependencies between services
+        * prior to starting any of the accelerators.
+        */
++      mutex_lock(&service_lock);
+       list_for_each_entry(service, &service_table, list) {
+               if (service->event_hld(accel_dev, ADF_EVENT_INIT)) {
+                       dev_err(&GET_DEV(accel_dev),
+                               "Failed to initialise service %s\n",
+                               service->name);
++                      mutex_unlock(&service_lock);
+                       return -EFAULT;
+               }
+               set_bit(accel_dev->accel_id, service->init_status);
+       }
++      mutex_unlock(&service_lock);
+       return 0;
+ }
+@@ -229,15 +232,18 @@ static int adf_dev_start(struct adf_acce
+       if (ret && ret != -EOPNOTSUPP)
+               return ret;
++      mutex_lock(&service_lock);
+       list_for_each_entry(service, &service_table, list) {
+               if (service->event_hld(accel_dev, ADF_EVENT_START)) {
+                       dev_err(&GET_DEV(accel_dev),
+                               "Failed to start service %s\n",
+                               service->name);
++                      mutex_unlock(&service_lock);
+                       return -EFAULT;
+               }
+               set_bit(accel_dev->accel_id, service->start_status);
+       }
++      mutex_unlock(&service_lock);
+       clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
+       set_bit(ADF_STATUS_STARTED, &accel_dev->status);
+@@ -308,6 +314,7 @@ static void adf_dev_stop(struct adf_acce
+               qat_comp_algs_unregister();
+       clear_bit(ADF_STATUS_COMP_ALGS_REGISTERED, &accel_dev->status);
++      mutex_lock(&service_lock);
+       list_for_each_entry(service, &service_table, list) {
+               if (!test_bit(accel_dev->accel_id, service->start_status))
+                       continue;
+@@ -319,6 +326,7 @@ static void adf_dev_stop(struct adf_acce
+                       clear_bit(accel_dev->accel_id, service->start_status);
+               }
+       }
++      mutex_unlock(&service_lock);
+       if (hw_data->stop_timer)
+               hw_data->stop_timer(accel_dev);
+@@ -368,6 +376,7 @@ static void adf_dev_shutdown(struct adf_
+                                 &accel_dev->status);
+       }
++      mutex_lock(&service_lock);
+       list_for_each_entry(service, &service_table, list) {
+               if (!test_bit(accel_dev->accel_id, service->init_status))
+                       continue;
+@@ -378,6 +387,7 @@ static void adf_dev_shutdown(struct adf_
+               else
+                       clear_bit(accel_dev->accel_id, service->init_status);
+       }
++      mutex_unlock(&service_lock);
+       adf_rl_exit(accel_dev);
+@@ -412,12 +422,14 @@ int adf_dev_restarting_notify(struct adf
+ {
+       struct service_hndl *service;
++      mutex_lock(&service_lock);
+       list_for_each_entry(service, &service_table, list) {
+               if (service->event_hld(accel_dev, ADF_EVENT_RESTARTING))
+                       dev_err(&GET_DEV(accel_dev),
+                               "Failed to restart service %s.\n",
+                               service->name);
+       }
++      mutex_unlock(&service_lock);
+       return 0;
+ }
+@@ -425,12 +437,14 @@ int adf_dev_restarted_notify(struct adf_
+ {
+       struct service_hndl *service;
++      mutex_lock(&service_lock);
+       list_for_each_entry(service, &service_table, list) {
+               if (service->event_hld(accel_dev, ADF_EVENT_RESTARTED))
+                       dev_err(&GET_DEV(accel_dev),
+                               "Failed to restart service %s.\n",
+                               service->name);
+       }
++      mutex_unlock(&service_lock);
+       return 0;
+ }
+@@ -438,12 +452,14 @@ void adf_error_notifier(struct adf_accel
+ {
+       struct service_hndl *service;
++      mutex_lock(&service_lock);
+       list_for_each_entry(service, &service_table, list) {
+               if (service->event_hld(accel_dev, ADF_EVENT_FATAL_ERROR))
+                       dev_err(&GET_DEV(accel_dev),
+                               "Failed to send error event to %s.\n",
+                               service->name);
+       }
++      mutex_unlock(&service_lock);
+ }
+ int adf_dev_down(struct adf_accel_dev *accel_dev)
diff --git a/queue-6.12/crypto-qat-validate-rsa-crt-component-lengths.patch b/queue-6.12/crypto-qat-validate-rsa-crt-component-lengths.patch
new file mode 100644 (file)
index 0000000..a61cfdb
--- /dev/null
@@ -0,0 +1,83 @@
+From b3ac78756588059729b9195fcc9f4b37d54057a5 Mon Sep 17 00:00:00 2001
+From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Date: Thu, 28 May 2026 16:57:44 +0100
+Subject: crypto: qat - validate RSA CRT component lengths
+
+From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+
+commit b3ac78756588059729b9195fcc9f4b37d54057a5 upstream.
+
+The generic RSA key parser (rsa_helper.c) bounds each CRT component (p,
+q, dp, dq, qinv) by the modulus size n_sz, but qat_rsa_setkey_crt()
+allocates half-size DMA buffers (key_sz / 2) and right-aligns each
+component with:
+
+    memcpy(dst + half_key_sz - len, src, len)
+
+When a CRT component is larger than half_key_sz the subtraction
+underflows and memcpy writes past the DMA buffer, causing memory
+corruption.
+
+Add a len > half_key_sz check next to the existing !len check for each
+of the five CRT components so the driver falls back to the non-CRT path
+instead of writing out of bounds.
+
+Fixes: 879f77e9071f ("crypto: qat - Add RSA CRT mode")
+Cc: stable@vger.kernel.org
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Ahsan Atta <ahsan.atta@intel.com>
+Reviewed-by: Laurent M Coquerel <laurent.m.coquerel@intel.com>
+Tested-by: Laurent M Coquerel <laurent.m.coquerel@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/intel/qat/qat_common/qat_asym_algs.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c
++++ b/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c
+@@ -1085,7 +1085,7 @@ static void qat_rsa_setkey_crt(struct qa
+       ptr = rsa_key->p;
+       len = rsa_key->p_sz;
+       qat_rsa_drop_leading_zeros(&ptr, &len);
+-      if (!len)
++      if (!len || len > half_key_sz)
+               goto err;
+       ctx->p = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_p, GFP_KERNEL);
+       if (!ctx->p)
+@@ -1096,7 +1096,7 @@ static void qat_rsa_setkey_crt(struct qa
+       ptr = rsa_key->q;
+       len = rsa_key->q_sz;
+       qat_rsa_drop_leading_zeros(&ptr, &len);
+-      if (!len)
++      if (!len || len > half_key_sz)
+               goto free_p;
+       ctx->q = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_q, GFP_KERNEL);
+       if (!ctx->q)
+@@ -1107,7 +1107,7 @@ static void qat_rsa_setkey_crt(struct qa
+       ptr = rsa_key->dp;
+       len = rsa_key->dp_sz;
+       qat_rsa_drop_leading_zeros(&ptr, &len);
+-      if (!len)
++      if (!len || len > half_key_sz)
+               goto free_q;
+       ctx->dp = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_dp,
+                                    GFP_KERNEL);
+@@ -1119,7 +1119,7 @@ static void qat_rsa_setkey_crt(struct qa
+       ptr = rsa_key->dq;
+       len = rsa_key->dq_sz;
+       qat_rsa_drop_leading_zeros(&ptr, &len);
+-      if (!len)
++      if (!len || len > half_key_sz)
+               goto free_dp;
+       ctx->dq = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_dq,
+                                    GFP_KERNEL);
+@@ -1131,7 +1131,7 @@ static void qat_rsa_setkey_crt(struct qa
+       ptr = rsa_key->qinv;
+       len = rsa_key->qinv_sz;
+       qat_rsa_drop_leading_zeros(&ptr, &len);
+-      if (!len)
++      if (!len || len > half_key_sz)
+               goto free_dq;
+       ctx->qinv = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_qinv,
+                                      GFP_KERNEL);
index bda7ed4b7e9d49fdff7ce732bac228fa28439b62..fbe5be929b91d21fc9668803e136d8999d07f424 100644 (file)
@@ -279,3 +279,7 @@ crypto-ccp-do-not-initialize-snp-for-ioctl-snp_vlek_load.patch
 crypto-drbg-fix-returning-success-on-failure-in-ctr_drbg.patch
 crypto-drbg-fix-drbg_max_addtl-on-64-bit-kernels.patch
 crypto-drbg-fix-the-fips_enabled-priority-boost.patch
+crypto-qat-keep-vfs-enabled-during-reset.patch
+crypto-qat-notify-fatal-error-before-aer-reset-preparation.patch
+crypto-qat-protect-service-table-iterations-with-service_lock.patch
+crypto-qat-validate-rsa-crt-component-lengths.patch