summaryrefslogtreecommitdiff
path: root/drivers/dma/idxd
diff options
context:
space:
mode:
authorYuho Choi <dbgh9129@gmail.com>2026-05-25 10:15:50 -0400
committerVinod Koul <vkoul@kernel.org>2026-07-02 20:49:54 +0530
commitee1d7274102285d78a53161fc705a8d8cd40b066 (patch)
treec27db91076c71c6f7b112bb4a4793369779e591f /drivers/dma/idxd
parentec2d428b2e32dd157de8f86a86dd85c5b2c8f45c (diff)
dmaengine: idxd: fix fdev setup failure cleanup in idxd_cdev_open()
The failed_dev_add and failed_dev_name paths drop the file-device reference while wq->wq_lock is still held. If put_device(fdev) drops the last reference, idxd_file_dev_release() runs synchronously and tries to take wq->wq_lock again, deadlocking. Those paths also fall through into the later ctx cleanup labels even though idxd_file_dev_release() owns that cleanup and frees ctx. This can make idxd_xa_pasid_remove(ctx) and kfree(ctx) operate on a freed context. Move idxd_wq_get() before file-device setup can fail, since the release callback always calls idxd_wq_put(). Then unlock wq->wq_lock before put_device(fdev) and return directly from the file-device setup failure path, leaving ctx cleanup to the release callback. Fixes: e6fd6d7e5f0fe ("dmaengine: idxd: add a device to represent the file opened") Signed-off-by: Yuho Choi <dbgh9129@gmail.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com> Link: https://patch.msgid.link/20260525141550.1385581-1-dbgh9129@gmail.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma/idxd')
-rw-r--r--drivers/dma/idxd/cdev.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c
index 0366c7cf3502..82b07cf942ef 100644
--- a/drivers/dma/idxd/cdev.c
+++ b/drivers/dma/idxd/cdev.c
@@ -288,6 +288,7 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)
fdev->parent = cdev_dev(idxd_cdev);
fdev->bus = &dsa_bus_type;
fdev->type = &idxd_cdev_file_type;
+ idxd_wq_get(wq);
rc = dev_set_name(fdev, "file%d", ctx->id);
if (rc < 0) {
@@ -301,13 +302,14 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)
goto failed_dev_add;
}
- idxd_wq_get(wq);
mutex_unlock(&wq->wq_lock);
return 0;
failed_dev_add:
failed_dev_name:
+ mutex_unlock(&wq->wq_lock);
put_device(fdev);
+ return rc;
failed_ida:
failed_set_pasid:
if (device_user_pasid_enabled(idxd))