mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
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: e486147c91 ("accel/amdxdna: Add BO import and export")
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
Link: https://patch.msgid.link/20260611055150.3070216-2-lizhi.hou@amd.com
This commit is contained in:
@@ -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 @@ static int amdxdna_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user