diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3153-drm-syncobj-fix-leaking-dma_fence-in-drm_syncobj_que.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3153-drm-syncobj-fix-leaking-dma_fence-in-drm_syncobj_que.patch | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3153-drm-syncobj-fix-leaking-dma_fence-in-drm_syncobj_que.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3153-drm-syncobj-fix-leaking-dma_fence-in-drm_syncobj_que.patch new file mode 100644 index 00000000..232f5008 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3153-drm-syncobj-fix-leaking-dma_fence-in-drm_syncobj_que.patch @@ -0,0 +1,113 @@ +From 4352bbe79144d6293cab9514012b625a820207f9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Mon, 22 Jul 2019 14:56:25 +0200 +Subject: [PATCH 3153/4256] drm/syncobj: fix leaking dma_fence in + drm_syncobj_query_ioctl +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We need to check the context number instead if the previous sequence to detect +an error and if an error is detected we need to drop the reference to the +current fence or otherwise would leak it. + +Signed-off-by: Christian König <christian.koenig@amd.com> +Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> +Fixes: 27b575a9aa2f ("drm/syncobj: add timeline payload query ioctl v6") +Link: https://patchwork.freedesktop.org/patch/319123/ +--- + drivers/gpu/drm/drm_syncobj.c | 62 +++++++++++++++++++++++++++++++++++ + include/uapi/drm/drm.h | 7 ++++ + 2 files changed, 69 insertions(+) + +diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c +index 74482832c759..abda0a01d8dc 100644 +--- a/drivers/gpu/drm/drm_syncobj.c ++++ b/drivers/gpu/drm/drm_syncobj.c +@@ -1069,3 +1069,65 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, + + return ret; + } ++ ++int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_private) ++{ ++ struct drm_syncobj_timeline_array *args = data; ++ struct drm_syncobj **syncobjs; ++ uint64_t __user *points = u64_to_user_ptr(args->points); ++ uint32_t i; ++ int ret; ++ ++ if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) ++ return -ENODEV; ++ ++ if (args->pad != 0) ++ return -EINVAL; ++ ++ if (args->count_handles == 0) ++ return -EINVAL; ++ ++ ret = drm_syncobj_array_find(file_private, ++ u64_to_user_ptr(args->handles), ++ args->count_handles, ++ &syncobjs); ++ if (ret < 0) ++ return ret; ++ ++ for (i = 0; i < args->count_handles; i++) { ++ struct dma_fence_chain *chain; ++ struct dma_fence *fence; ++ uint64_t point; ++ ++ fence = drm_syncobj_fence_get(syncobjs[i]); ++ chain = to_dma_fence_chain(fence); ++ if (chain) { ++ struct dma_fence *iter, *last_signaled = NULL; ++ ++ dma_fence_chain_for_each(iter, fence) { ++ if (iter->context != fence->context) { ++ dma_fence_put(iter); ++ /* It is most likely that timeline has ++ * unorder points. */ ++ break; ++ } ++ dma_fence_put(last_signaled); ++ last_signaled = dma_fence_get(iter); ++ } ++ point = dma_fence_is_signaled(last_signaled) ? ++ last_signaled->seqno : ++ to_dma_fence_chain(last_signaled)->prev_seqno; ++ dma_fence_put(last_signaled); ++ } else { ++ point = 0; ++ } ++ ret = copy_to_user(&points[i], &point, sizeof(uint64_t)); ++ ret = ret ? -EFAULT : 0; ++ if (ret) ++ break; ++ } ++ drm_syncobj_array_free(syncobjs, args->count_handles); ++ ++ return ret; ++} +diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h +index 300f336633f2..c18616d7fcd5 100644 +--- a/include/uapi/drm/drm.h ++++ b/include/uapi/drm/drm.h +@@ -753,6 +753,13 @@ struct drm_syncobj_array { + __u32 pad; + }; + ++struct drm_syncobj_timeline_array { ++ __u64 handles; ++ __u64 points; ++ __u32 count_handles; ++ __u32 pad; ++}; ++ + /* Query current scanout sequence number */ + struct drm_crtc_get_sequence { + __u32 crtc_id; /* requested crtc_id */ +-- +2.17.1 + |