[PATCH] gpu: host1x: Fix buffer object mapping leak in pin_job()

Wentao Liang posted 1 patch 1 week, 1 day ago
drivers/gpu/host1x/job.c | 3 +++
1 file changed, 3 insertions(+)
[PATCH] gpu: host1x: Fix buffer object mapping leak in pin_job()
Posted by Wentao Liang 1 week, 1 day ago
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: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
---
 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