aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-03-03 14:45:57 -0500
committerEric Anholt <eric@anholt.net>2009-03-10 16:11:11 -0400
commitb70d11da61d751ad968c6f686d83ac1b0ae41466 (patch)
tree388afdd8b085860e1f5ac7e3bc50b6d56ab1325e /drivers
parent99adcd9d67aaf04e28f5ae96df280f236bde4b66 (diff)
drm: Return EINVAL on duplicate objects in execbuffer object list
If userspace passes an object list with the same object appearing more than once, we end up hitting the BUG_ON() in i915_gem_object_set_to_gpu_domain() as it gets called a second time for the same object. Signed-off-by: Kristian Høgsberg <krh@redhat.com> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h6
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c17
2 files changed, 22 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 17fa40858d26..9186d43be011 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -457,6 +457,12 @@ struct drm_i915_gem_object {
457 457
458 /** for phy allocated objects */ 458 /** for phy allocated objects */
459 struct drm_i915_gem_phys_object *phys_obj; 459 struct drm_i915_gem_phys_object *phys_obj;
460
461 /**
462 * Used for checking the object doesn't appear more than once
463 * in an execbuffer object list.
464 */
465 int in_execbuffer;
460}; 466};
461 467
462/** 468/**
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 85685bfd12da..7bdcc752f139 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2469,6 +2469,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
2469 struct drm_i915_gem_exec_object *exec_list = NULL; 2469 struct drm_i915_gem_exec_object *exec_list = NULL;
2470 struct drm_gem_object **object_list = NULL; 2470 struct drm_gem_object **object_list = NULL;
2471 struct drm_gem_object *batch_obj; 2471 struct drm_gem_object *batch_obj;
2472 struct drm_i915_gem_object *obj_priv;
2472 int ret, i, pinned = 0; 2473 int ret, i, pinned = 0;
2473 uint64_t exec_offset; 2474 uint64_t exec_offset;
2474 uint32_t seqno, flush_domains; 2475 uint32_t seqno, flush_domains;
@@ -2533,6 +2534,15 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
2533 ret = -EBADF; 2534 ret = -EBADF;
2534 goto err; 2535 goto err;
2535 } 2536 }
2537
2538 obj_priv = object_list[i]->driver_private;
2539 if (obj_priv->in_execbuffer) {
2540 DRM_ERROR("Object %p appears more than once in object list\n",
2541 object_list[i]);
2542 ret = -EBADF;
2543 goto err;
2544 }
2545 obj_priv->in_execbuffer = true;
2536 } 2546 }
2537 2547
2538 /* Pin and relocate */ 2548 /* Pin and relocate */
@@ -2674,8 +2684,13 @@ err:
2674 for (i = 0; i < pinned; i++) 2684 for (i = 0; i < pinned; i++)
2675 i915_gem_object_unpin(object_list[i]); 2685 i915_gem_object_unpin(object_list[i]);
2676 2686
2677 for (i = 0; i < args->buffer_count; i++) 2687 for (i = 0; i < args->buffer_count; i++) {
2688 if (object_list[i]) {
2689 obj_priv = object_list[i]->driver_private;
2690 obj_priv->in_execbuffer = false;
2691 }
2678 drm_gem_object_unreference(object_list[i]); 2692 drm_gem_object_unreference(object_list[i]);
2693 }
2679 2694
2680 mutex_unlock(&dev->struct_mutex); 2695 mutex_unlock(&dev->struct_mutex);
2681 2696