Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit d4244a42 authored by Harshdeep Dhatt's avatar Harshdeep Dhatt Committed by Michael Bestas
Browse files

BACKPORT: kgsl: hwsched: Don't cross dereference kgsl_mem_entry pointer



The passed in pointer in kgsl_count_hw_fences() can be a
kgsl_mem_entry pointer. This gets cross dereferenced to
a kgsl_drawobj_sync_event pointer and causes a NULL pointer
dereference. To avoid this cross dereference, decouple the two
paths and call kgsl_count_hw_fences() only in the appropriate
path.

Change-Id: I1088a0b67f1f82a20ddc94c94cbdd31a44b18da6
Signed-off-by: default avatarHarshdeep Dhatt <quic_hdhatt@quicinc.com>
parent 5b696ce7
Loading
Loading
Loading
Loading
+1 −2
Original line number Original line Diff line number Diff line
@@ -2470,8 +2470,7 @@ static long gpuobj_free_on_fence(struct kgsl_device_private *dev_priv,
		return -EINVAL;
		return -EINVAL;
	}
	}


	handle = kgsl_sync_fence_async_wait(event.fd,
	handle = kgsl_sync_fence_async_wait(event.fd, gpuobj_free_fence_func, entry);
		gpuobj_free_fence_func, entry, NULL);


	if (IS_ERR(handle)) {
	if (IS_ERR(handle)) {
		kgsl_mem_entry_unset_pend(entry);
		kgsl_mem_entry_unset_pend(entry);
+3 −2
Original line number Original line Diff line number Diff line
@@ -562,8 +562,7 @@ static int drawobj_add_sync_fence(struct kgsl_device *device,


	set_bit(event->id, &syncobj->pending);
	set_bit(event->id, &syncobj->pending);


	event->handle = kgsl_sync_fence_async_wait(sync.fd,
	event->handle = kgsl_sync_fence_async_wait(sync.fd, drawobj_sync_fence_func, event);
				drawobj_sync_fence_func, event, priv);


	event->priv = priv;
	event->priv = priv;


@@ -585,6 +584,8 @@ static int drawobj_add_sync_fence(struct kgsl_device *device,
		return ret;
		return ret;
	}
	}


	kgsl_get_fence_info(event);

	for (i = 0; priv && i < priv->num_fences; i++)
	for (i = 0; priv && i < priv->num_fences; i++)
		trace_syncpoint_fence(syncobj, priv->fences[i].name);
		trace_syncpoint_fence(syncobj, priv->fences[i].name);


+6 −7
Original line number Original line Diff line number Diff line
@@ -424,19 +424,20 @@ static void kgsl_sync_fence_callback(struct dma_fence *fence,
	}
	}
}
}


static void kgsl_get_fence_names(struct dma_fence *fence,
void kgsl_get_fence_info(struct kgsl_drawobj_sync_event *event)
	struct event_fence_info *info_ptr)
{
{
	unsigned int num_fences;
	unsigned int num_fences;
	struct dma_fence **fences;
	struct dma_fence *fence, **fences;
	struct dma_fence_array *array;
	struct dma_fence_array *array;
	struct event_fence_info *info_ptr = event->priv;
	int i;
	int i;


	if (!info_ptr)
	if (!info_ptr)
		return;
		return;


	array = to_dma_fence_array(fence);
	fence = event->handle->fence;


	array = to_dma_fence_array(fence);
	if (array != NULL) {
	if (array != NULL) {
		num_fences = array->num_fences;
		num_fences = array->num_fences;
		fences = array->fences;
		fences = array->fences;
@@ -471,7 +472,7 @@ static void kgsl_get_fence_names(struct dma_fence *fence,
}
}


struct kgsl_sync_fence_cb *kgsl_sync_fence_async_wait(int fd,
struct kgsl_sync_fence_cb *kgsl_sync_fence_async_wait(int fd,
	bool (*func)(void *priv), void *priv, struct event_fence_info *info_ptr)
	bool (*func)(void *priv), void *priv)
{
{
	struct kgsl_sync_fence_cb *kcb;
	struct kgsl_sync_fence_cb *kcb;
	struct dma_fence *fence;
	struct dma_fence *fence;
@@ -492,8 +493,6 @@ struct kgsl_sync_fence_cb *kgsl_sync_fence_async_wait(int fd,
	kcb->priv = priv;
	kcb->priv = priv;
	kcb->func = func;
	kcb->func = func;


	kgsl_get_fence_names(fence, info_ptr);

	/* if status then error or signaled */
	/* if status then error or signaled */
	status = dma_fence_add_callback(fence, &kcb->fence_cb,
	status = dma_fence_add_callback(fence, &kcb->fence_cb,
				kgsl_sync_fence_callback);
				kgsl_sync_fence_callback);
+8 −5
Original line number Original line Diff line number Diff line
@@ -85,9 +85,9 @@ void kgsl_sync_timeline_detach(struct kgsl_sync_timeline *ktimeline);


void kgsl_sync_timeline_put(struct kgsl_sync_timeline *ktimeline);
void kgsl_sync_timeline_put(struct kgsl_sync_timeline *ktimeline);


struct kgsl_sync_fence_cb *kgsl_sync_fence_async_wait(int fd,
struct kgsl_sync_fence_cb *kgsl_sync_fence_async_wait(int fd, bool (*func)(void *priv), void *priv);
					bool (*func)(void *priv), void *priv,

					struct event_fence_info *info_ptr);
void kgsl_get_fence_info(struct kgsl_drawobj_sync_event *event);


void kgsl_sync_fence_async_cancel(struct kgsl_sync_fence_cb *kcb);
void kgsl_sync_fence_async_cancel(struct kgsl_sync_fence_cb *kcb);


@@ -129,9 +129,12 @@ static inline void kgsl_sync_timeline_put(struct kgsl_sync_timeline *ktimeline)
}
}




static inline void kgsl_get_fence_info(struct kgsl_drawobj_sync_event *event)
{
}

static inline struct kgsl_sync_fence_cb *kgsl_sync_fence_async_wait(int fd,
static inline struct kgsl_sync_fence_cb *kgsl_sync_fence_async_wait(int fd,
					bool (*func)(void *priv), void *priv,
	bool (*func)(void *priv), void *priv);
					struct event_fence_info *info_ptr)
{
{
	return NULL;
	return NULL;
}
}