| From f49a51bfdc8ea717c97ccd4cc98b7e6daaa5553a Mon Sep 17 00:00:00 2001 |
| From: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Date: Tue, 27 Oct 2020 22:49:22 +0100 |
| Subject: drm/shme-helpers: Fix dma_buf_mmap forwarding bug |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Daniel Vetter <daniel.vetter@ffwll.ch> |
| |
| commit f49a51bfdc8ea717c97ccd4cc98b7e6daaa5553a upstream. |
| |
| When we forward an mmap to the dma_buf exporter, they get to own |
| everything. Unfortunately drm_gem_mmap_obj() overwrote |
| vma->vm_private_data after the driver callback, wreaking the |
| exporter complete. This was noticed because vb2_common_vm_close blew |
| up on mali gpu with panfrost after commit 26d3ac3cb04d |
| ("drm/shmem-helpers: Redirect mmap for imported dma-buf"). |
| |
| Unfortunately drm_gem_mmap_obj also acquires a surplus reference that |
| we need to drop in shmem helpers, which is a bit of a mislayer |
| situation. Maybe the entire dma_buf_mmap forwarding should be pulled |
| into core gem code. |
| |
| Note that the only two other drivers which forward mmap in their own |
| code (etnaviv and exynos) get this somewhat right by overwriting the |
| gem mmap code. But they seem to still have the leak. This might be a |
| good excuse to move these drivers over to shmem helpers completely. |
| |
| Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> |
| Acked-by: Christian König <christian.koenig@amd.com> |
| Cc: Christian König <christian.koenig@amd.com> |
| Cc: Sumit Semwal <sumit.semwal@linaro.org> |
| Cc: Lucas Stach <l.stach@pengutronix.de> |
| Cc: Russell King <linux+etnaviv@armlinux.org.uk> |
| Cc: Christian Gmeiner <christian.gmeiner@gmail.com> |
| Cc: Inki Dae <inki.dae@samsung.com> |
| Cc: Joonyoung Shim <jy0922.shim@samsung.com> |
| Cc: Seung-Woo Kim <sw0312.kim@samsung.com> |
| Cc: Kyungmin Park <kyungmin.park@samsung.com> |
| Fixes: 26d3ac3cb04d ("drm/shmem-helpers: Redirect mmap for imported dma-buf") |
| Cc: Boris Brezillon <boris.brezillon@collabora.com> |
| Cc: Thomas Zimmermann <tzimmermann@suse.de> |
| Cc: Gerd Hoffmann <kraxel@redhat.com> |
| Cc: Rob Herring <robh@kernel.org> |
| Cc: dri-devel@lists.freedesktop.org |
| Cc: linux-media@vger.kernel.org |
| Cc: linaro-mm-sig@lists.linaro.org |
| Cc: <stable@vger.kernel.org> # v5.9+ |
| Reported-and-tested-by: piotr.oniszczuk@gmail.com |
| Cc: piotr.oniszczuk@gmail.com |
| Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> |
| Link: https://patchwork.freedesktop.org/patch/msgid/20201027214922.3566743-1-daniel.vetter@ffwll.ch |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/drm_gem.c | 4 ++-- |
| drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ++++++- |
| 2 files changed, 8 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/gpu/drm/drm_gem.c |
| +++ b/drivers/gpu/drm/drm_gem.c |
| @@ -1085,6 +1085,8 @@ int drm_gem_mmap_obj(struct drm_gem_obje |
| */ |
| drm_gem_object_get(obj); |
| |
| + vma->vm_private_data = obj; |
| + |
| if (obj->funcs && obj->funcs->mmap) { |
| ret = obj->funcs->mmap(obj, vma); |
| if (ret) { |
| @@ -1107,8 +1109,6 @@ int drm_gem_mmap_obj(struct drm_gem_obje |
| vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); |
| } |
| |
| - vma->vm_private_data = obj; |
| - |
| return 0; |
| } |
| EXPORT_SYMBOL(drm_gem_mmap_obj); |
| --- a/drivers/gpu/drm/drm_gem_shmem_helper.c |
| +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c |
| @@ -594,8 +594,13 @@ int drm_gem_shmem_mmap(struct drm_gem_ob |
| /* Remove the fake offset */ |
| vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); |
| |
| - if (obj->import_attach) |
| + if (obj->import_attach) { |
| + /* Drop the reference drm_gem_mmap_obj() acquired.*/ |
| + drm_gem_object_put(obj); |
| + vma->vm_private_data = NULL; |
| + |
| return dma_buf_mmap(obj->dma_buf, vma, 0); |
| + } |
| |
| shmem = to_drm_gem_shmem_obj(obj); |
| |