msm: kgsl: Don't access context memory after it's freed

Context memory was potentially accessed after being freed. Fix this
by incrementing the context's refcount at strategic places.

Change-Id: I31049bdd3eb9ac52160ca593619fcc8a32d4ddee
Signed-off-by: Lynus Vaz <lvaz@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl_events.c b/drivers/gpu/msm/kgsl_events.c
index 9e9c0da..bab30f1 100644
--- a/drivers/gpu/msm/kgsl_events.c
+++ b/drivers/gpu/msm/kgsl_events.c
@@ -139,6 +139,15 @@
 	cur = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
 	id = context->id;
 
+	/*
+	 * Increment the refcount to avoid freeing the context while
+	 * cancelling its events
+	 */
+	kgsl_context_get(context);
+
+	/* Remove ourselves from the master pending list */
+	list_del_init(&context->events_list);
+
 	list_for_each_entry_safe(event, event_tmp, &context->events, list) {
 		/*
 		 * "cancel" the events by calling their callback.
@@ -161,9 +170,7 @@
 
 		kgsl_active_count_put(device);
 	}
-
-	/* Remove ourselves from the master pending list */
-	list_del_init(&context->events_list);
+	kgsl_context_put(context);
 }
 
 /**
@@ -309,12 +316,18 @@
 		events_list) {
 
 		/*
+		 * Increment the refcount to make sure that the list_del_init
+		 * is called with a valid context's list
+		 */
+		kgsl_context_get(context);
+		/*
 		 * If kgsl_timestamp_expired_context returns 0 then it no longer
 		 * has any pending events and can be removed from the list
 		 */
 
 		if (kgsl_process_context_events(device, context) == 0)
 			list_del_init(&context->events_list);
+		kgsl_context_put(context);
 	}
 
 	mutex_unlock(&device->mutex);