From: Greg Kroah-Hartman Date: Wed, 15 Jul 2026 10:24:44 +0000 (+0200) Subject: 6.18-stable patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc45049ebce630b43f99eeffdc155ab7945e0e70;p=thirdparty%2Fkernel%2Fstable-queue.git 6.18-stable patches added patches: crypto-qat-centralize-bus-master-enable.patch crypto-qat-factor-out-aer-reset-helpers.patch crypto-qat-handle-sysfs-triggered-reset-callbacks.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-skip-restart-for-down-devices.patch crypto-qat-validate-rsa-crt-component-lengths.patch --- diff --git a/queue-6.18/crypto-qat-centralize-bus-master-enable.patch b/queue-6.18/crypto-qat-centralize-bus-master-enable.patch new file mode 100644 index 0000000000..b36265f76e --- /dev/null +++ b/queue-6.18/crypto-qat-centralize-bus-master-enable.patch @@ -0,0 +1,197 @@ +From e5712ff82947dd02d118cee119ed36cec671d814 Mon Sep 17 00:00:00 2001 +From: Ahsan Atta +Date: Wed, 13 May 2026 17:16:56 +0200 +Subject: crypto: qat - centralize bus master enable + +From: Ahsan Atta + +commit e5712ff82947dd02d118cee119ed36cec671d814 upstream. + +QAT driver currently toggles PCI bus mastering in multiple places +(probe paths, and reset callbacks). This makes BME state depend on +call ordering and on what PCI command bits were captured in saved PCI +config state. + +Make BME control explicit and deterministic: +- remove pci_set_master() from device-specific probe paths +- add adf_set_bme() and call it from adf_dev_init() so BME is enabled + at one point before device bring-up +- drop redundant pci_set_master() and pci_clear_master from adf_aer.c + and rely on the unified init path for BME enablement + +This is in preparation for adding reset_prepare() and reset_done() +hooks. In the PCI reset callback flow, the PCI core saves and +restores device configuration state around reset_prepare() and +reset_done(). This change is needed to ensure that we are able to +properly shutdown or reinitialize the device post sysfs triggered +resets. + +Cc: stable@vger.kernel.org +Signed-off-by: Ahsan Atta +Reviewed-by: Giovanni Cabiddu +Suggested-by: Andy Shevchenko +Reviewed-by: Andy Shevchenko +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/intel/qat/qat_420xx/adf_drv.c | 2 -- + drivers/crypto/intel/qat/qat_4xxx/adf_drv.c | 2 -- + drivers/crypto/intel/qat/qat_6xxx/adf_drv.c | 2 -- + drivers/crypto/intel/qat/qat_c3xxx/adf_drv.c | 1 - + drivers/crypto/intel/qat/qat_c3xxxvf/adf_drv.c | 1 - + drivers/crypto/intel/qat/qat_c62x/adf_drv.c | 1 - + drivers/crypto/intel/qat/qat_c62xvf/adf_drv.c | 1 - + drivers/crypto/intel/qat/qat_common/adf_aer.c | 10 +++++++--- + drivers/crypto/intel/qat/qat_common/adf_common_drv.h | 1 + + drivers/crypto/intel/qat/qat_common/adf_init.c | 2 ++ + drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c | 1 - + drivers/crypto/intel/qat/qat_dh895xccvf/adf_drv.c | 1 - + 12 files changed, 10 insertions(+), 15 deletions(-) + +--- a/drivers/crypto/intel/qat/qat_420xx/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_420xx/adf_drv.c +@@ -146,8 +146,6 @@ static int adf_probe(struct pci_dev *pde + } + } + +- pci_set_master(pdev); +- + if (pci_save_state(pdev)) { + dev_err(&pdev->dev, "Failed to save pci state.\n"); + ret = -ENOMEM; +--- a/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c +@@ -148,8 +148,6 @@ static int adf_probe(struct pci_dev *pde + } + } + +- pci_set_master(pdev); +- + if (pci_save_state(pdev)) { + dev_err(&pdev->dev, "Failed to save pci state.\n"); + ret = -ENOMEM; +--- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +@@ -162,8 +162,6 @@ static int adf_probe(struct pci_dev *pde + } + } + +- pci_set_master(pdev); +- + /* + * The PCI config space is saved at this point and will be restored + * after a Function Level Reset (FLR) as the FLR does not completely +--- a/drivers/crypto/intel/qat/qat_c3xxx/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_c3xxx/adf_drv.c +@@ -167,7 +167,6 @@ static int adf_probe(struct pci_dev *pde + goto out_err_free_reg; + } + } +- pci_set_master(pdev); + + if (pci_save_state(pdev)) { + dev_err(&pdev->dev, "Failed to save pci state\n"); +--- a/drivers/crypto/intel/qat/qat_c3xxxvf/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_c3xxxvf/adf_drv.c +@@ -163,7 +163,6 @@ static int adf_probe(struct pci_dev *pde + goto out_err_free_reg; + } + } +- pci_set_master(pdev); + /* Completion for VF2PF request/response message exchange */ + init_completion(&accel_dev->vf.msg_received); + +--- a/drivers/crypto/intel/qat/qat_c62x/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_c62x/adf_drv.c +@@ -167,7 +167,6 @@ static int adf_probe(struct pci_dev *pde + goto out_err_free_reg; + } + } +- pci_set_master(pdev); + + if (pci_save_state(pdev)) { + dev_err(&pdev->dev, "Failed to save pci state\n"); +--- a/drivers/crypto/intel/qat/qat_c62xvf/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_c62xvf/adf_drv.c +@@ -163,7 +163,6 @@ static int adf_probe(struct pci_dev *pde + goto out_err_free_reg; + } + } +- pci_set_master(pdev); + /* Completion for VF2PF request/response message exchange */ + init_completion(&accel_dev->vf.msg_received); + +--- a/drivers/crypto/intel/qat/qat_common/adf_aer.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_aer.c +@@ -41,7 +41,6 @@ static pci_ers_result_t adf_error_detect + 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); + + return PCI_ERS_RESULT_NEED_RESET; +@@ -106,6 +105,13 @@ void adf_dev_restore(struct adf_accel_de + } + } + ++void adf_set_bme(struct adf_accel_dev *accel_dev) ++{ ++ struct pci_dev *pdev = accel_to_pci_dev(accel_dev); ++ ++ pci_set_master(pdev); ++} ++ + static void adf_device_sriov_worker(struct work_struct *work) + { + struct adf_sriov_dev_data *sriov_data = +@@ -198,8 +204,6 @@ static pci_ers_result_t adf_slot_reset(s + return PCI_ERS_RESULT_DISCONNECT; + } + +- if (!pdev->is_busmaster) +- pci_set_master(pdev); + pci_restore_state(pdev); + res = adf_dev_up(accel_dev, false); + if (res && res != -EALREADY) +--- a/drivers/crypto/intel/qat/qat_common/adf_common_drv.h ++++ b/drivers/crypto/intel/qat/qat_common/adf_common_drv.h +@@ -84,6 +84,7 @@ extern const struct pci_error_handlers a + void adf_reset_sbr(struct adf_accel_dev *accel_dev); + void adf_reset_flr(struct adf_accel_dev *accel_dev); + void adf_dev_restore(struct adf_accel_dev *accel_dev); ++void adf_set_bme(struct adf_accel_dev *accel_dev); + int adf_init_aer(void); + void adf_exit_aer(void); + int adf_init_arb(struct adf_accel_dev *accel_dev); +--- a/drivers/crypto/intel/qat/qat_common/adf_init.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_init.c +@@ -73,6 +73,8 @@ static int adf_dev_init(struct adf_accel + return -EFAULT; + } + ++ adf_set_bme(accel_dev); ++ + if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status) && + !accel_dev->is_vf) { + dev_err(&GET_DEV(accel_dev), "Device not configured\n"); +--- a/drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c +@@ -167,7 +167,6 @@ static int adf_probe(struct pci_dev *pde + goto out_err_free_reg; + } + } +- pci_set_master(pdev); + + if (pci_save_state(pdev)) { + dev_err(&pdev->dev, "Failed to save pci state\n"); +--- a/drivers/crypto/intel/qat/qat_dh895xccvf/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_dh895xccvf/adf_drv.c +@@ -163,7 +163,6 @@ static int adf_probe(struct pci_dev *pde + goto out_err_free_reg; + } + } +- pci_set_master(pdev); + /* Completion for VF2PF request/response message exchange */ + init_completion(&accel_dev->vf.msg_received); + diff --git a/queue-6.18/crypto-qat-factor-out-aer-reset-helpers.patch b/queue-6.18/crypto-qat-factor-out-aer-reset-helpers.patch new file mode 100644 index 0000000000..917ca8cde5 --- /dev/null +++ b/queue-6.18/crypto-qat-factor-out-aer-reset-helpers.patch @@ -0,0 +1,148 @@ +From 56707afb92fee371c0f2e04332c9aa03cdb89793 Mon Sep 17 00:00:00 2001 +From: Ahsan Atta +Date: Wed, 13 May 2026 17:16:58 +0200 +Subject: crypto: qat - factor out AER reset helpers + +From: Ahsan Atta + +commit 56707afb92fee371c0f2e04332c9aa03cdb89793 upstream. + +Move the shutdown and recovery sequences out of adf_error_detected() +and adf_slot_reset() into reset_prepare() and reset_done() helpers. + +This makes the AER recovery path easier to follow and prepares the +common reset flow for reuse by additional PCI reset callbacks without +duplicating the logic. + +No functional change intended. + +Cc: stable@vger.kernel.org +Signed-off-by: Ahsan Atta +Reviewed-by: Giovanni Cabiddu +Reviewed-by: Damian Muszynski +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/intel/qat/qat_common/adf_aer.c | 86 ++++++++++++++++---------- + 1 file changed, 53 insertions(+), 33 deletions(-) + +--- a/drivers/crypto/intel/qat/qat_common/adf_aer.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_aer.c +@@ -17,27 +17,18 @@ struct adf_fatal_error_data { + static struct workqueue_struct *device_reset_wq; + static struct workqueue_struct *device_sriov_wq; + +-static pci_ers_result_t adf_error_detected(struct pci_dev *pdev, +- pci_channel_state_t state) ++static pci_ers_result_t reset_prepare(struct pci_dev *pdev) + { + struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev); + +- dev_info(&pdev->dev, "Acceleration driver hardware error detected.\n"); + if (!accel_dev) { + dev_err(&pdev->dev, "Can't find acceleration device\n"); + return PCI_ERS_RESULT_DISCONNECT; + } + +- if (state == pci_channel_io_perm_failure) { +- dev_err(&pdev->dev, "Can't recover from device error\n"); +- return PCI_ERS_RESULT_DISCONNECT; +- } +- + if (!adf_dev_started(accel_dev)) + return PCI_ERS_RESULT_CAN_RECOVER; + +- 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"); +@@ -49,6 +40,57 @@ static pci_ers_result_t adf_error_detect + return PCI_ERS_RESULT_NEED_RESET; + } + ++static pci_ers_result_t reset_done(struct pci_dev *pdev) ++{ ++ struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev); ++ int res; ++ ++ if (!accel_dev) { ++ dev_err(&pdev->dev, "Can't find acceleration device\n"); ++ return PCI_ERS_RESULT_DISCONNECT; ++ } ++ ++ if (!adf_devmgr_in_reset(accel_dev)) ++ goto reset_complete; ++ ++ pci_restore_state(pdev); ++ res = adf_dev_up(accel_dev, false); ++ if (res && res != -EALREADY) ++ return PCI_ERS_RESULT_DISCONNECT; ++ ++ adf_reenable_sriov(accel_dev); ++ adf_pf2vf_notify_restarted(accel_dev); ++ adf_dev_restarted_notify(accel_dev); ++ clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status); ++ ++reset_complete: ++ dev_info(&pdev->dev, "Device reset completed successfully\n"); ++ ++ return PCI_ERS_RESULT_RECOVERED; ++} ++ ++static pci_ers_result_t adf_error_detected(struct pci_dev *pdev, ++ pci_channel_state_t state) ++{ ++ struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev); ++ ++ dev_info(&pdev->dev, "Acceleration driver hardware error detected.\n"); ++ if (!accel_dev) { ++ dev_err(&pdev->dev, "Can't find acceleration device\n"); ++ return PCI_ERS_RESULT_DISCONNECT; ++ } ++ ++ if (state == pci_channel_io_perm_failure) { ++ dev_err(&pdev->dev, "Can't recover from device error\n"); ++ return PCI_ERS_RESULT_DISCONNECT; ++ } ++ ++ adf_error_notifier(accel_dev); ++ adf_pf2vf_notify_fatal_error(accel_dev); ++ ++ return reset_prepare(pdev); ++} ++ + /* reset dev data */ + struct adf_reset_dev_data { + int mode; +@@ -199,29 +241,7 @@ static int adf_dev_aer_schedule_reset(st + + static pci_ers_result_t adf_slot_reset(struct pci_dev *pdev) + { +- struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev); +- int res = 0; +- +- if (!accel_dev) { +- pr_err("QAT: Can't find acceleration device\n"); +- return PCI_ERS_RESULT_DISCONNECT; +- } +- +- if (!adf_devmgr_in_reset(accel_dev)) +- goto reset_complete; +- +- pci_restore_state(pdev); +- res = adf_dev_up(accel_dev, false); +- if (res && res != -EALREADY) +- return PCI_ERS_RESULT_DISCONNECT; +- +- adf_reenable_sriov(accel_dev); +- adf_pf2vf_notify_restarted(accel_dev); +- adf_dev_restarted_notify(accel_dev); +- clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status); +- +-reset_complete: +- return PCI_ERS_RESULT_RECOVERED; ++ return reset_done(pdev); + } + + static void adf_resume(struct pci_dev *pdev) diff --git a/queue-6.18/crypto-qat-handle-sysfs-triggered-reset-callbacks.patch b/queue-6.18/crypto-qat-handle-sysfs-triggered-reset-callbacks.patch new file mode 100644 index 0000000000..b6b4a435d0 --- /dev/null +++ b/queue-6.18/crypto-qat-handle-sysfs-triggered-reset-callbacks.patch @@ -0,0 +1,54 @@ +From 4627ef7019bc532f992c0723e881811ce12f0a02 Mon Sep 17 00:00:00 2001 +From: Ahsan Atta +Date: Wed, 13 May 2026 17:16:59 +0200 +Subject: crypto: qat - handle sysfs-triggered reset callbacks + +From: Ahsan Atta + +commit 4627ef7019bc532f992c0723e881811ce12f0a02 upstream. + +A reset requested through /sys/bus/pci/devices/.../reset invokes the +driver reset_prepare() and reset_done() callbacks. The QAT driver does +not implement those callbacks today, so the reset proceeds without +quiescing the device or bringing it back up afterward, which leaves +the device unusable. + +Hook reset_prepare() and reset_done() into adf_err_handler so the +common shutdown and recovery flow also runs for reset. Skip device +quiesce if the device is already in a down state. + +Cc: stable@vger.kernel.org +Signed-off-by: Ahsan Atta +Reviewed-by: Giovanni Cabiddu +Reviewed-by: Damian Muszynski +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/intel/qat/qat_common/adf_aer.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/crypto/intel/qat/qat_common/adf_aer.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_aer.c +@@ -222,10 +222,22 @@ static void adf_resume(struct pci_dev *p + dev_info(&pdev->dev, "Device is up and running\n"); + } + ++static void adf_reset_prepare(struct pci_dev *pdev) ++{ ++ reset_prepare(pdev); ++} ++ ++static void adf_reset_done(struct pci_dev *pdev) ++{ ++ reset_done(pdev); ++} ++ + const struct pci_error_handlers adf_err_handler = { + .error_detected = adf_error_detected, + .slot_reset = adf_slot_reset, + .resume = adf_resume, ++ .reset_prepare = adf_reset_prepare, ++ .reset_done = adf_reset_done, + }; + EXPORT_SYMBOL_GPL(adf_err_handler); + diff --git a/queue-6.18/crypto-qat-keep-vfs-enabled-during-reset.patch b/queue-6.18/crypto-qat-keep-vfs-enabled-during-reset.patch new file mode 100644 index 0000000000..e3687efa1e --- /dev/null +++ b/queue-6.18/crypto-qat-keep-vfs-enabled-during-reset.patch @@ -0,0 +1,68 @@ +From 57518500053987672050dc2f7bf8a774d5d52fd9 Mon Sep 17 00:00:00 2001 +From: Ahsan Atta +Date: Wed, 13 May 2026 17:16:54 +0200 +Subject: crypto: qat - keep VFs enabled during reset + +From: Ahsan Atta + +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 +Reviewed-by: Giovanni Cabiddu +Reviewed-by: Damian Muszynski +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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.18/crypto-qat-notify-fatal-error-before-aer-reset-preparation.patch b/queue-6.18/crypto-qat-notify-fatal-error-before-aer-reset-preparation.patch new file mode 100644 index 0000000000..82e3aaf88d --- /dev/null +++ b/queue-6.18/crypto-qat-notify-fatal-error-before-aer-reset-preparation.patch @@ -0,0 +1,45 @@ +From 6931835f2fdd0cb9b1c7791748d7e67d0749056a Mon Sep 17 00:00:00 2001 +From: Ahsan Atta +Date: Wed, 13 May 2026 17:16:55 +0200 +Subject: crypto: qat - notify fatal error before AER reset preparation + +From: Ahsan Atta + +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 +Reviewed-by: Giovanni Cabiddu +Reviewed-by: Damian Muszynski +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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); + adf_dev_down(accel_dev); + diff --git a/queue-6.18/crypto-qat-protect-service-table-iterations-with-service_lock.patch b/queue-6.18/crypto-qat-protect-service-table-iterations-with-service_lock.patch new file mode 100644 index 0000000000..a316334166 --- /dev/null +++ b/queue-6.18/crypto-qat-protect-service-table-iterations-with-service_lock.patch @@ -0,0 +1,156 @@ +From 5c6f845e77ec35f9b7b047cc8f9789bf397cdd3e Mon Sep 17 00:00:00 2001 +From: Ahsan Atta +Date: Wed, 20 May 2026 13:41:55 +0100 +Subject: crypto: qat - protect service table iterations with service_lock + +From: Ahsan Atta + +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 +Co-developed-by: Maksim Lukoshkov +Signed-off-by: Maksim Lukoshkov +Reviewed-by: Giovanni Cabiddu +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -154,15 +154,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; + } +@@ -231,15 +234,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); +@@ -310,6 +316,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; +@@ -321,6 +328,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); +@@ -370,6 +378,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; +@@ -380,6 +389,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); + +@@ -414,12 +424,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; + } + +@@ -427,12 +439,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; + } + +@@ -440,12 +454,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.18/crypto-qat-skip-restart-for-down-devices.patch b/queue-6.18/crypto-qat-skip-restart-for-down-devices.patch new file mode 100644 index 0000000000..6f3a369e17 --- /dev/null +++ b/queue-6.18/crypto-qat-skip-restart-for-down-devices.patch @@ -0,0 +1,58 @@ +From 9676657117b79f88c22875680c36d7da84b75eca Mon Sep 17 00:00:00 2001 +From: Ahsan Atta +Date: Wed, 13 May 2026 17:16:57 +0200 +Subject: crypto: qat - skip restart for down devices + +From: Ahsan Atta + +commit 9676657117b79f88c22875680c36d7da84b75eca upstream. + +Skip the shutdown and restart flow when adf_slot_reset() is entered +for a device that is already down. In that case, leave +ADF_STATUS_RESTARTING clear and let adf_slot_reset() restore PCI +function state without calling adf_dev_up(), re-enabling SR-IOV, or +sending restarted notifications. + +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 +Reviewed-by: Giovanni Cabiddu +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/intel/qat/qat_common/adf_aer.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/crypto/intel/qat/qat_common/adf_aer.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_aer.c +@@ -33,6 +33,9 @@ static pci_ers_result_t adf_error_detect + return PCI_ERS_RESULT_DISCONNECT; + } + ++ if (!adf_dev_started(accel_dev)) ++ return PCI_ERS_RESULT_CAN_RECOVER; ++ + adf_error_notifier(accel_dev); + adf_pf2vf_notify_fatal_error(accel_dev); + set_bit(ADF_STATUS_RESTARTING, &accel_dev->status); +@@ -204,6 +207,9 @@ static pci_ers_result_t adf_slot_reset(s + return PCI_ERS_RESULT_DISCONNECT; + } + ++ if (!adf_devmgr_in_reset(accel_dev)) ++ goto reset_complete; ++ + pci_restore_state(pdev); + res = adf_dev_up(accel_dev, false); + if (res && res != -EALREADY) +@@ -213,6 +219,8 @@ static pci_ers_result_t adf_slot_reset(s + adf_pf2vf_notify_restarted(accel_dev); + adf_dev_restarted_notify(accel_dev); + clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status); ++ ++reset_complete: + return PCI_ERS_RESULT_RECOVERED; + } + diff --git a/queue-6.18/crypto-qat-validate-rsa-crt-component-lengths.patch b/queue-6.18/crypto-qat-validate-rsa-crt-component-lengths.patch new file mode 100644 index 0000000000..a61cfdb2af --- /dev/null +++ b/queue-6.18/crypto-qat-validate-rsa-crt-component-lengths.patch @@ -0,0 +1,83 @@ +From b3ac78756588059729b9195fcc9f4b37d54057a5 Mon Sep 17 00:00:00 2001 +From: Giovanni Cabiddu +Date: Thu, 28 May 2026 16:57:44 +0100 +Subject: crypto: qat - validate RSA CRT component lengths + +From: Giovanni Cabiddu + +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 +Reviewed-by: Ahsan Atta +Reviewed-by: Laurent M Coquerel +Tested-by: Laurent M Coquerel +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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); diff --git a/queue-6.18/series b/queue-6.18/series index bae483a40f..a3a0884d05 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -360,4 +360,12 @@ crypto-ccp-do-not-initialize-snp-for-ioctl-snp_config.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-centralize-bus-master-enable.patch +crypto-qat-handle-sysfs-triggered-reset-callbacks.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-skip-restart-for-down-devices.patch +crypto-qat-validate-rsa-crt-component-lengths.patch +crypto-qat-factor-out-aer-reset-helpers.patch crypto-loongson-remove-broken-and-unused-loongson-rng.patch