diff mbox

[1/2] drm/i915: check execbuffer for validity earlier to save on work.

Message ID 1271972322-18780-1-git-send-email-oga@openbsd.org (mailing list archive)
State Deferred, archived
Headers show

Commit Message

Owain Ainsworth April 22, 2010, 9:38 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b85727c..a9da182 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3656,23 +3656,6 @@  err:
 	return ret;
 }
 
-static int
-i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer2 *exec,
-			   uint64_t exec_offset)
-{
-	uint32_t exec_start, exec_len;
-
-	exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
-	exec_len = (uint32_t) exec->batch_len;
-
-	if ((exec_start | exec_len) & 0x7)
-		return -EINVAL;
-
-	if (!exec_start)
-		return -EINVAL;
-
-	return 0;
-}
 
 static int
 i915_gem_wait_for_pending_flip(struct drm_device *dev,
@@ -3722,7 +3705,6 @@  i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	struct drm_clip_rect *cliprects = NULL;
 	struct drm_i915_gem_relocation_entry *relocs = NULL;
 	int ret = 0, ret2, i, pinned = 0;
-	uint64_t exec_offset;
 	uint32_t seqno, flush_domains, reloc_index;
 	int pin_tries, flips;
 
@@ -3730,6 +3712,16 @@  i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
 		  (int) args->buffers_ptr, args->buffer_count, args->batch_len);
 #endif
+	/*
+	 * check for valid execbuffer offset. We can do this early because
+	 * bound objects are always page aligned, so only the start offset
+	 * matters. Also check for overflow.
+	 */
+	if ((args->batch_start_offset | args->batch_len) & 0x7 ||
+	    args->batch_start_offset + args->batch_len < args->batch_len ||
+	    args->batch_start_offset + args->batch_len <
+	    args->batch_start_offset)
+		return -EINVAL;
 
 	if (args->buffer_count < 1) {
 		DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
@@ -3878,15 +3870,12 @@  i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 		ret = -EINVAL;
 		goto err;
 	}
-	batch_obj->pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
-
-	/* Sanity check the batch buffer, prior to moving objects */
-	exec_offset = exec_list[args->buffer_count - 1].offset;
-	ret = i915_gem_check_execbuffer (args, exec_offset);
-	if (ret != 0) {
-		DRM_ERROR("execbuf with invalid offset/length\n");
+	if (args->batch_start_offset + args->batch_len > batch_obj->size) {
+		DRM_ERROR("batchbuffer shorter than program length\n");
+		ret = EINVAL;
 		goto err;
 	}
+	batch_obj->pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
 
 	i915_verify_inactive(dev, __FILE__, __LINE__);
 
@@ -3955,7 +3944,8 @@  i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 #endif
 
 	/* Exec the batchbuffer */
-	ret = i915_dispatch_gem_execbuffer(dev, args, cliprects, exec_offset);
+	ret = i915_dispatch_gem_execbuffer(dev, args, cliprects,
+	    exec_list[args->buffer_count - 1].offset);
 	if (ret) {
 		DRM_ERROR("dispatch failed %d\n", ret);
 		goto err;