From: Lizhi Hou Date: Thu, 11 Jun 2026 05:51:49 +0000 (-0700) Subject: accel/amdxdna: Fix notifier_wq lifetime race during device removal X-Git-Tag: v7.2-rc2~10^2^2~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5c72124186d6983e90b7c44229fcb768e3ff769a;p=thirdparty%2Fkernel%2Flinux.git accel/amdxdna: Fix notifier_wq lifetime race during device removal amdxdna_remove() destroys notifier_wq. If amdxdna_gem_obj_free() is called after device removal, it may attempt to flush notifier_wq, resulting in a use-after-free. Fix the race by allocating notifier_wq with drmm_alloc_ordered_workqueue(), so its lifetime is managed by DRM and remains valid until all managed resources are released. Fixes: e486147c912f ("accel/amdxdna: Add BO import and export") Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Lizhi Hou Link: https://patch.msgid.link/20260611055150.3070216-2-lizhi.hou@amd.com --- diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c index 593766682940..e94d8290a807 100644 --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c @@ -392,9 +392,9 @@ static int amdxdna_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) return ret; - xdna->notifier_wq = alloc_ordered_workqueue("notifier_wq", WQ_MEM_RECLAIM); - if (!xdna->notifier_wq) { - ret = -ENOMEM; + xdna->notifier_wq = drmm_alloc_ordered_workqueue(ddev, "notifier_wq", WQ_MEM_RECLAIM); + if (IS_ERR(xdna->notifier_wq)) { + ret = PTR_ERR(xdna->notifier_wq); goto iommu_fini; } @@ -403,7 +403,7 @@ static int amdxdna_probe(struct pci_dev *pdev, const struct pci_device_id *id) mutex_unlock(&xdna->dev_lock); if (ret) { XDNA_ERR(xdna, "Hardware init failed, ret %d", ret); - goto destroy_notifier_wq; + goto iommu_fini; } ret = amdxdna_sysfs_init(xdna); @@ -427,8 +427,6 @@ failed_dev_fini: mutex_lock(&xdna->dev_lock); xdna->dev_info->ops->fini(xdna); mutex_unlock(&xdna->dev_lock); -destroy_notifier_wq: - destroy_workqueue(xdna->notifier_wq); iommu_fini: amdxdna_iommu_fini(xdna); return ret; @@ -439,8 +437,6 @@ static void amdxdna_remove(struct pci_dev *pdev) struct amdxdna_dev *xdna = pci_get_drvdata(pdev); struct amdxdna_client *client; - destroy_workqueue(xdna->notifier_wq); - drm_dev_unplug(&xdna->ddev); amdxdna_sysfs_fini(xdna);