aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3153-drm-syncobj-fix-leaking-dma_fence-in-drm_syncobj_que.patch
diff options
context:
space:
mode:
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.patch113
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
+