Commit 50e5a3f7 authored by Boris Brezillon's avatar Boris Brezillon Committed by Cui GaoSheng
Browse files

drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr()

stable inclusion
from stable-v6.6.28
commit 31806711e8a4b75e09b1c43652f2a6420e6e1002
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9QRMU
CVE: CVE-2024-35951

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=31806711e8a4b75e09b1c43652f2a6420e6e1002



--------------------------------

commit 1fc9af813b25e146d3607669247d0f970f5a87c3 upstream.

Subject: drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr()

If some the pages or sgt allocation failed, we shouldn't release the
pages ref we got earlier, otherwise we will end up with unbalanced
get/put_pages() calls. We should instead leave everything in place
and let the BO release function deal with extra cleanup when the object
is destroyed, or let the fault handler try again next time it's called.

Fixes: 187d2929 ("drm/panfrost: Add support for GPU heap allocations")
Cc: <stable@vger.kernel.org>
Reviewed-by: default avatarSteven Price <steven.price@arm.com>
Reviewed-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Co-developed-by: default avatarDmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: default avatarDmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240105184624.508603-18-dmitry.osipenko@collabora.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>

Conflicts:
            drivers/gpu/drm/panfrost/panfrost_mmu.c
Signed-off-by: default avatarCui GaoSheng <cuigaosheng1@huawei.com>
parent 2d86348f
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -447,12 +447,19 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
	mapping_set_unevictable(mapping);

	for (i = page_offset; i < page_offset + NUM_FAULT_PAGES; i++) {
		/* Can happen if the last fault only partially filled this
		 * section of the pages array before failing. In that case
		 * we skip already filled pages.
		 */
		if (pages[i])
			continue;

		pages[i] = shmem_read_mapping_page(mapping, i);
		if (IS_ERR(pages[i])) {
			mutex_unlock(&bo->base.pages_lock);
			ret = PTR_ERR(pages[i]);
			pages[i] = NULL;
			goto err_pages;
			goto err_bo;
		}
	}

@@ -462,7 +469,7 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
	ret = sg_alloc_table_from_pages(sgt, pages + page_offset,
					NUM_FAULT_PAGES, 0, SZ_2M, GFP_KERNEL);
	if (ret)
		goto err_pages;
		goto err_bo;

	ret = dma_map_sgtable(pfdev->dev, sgt, DMA_BIDIRECTIONAL, 0);
	if (ret)
@@ -482,8 +489,6 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,

err_map:
	sg_free_table(sgt);
err_pages:
	drm_gem_shmem_put_pages(&bo->base);
err_bo:
	panfrost_gem_mapping_put(bomapping);
	return ret;