If a buffer is pinned successfully but the mapping is never recorded in
job->unpins, host1x_job_unpin() cannot release it. This happens when a
relocation buffer is discontiguous (map->chunks > 1) and when
alloc_iova() or iommu_map_sgtable() fail while mapping a gather
buffer's IOVA, leaking the mapping and the buffer object reference it
holds.

Unpin the mapping before jumping to the shared error labels.

Fixes: c6aeaf56f468 ("drm/tegra: Implement correct DMA-BUF semantics")
Cc: [email protected]
Signed-off-by: Wentao Liang <[email protected]>
---
 drivers/gpu/host1x/job.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index 3ed49e1fd933..675e7dde7e38 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -193,6 +193,7 @@ static unsigned int pin_job(struct host1x *host, struct 
host1x_job *job)
                 * contiguous chunk of I/O virtual memory.
                 */
                if (map->chunks > 1) {
+                       host1x_bo_unpin(map);
                        err = -EINVAL;
                        goto unpin;
                }
@@ -244,6 +245,7 @@ static unsigned int pin_job(struct host1x *host, struct 
host1x_job *job)
                        alloc = alloc_iova(&host->iova, gather_size >> shift,
                                           host->iova_end >> shift, true);
                        if (!alloc) {
+                               host1x_bo_unpin(map);
                                err = -ENOMEM;
                                goto put;
                        }
@@ -252,6 +254,7 @@ static unsigned int pin_job(struct host1x *host, struct 
host1x_job *job)
                                                map->sgt, IOMMU_READ);
                        if (err == 0) {
                                __free_iova(&host->iova, alloc);
+                               host1x_bo_unpin(map);
                                err = -EINVAL;
                                goto put;
                        }
-- 
2.34.1

Reply via email to