msm: kgsl: Check user generated timestamp before queuing drawobjs

In ioctls like kgsl_ioctl_submit_commands(), if both syncobj
type and cmd/marker/sparseobj type are submitted, the syncobj
is queued first followed by the other obj type. After syncobj
is successfully queued, in case of failure in get_timestamp
while queuing the other obj, both the command objs are
destroyed. As sync obj is already queued, accessing this
later would cause a crash.

Compare the user generated timestamp with the drawctxt
timestamp and return early in case of error. This avoids
unnecessary queuing of drawobjs.

Change-Id: I336c95c42ab1075d7653cba02772f92c918c884c
Signed-off-by: Archana Sriram <apsrir@codeaurora.org>
Signed-off-by: Harshitha Sai Neelati <hsaine@codeaurora.org>
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index 0f45b4f..7b3bc51 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -1411,6 +1411,22 @@
 
 	user_ts = *timestamp;
 
+	/*
+	 * If there is only one drawobj in the array and it is of
+	 * type SYNCOBJ_TYPE, skip comparing user_ts as it can be 0
+	 */
+	if (!(count == 1 && drawobj[0]->type == SYNCOBJ_TYPE) &&
+		(drawctxt->base.flags & KGSL_CONTEXT_USER_GENERATED_TS)) {
+		/*
+		 * User specified timestamps need to be greater than the last
+		 * issued timestamp in the context
+		 */
+		if (timestamp_cmp(drawctxt->timestamp, user_ts) >= 0) {
+			spin_unlock(&drawctxt->lock);
+			return -ERANGE;
+		}
+	}
+
 	for (i = 0; i < count; i++) {
 
 		switch (drawobj[i]->type) {