Skip to content

Commit

Permalink
drm: Return EINVAL on duplicate objects in execbuffer object list
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Kristian Høgsberg authored and Eric Anholt committed Mar 10, 2009
1 parent 99adcd9 commit b70d11d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
6 changes: 6 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,12 @@ struct drm_i915_gem_object {

/** for phy allocated objects */
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;
};

/**
Expand Down
17 changes: 16 additions & 1 deletion drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2469,6 +2469,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_i915_gem_exec_object *exec_list = NULL;
struct drm_gem_object **object_list = NULL;
struct drm_gem_object *batch_obj;
struct drm_i915_gem_object *obj_priv;
int ret, i, pinned = 0;
uint64_t exec_offset;
uint32_t seqno, flush_domains;
Expand Down Expand Up @@ -2533,6 +2534,15 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
ret = -EBADF;
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 */
Expand Down Expand Up @@ -2674,8 +2684,13 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
for (i = 0; i < pinned; 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]);
}

mutex_unlock(&dev->struct_mutex);

Expand Down

0 comments on commit b70d11d

Please sign in to comment.