v3d_rewrite_csd_job_wg_counts_from_indirect() maps both the indirect
buffer and the workgroup buffer and is expected to release them before
returning. When any of the workgroup counts read from the buffer is zero,
the function bailed out early and skipped the cleanup, leaking the vaddr
mappings of both BOs.

Jump to the cleanup path instead of returning directly, so the mappings
are always dropped.

Cc: [email protected]
Fixes: 18b8413b25b7 ("drm/v3d: Create a CPU job extension for a indirect CSD 
job")
Suggested-by: Jose Maria Casanova Crespo <[email protected]>
Signed-off-by: Maíra Canal <[email protected]>
Reviewed-by: Iago Toral Quiroga <[email protected]>
---
 drivers/gpu/drm/v3d/v3d_sched.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c
index 94bf628dc91c..47f83936cd73 100644
--- a/drivers/gpu/drm/v3d/v3d_sched.c
+++ b/drivers/gpu/drm/v3d/v3d_sched.c
@@ -403,7 +403,7 @@ v3d_rewrite_csd_job_wg_counts_from_indirect(struct 
v3d_cpu_job *job)
        wg_counts = (uint32_t *)(bo->vaddr + indirect_csd->offset);
 
        if (wg_counts[0] == 0 || wg_counts[1] == 0 || wg_counts[2] == 0)
-               return;
+               goto unmap_bo;
 
        args->cfg[0] = wg_counts[0] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
        args->cfg[1] = wg_counts[1] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
@@ -428,6 +428,7 @@ v3d_rewrite_csd_job_wg_counts_from_indirect(struct 
v3d_cpu_job *job)
                }
        }
 
+unmap_bo:
        v3d_put_bo_vaddr(indirect);
        v3d_put_bo_vaddr(bo);
 }

-- 
2.54.0

Reply via email to