The return value of init_srcu_struct() is currently ignored. If
initialization fails, subsequent use of hwctx_srcu may result in invalid
memory accesses.

Check the return value of init_srcu_struct() and propagate the error to
the caller.

Fixes: aac243092b70 ("accel/amdxdna: Add command execution")
Signed-off-by: Lizhi Hou <[email protected]>
---
 drivers/accel/amdxdna/amdxdna_pci_drv.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c 
b/drivers/accel/amdxdna/amdxdna_pci_drv.c
index 86e9c230875a..bb339e641416 100644
--- a/drivers/accel/amdxdna/amdxdna_pci_drv.c
+++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c
@@ -109,11 +109,16 @@ static int amdxdna_drm_open(struct drm_device *ddev, 
struct drm_file *filp)
 {
        struct amdxdna_dev *xdna = to_xdna_dev(ddev);
        struct amdxdna_client *client;
+       int ret;
 
        client = kzalloc_obj(*client);
        if (!client)
                return -ENOMEM;
 
+       ret = init_srcu_struct(&client->hwctx_srcu);
+       if (ret)
+               goto free_client;
+
        client->pid = pid_nr(rcu_access_pointer(filp->pid));
        client->xdna = xdna;
        client->pasid = IOMMU_PASID_INVALID;
@@ -125,13 +130,12 @@ static int amdxdna_drm_open(struct drm_device *ddev, 
struct drm_file *filp)
                        XDNA_WARN(xdna, "PASID not available for pid %d", 
client->pid);
                        if (!amdxdna_use_carveout(xdna)) {
                                XDNA_ERR(xdna, "PASID unavailable and carveout 
not configured");
-                               kfree(client);
-                               return -EINVAL;
+                               ret = -EINVAL;
+                               goto cleanup_srcu;
                        }
                }
        }
        mmgrab(client->mm);
-       init_srcu_struct(&client->hwctx_srcu);
        xa_init_flags(&client->hwctx_xa, XA_FLAGS_ALLOC);
        xa_init_flags(&client->dev_heap_xa, XA_FLAGS_ALLOC);
        drm_mm_init(&client->dev_heap_mm, xdna->dev_info->dev_mem_base,
@@ -149,6 +153,12 @@ static int amdxdna_drm_open(struct drm_device *ddev, 
struct drm_file *filp)
 
        XDNA_DBG(xdna, "pid %d opened", client->pid);
        return 0;
+
+cleanup_srcu:
+       cleanup_srcu_struct(&client->hwctx_srcu);
+free_client:
+       kfree(client);
+       return ret;
 }
 
 static void amdxdna_client_cleanup(struct amdxdna_client *client)
-- 
2.34.1

Reply via email to