If we fail a handle-lookup part way thru, we need to drop the already
obtained obj references.

Fixes: 2e6a8a1fe2b2 ("drm/msm: Add VM_BIND ioctl")
Signed-off-by: Rob Clark <robin.cl...@oss.qualcomm.com>
Tested-by: Connor Abbott <cwabbo...@gmail.com>
---
 drivers/gpu/drm/msm/msm_gem_vma.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c 
b/drivers/gpu/drm/msm/msm_gem_vma.c
index 00d0f3b7ba32..209154be5efc 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -1023,6 +1023,7 @@ vm_bind_job_lookup_ops(struct msm_vm_bind_job *job, 
struct drm_msm_vm_bind *args
        struct drm_device *dev = job->vm->drm;
        int ret = 0;
        int cnt = 0;
+       int i = -1;
 
        if (args->nr_ops == 1) {
                /* Single op case, the op is inlined: */
@@ -1056,11 +1057,12 @@ vm_bind_job_lookup_ops(struct msm_vm_bind_job *job, 
struct drm_msm_vm_bind *args
 
        spin_lock(&file->table_lock);
 
-       for (unsigned i = 0; i < args->nr_ops; i++) {
+       for (i = 0; i < args->nr_ops; i++) {
+               struct msm_vm_bind_op *op = &job->ops[i];
                struct drm_gem_object *obj;
 
-               if (!job->ops[i].handle) {
-                       job->ops[i].obj = NULL;
+               if (!op->handle) {
+                       op->obj = NULL;
                        continue;
                }
 
@@ -1068,15 +1070,15 @@ vm_bind_job_lookup_ops(struct msm_vm_bind_job *job, 
struct drm_msm_vm_bind *args
                 * normally use drm_gem_object_lookup(), but for bulk lookup
                 * all under single table_lock just hit object_idr directly:
                 */
-               obj = idr_find(&file->object_idr, job->ops[i].handle);
+               obj = idr_find(&file->object_idr, op->handle);
                if (!obj) {
-                       ret = UERR(EINVAL, dev, "invalid handle %u at index 
%u\n", job->ops[i].handle, i);
+                       ret = UERR(EINVAL, dev, "invalid handle %u at index 
%u\n", op->handle, i);
                        goto out_unlock;
                }
 
                drm_gem_object_get(obj);
 
-               job->ops[i].obj = obj;
+               op->obj = obj;
                cnt++;
        }
 
@@ -1085,6 +1087,17 @@ vm_bind_job_lookup_ops(struct msm_vm_bind_job *job, 
struct drm_msm_vm_bind *args
 out_unlock:
        spin_unlock(&file->table_lock);
 
+       if (ret) {
+               for (; i >= 0; i--) {
+                       struct msm_vm_bind_op *op = &job->ops[i];
+
+                       if (!op->obj)
+                               continue;
+
+                       drm_gem_object_put(op->obj);
+                       op->obj = NULL;
+               }
+       }
 out:
        return ret;
 }
-- 
2.50.1

Reply via email to