In msm_gem_vm_sm_step_remap(), a temporary reference on vm_bo is
acquired via drm_gpuvm_bo_get() to keep the object alive during
vma close and creation. On success, the reference is released with
drm_gpuvm_bo_put(). However, when vma_from_op() fails for prev_vma
or next_vma, the function returns directly without releasing the
reference, causing a leak.

Fix by converting the error returns to a common error path that
releases the temporary reference before returning.

Cc: [email protected]
Fixes: 2e6a8a1fe2b2 ("drm/msm: Add VM_BIND ioctl")
Signed-off-by: Wentao Liang <[email protected]>
---
 drivers/gpu/drm/msm/msm_gem_vma.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c 
b/drivers/gpu/drm/msm/msm_gem_vma.c
index 1a952b171ed7..69289bea7a66 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -602,8 +602,10 @@ msm_gem_vm_sm_step_remap(struct drm_gpuva_op *op, void 
*arg)
 
        if (op->remap.prev) {
                prev_vma = vma_from_op(arg, op->remap.prev);
-               if (WARN_ON(IS_ERR(prev_vma)))
-                       return PTR_ERR(prev_vma);
+               if (WARN_ON(IS_ERR(prev_vma))) {
+                       ret = PTR_ERR(prev_vma);
+                       goto drop_ref;
+               }
 
                vm_dbg("prev_vma: %p:%p: %016llx %016llx", vm, prev_vma, 
prev_vma->va.addr, prev_vma->va.range);
                to_msm_vma(prev_vma)->mapped = mapped;
@@ -612,8 +614,10 @@ msm_gem_vm_sm_step_remap(struct drm_gpuva_op *op, void 
*arg)
 
        if (op->remap.next) {
                next_vma = vma_from_op(arg, op->remap.next);
-               if (WARN_ON(IS_ERR(next_vma)))
-                       return PTR_ERR(next_vma);
+               if (WARN_ON(IS_ERR(next_vma))) {
+                       ret = PTR_ERR(next_vma);
+                       goto drop_ref;
+               }
 
                vm_dbg("next_vma: %p:%p: %016llx %016llx", vm, next_vma, 
next_vma->va.addr, next_vma->va.range);
                to_msm_vma(next_vma)->mapped = mapped;
@@ -623,6 +627,7 @@ msm_gem_vm_sm_step_remap(struct drm_gpuva_op *op, void *arg)
        if (!mapped)
                drm_gpuvm_bo_evict(vm_bo, true);
 
+drop_ref:
        /* Drop the previous ref: */
        drm_gpuvm_bo_put(vm_bo);
 
-- 
2.34.1

Reply via email to