Commit b70d11da authored by Kristian Høgsberg's avatar Kristian Høgsberg Committed by Eric Anholt

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: default avatarKristian Høgsberg <krh@redhat.com>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 99adcd9d
...@@ -457,6 +457,12 @@ struct drm_i915_gem_object { ...@@ -457,6 +457,12 @@ struct drm_i915_gem_object {
/** for phy allocated objects */ /** for phy allocated objects */
struct drm_i915_gem_phys_object *phys_obj; struct drm_i915_gem_phys_object *phys_obj;
/**
* Used for checking the object doesn't appear more than once
* in an execbuffer object list.
*/
int in_execbuffer;
}; };
/** /**
......
...@@ -2469,6 +2469,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, ...@@ -2469,6 +2469,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_i915_gem_exec_object *exec_list = NULL; struct drm_i915_gem_exec_object *exec_list = NULL;
struct drm_gem_object **object_list = NULL; struct drm_gem_object **object_list = NULL;
struct drm_gem_object *batch_obj; struct drm_gem_object *batch_obj;
struct drm_i915_gem_object *obj_priv;
int ret, i, pinned = 0; int ret, i, pinned = 0;
uint64_t exec_offset; uint64_t exec_offset;
uint32_t seqno, flush_domains; uint32_t seqno, flush_domains;
...@@ -2533,6 +2534,15 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, ...@@ -2533,6 +2534,15 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
ret = -EBADF; ret = -EBADF;
goto err; goto err;
} }
obj_priv = object_list[i]->driver_private;
if (obj_priv->in_execbuffer) {
DRM_ERROR("Object %p appears more than once in object list\n",
object_list[i]);
ret = -EBADF;
goto err;
}
obj_priv->in_execbuffer = true;
} }
/* Pin and relocate */ /* Pin and relocate */
...@@ -2674,8 +2684,13 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, ...@@ -2674,8 +2684,13 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
for (i = 0; i < pinned; i++) for (i = 0; i < pinned; i++)
i915_gem_object_unpin(object_list[i]); i915_gem_object_unpin(object_list[i]);
for (i = 0; i < args->buffer_count; i++) for (i = 0; i < args->buffer_count; i++) {
if (object_list[i]) {
obj_priv = object_list[i]->driver_private;
obj_priv->in_execbuffer = false;
}
drm_gem_object_unreference(object_list[i]); drm_gem_object_unreference(object_list[i]);
}
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment