]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
crypto: qat - flush misc workqueue during device shutdown
authorGiovanni Cabiddu <giovanni.cabiddu@intel.com>
Fri, 23 Jan 2026 03:24:22 +0000 (03:24 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 6 Feb 2026 15:44:23 +0000 (16:44 +0100)
[ Upstream commit 3d4df408ba9bad2b205c7fb8afc1836a6a4ca88a ]

Repeated loading and unloading of a device specific QAT driver, for
example qat_4xxx, in a tight loop can lead to a crash due to a
use-after-free scenario. This occurs when a power management (PM)
interrupt triggers just before the device-specific driver (e.g.,
qat_4xxx.ko) is unloaded, while the core driver (intel_qat.ko) remains
loaded.

Since the driver uses a shared workqueue (`qat_misc_wq`) across all
devices and owned by intel_qat.ko, a deferred routine from the
device-specific driver may still be pending in the queue. If this
routine executes after the driver is unloaded, it can dereference freed
memory, resulting in a page fault and kernel crash like the following:

    BUG: unable to handle page fault for address: ffa000002e50a01c
    #PF: supervisor read access in kernel mode
    RIP: 0010:pm_bh_handler+0x1d2/0x250 [intel_qat]
    Call Trace:
      pm_bh_handler+0x1d2/0x250 [intel_qat]
      process_one_work+0x171/0x340
      worker_thread+0x277/0x3a0
      kthread+0xf0/0x120
      ret_from_fork+0x2d/0x50

To prevent this, flush the misc workqueue during device shutdown to
ensure that all pending work items are completed before the driver is
unloaded.

Note: This approach may slightly increase shutdown latency if the
workqueue contains jobs from other devices, but it ensures correctness
and stability.

Fixes: e5745f34113b ("crypto: qat - enable power management for QAT GEN4")
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Cc: stable@vger.kernel.org
Reviewed-by: Ahsan Atta <ahsan.atta@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
[ Intel crypto drivers was moved by
  a4b16dad4657 ("crypto: qat - Move driver to drivers/crypto/intel/qat")
  so apply the patch to files under drivers/crypto/qat/qat_common in
  6.1.y. ]
Signed-off-by: Wenshan Lan <jetlan9@163.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/crypto/qat/qat_common/adf_common_drv.h
drivers/crypto/qat/qat_common/adf_init.c
drivers/crypto/qat/qat_common/adf_isr.c

index d2bc2361cd0697b3c4e567a58319bbb2a6a2fcc5..86aebe07db4484b6dec2ffc495dc03de08909a3e 100644 (file)
@@ -194,6 +194,7 @@ int qat_uclo_set_cfg_ae_mask(struct icp_qat_fw_loader_handle *handle,
 int adf_init_misc_wq(void);
 void adf_exit_misc_wq(void);
 bool adf_misc_wq_queue_work(struct work_struct *work);
+void adf_misc_wq_flush(void);
 #if defined(CONFIG_PCI_IOV)
 int adf_sriov_configure(struct pci_dev *pdev, int numvfs);
 void adf_disable_sriov(struct adf_accel_dev *accel_dev);
index 49f07584f8c9f38ce8e11f7d75628d5f9ddb8ac6..9d54dc3beafd5f56cf3a9af97aac32051baf16e0 100644 (file)
@@ -337,6 +337,7 @@ void adf_dev_shutdown(struct adf_accel_dev *accel_dev)
                hw_data->exit_admin_comms(accel_dev);
 
        adf_cleanup_etr_data(accel_dev);
+       adf_misc_wq_flush();
        adf_dev_restore(accel_dev);
 }
 EXPORT_SYMBOL_GPL(adf_dev_shutdown);
index ad9e135b8560b6dcf6e941ebd5176f70147aa7e4..e41ae70d69edb17f11220f7dcb3e1c27fecd60fd 100644 (file)
@@ -380,3 +380,8 @@ bool adf_misc_wq_queue_work(struct work_struct *work)
 {
        return queue_work(adf_misc_wq, work);
 }
+
+void adf_misc_wq_flush(void)
+{
+       flush_workqueue(adf_misc_wq);
+}