--- /dev/null
+From 00ae1491f970acc454be0df63f50942d94825860 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@linaro.org>
+Date: Thu, 6 Jul 2023 15:37:51 +0300
+Subject: dma-buf: fix an error pointer vs NULL bug
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+commit 00ae1491f970acc454be0df63f50942d94825860 upstream.
+
+Smatch detected potential error pointer dereference.
+
+ drivers/gpu/drm/drm_syncobj.c:888 drm_syncobj_transfer_to_timeline()
+ error: 'fence' dereferencing possible ERR_PTR()
+
+The error pointer comes from dma_fence_allocate_private_stub(). One
+caller expected error pointers and one expected NULL pointers. Change
+it to return NULL and update the caller which expected error pointers,
+drm_syncobj_assign_null_handle(), to check for NULL instead.
+
+Fixes: f781f661e8c9 ("dma-buf: keep the signaling time of merged fences v3")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/b09f1996-3838-4fa2-9193-832b68262e43@moroto.mountain
+Cc: Jindong Yue <jindong.yue@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma-buf/dma-fence.c | 2 +-
+ drivers/gpu/drm/drm_syncobj.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/dma-buf/dma-fence.c
++++ b/drivers/dma-buf/dma-fence.c
+@@ -160,7 +160,7 @@ struct dma_fence *dma_fence_allocate_pri
+
+ fence = kzalloc(sizeof(*fence), GFP_KERNEL);
+ if (fence == NULL)
+- return ERR_PTR(-ENOMEM);
++ return NULL;
+
+ dma_fence_init(fence,
+ &dma_fence_stub_ops,
+--- a/drivers/gpu/drm/drm_syncobj.c
++++ b/drivers/gpu/drm/drm_syncobj.c
+@@ -355,8 +355,8 @@ static int drm_syncobj_assign_null_handl
+ {
+ struct dma_fence *fence = dma_fence_allocate_private_stub(ktime_get());
+
+- if (IS_ERR(fence))
+- return PTR_ERR(fence);
++ if (!fence)
++ return -ENOMEM;
+
+ drm_syncobj_replace_fence(syncobj, fence);
+ dma_fence_put(fence);
--- /dev/null
+From f781f661e8c99b0cb34129f2e374234d61864e77 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Tue, 13 Jun 2023 10:09:20 +0200
+Subject: dma-buf: keep the signaling time of merged fences v3
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+commit f781f661e8c99b0cb34129f2e374234d61864e77 upstream.
+
+Some Android CTS is testing if the signaling time keeps consistent
+during merges.
+
+v2: use the current time if the fence is still in the signaling path and
+the timestamp not yet available.
+v3: improve comment, fix one more case to use the correct timestamp
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Luben Tuikov <luben.tuikov@amd.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230630120041.109216-1-christian.koenig@amd.com
+Cc: Jindong Yue <jindong.yue@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma-buf/dma-fence-unwrap.c | 26 ++++++++++++++++++++++----
+ drivers/dma-buf/dma-fence.c | 5 +++--
+ drivers/gpu/drm/drm_syncobj.c | 2 +-
+ include/linux/dma-fence.h | 2 +-
+ 4 files changed, 27 insertions(+), 8 deletions(-)
+
+--- a/drivers/dma-buf/dma-fence-unwrap.c
++++ b/drivers/dma-buf/dma-fence-unwrap.c
+@@ -66,18 +66,36 @@ struct dma_fence *__dma_fence_unwrap_mer
+ {
+ struct dma_fence_array *result;
+ struct dma_fence *tmp, **array;
++ ktime_t timestamp;
+ unsigned int i;
+ size_t count;
+
+ count = 0;
++ timestamp = ns_to_ktime(0);
+ for (i = 0; i < num_fences; ++i) {
+- dma_fence_unwrap_for_each(tmp, &iter[i], fences[i])
+- if (!dma_fence_is_signaled(tmp))
++ dma_fence_unwrap_for_each(tmp, &iter[i], fences[i]) {
++ if (!dma_fence_is_signaled(tmp)) {
+ ++count;
++ } else if (test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT,
++ &tmp->flags)) {
++ if (ktime_after(tmp->timestamp, timestamp))
++ timestamp = tmp->timestamp;
++ } else {
++ /*
++ * Use the current time if the fence is
++ * currently signaling.
++ */
++ timestamp = ktime_get();
++ }
++ }
+ }
+
++ /*
++ * If we couldn't find a pending fence just return a private signaled
++ * fence with the timestamp of the last signaled one.
++ */
+ if (count == 0)
+- return dma_fence_get_stub();
++ return dma_fence_allocate_private_stub(timestamp);
+
+ array = kmalloc_array(count, sizeof(*array), GFP_KERNEL);
+ if (!array)
+@@ -138,7 +156,7 @@ restart:
+ } while (tmp);
+
+ if (count == 0) {
+- tmp = dma_fence_get_stub();
++ tmp = dma_fence_allocate_private_stub(ktime_get());
+ goto return_tmp;
+ }
+
+--- a/drivers/dma-buf/dma-fence.c
++++ b/drivers/dma-buf/dma-fence.c
+@@ -150,10 +150,11 @@ EXPORT_SYMBOL(dma_fence_get_stub);
+
+ /**
+ * dma_fence_allocate_private_stub - return a private, signaled fence
++ * @timestamp: timestamp when the fence was signaled
+ *
+ * Return a newly allocated and signaled stub fence.
+ */
+-struct dma_fence *dma_fence_allocate_private_stub(void)
++struct dma_fence *dma_fence_allocate_private_stub(ktime_t timestamp)
+ {
+ struct dma_fence *fence;
+
+@@ -169,7 +170,7 @@ struct dma_fence *dma_fence_allocate_pri
+ set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
+ &fence->flags);
+
+- dma_fence_signal(fence);
++ dma_fence_signal_timestamp(fence, timestamp);
+
+ return fence;
+ }
+--- a/drivers/gpu/drm/drm_syncobj.c
++++ b/drivers/gpu/drm/drm_syncobj.c
+@@ -353,7 +353,7 @@ EXPORT_SYMBOL(drm_syncobj_replace_fence)
+ */
+ static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
+ {
+- struct dma_fence *fence = dma_fence_allocate_private_stub();
++ struct dma_fence *fence = dma_fence_allocate_private_stub(ktime_get());
+
+ if (IS_ERR(fence))
+ return PTR_ERR(fence);
+--- a/include/linux/dma-fence.h
++++ b/include/linux/dma-fence.h
+@@ -606,7 +606,7 @@ static inline signed long dma_fence_wait
+ void dma_fence_set_deadline(struct dma_fence *fence, ktime_t deadline);
+
+ struct dma_fence *dma_fence_get_stub(void);
+-struct dma_fence *dma_fence_allocate_private_stub(void);
++struct dma_fence *dma_fence_allocate_private_stub(ktime_t timestamp);
+ u64 dma_fence_context_alloc(unsigned num);
+
+ extern const struct dma_fence_ops dma_fence_array_ops;