Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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;
};

/**
+16 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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 */
@@ -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);