[PATCH 55/74] fast-set-domains-ioctl

Chris Wilson chris at chris-wilson.co.uk
Sun Jul 16 19:00:56 UTC 2017


---
 drivers/gpu/drm/i915/i915_drv.c |  2 +-
 drivers/gpu/drm/i915/i915_drv.h |  5 ++--
 drivers/gpu/drm/i915/i915_gem.c | 52 ++++++++++++++++++++++++++---------------
 3 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 9feddf59cccf..d6b5044d4c82 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2655,7 +2655,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
-	DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW),
+	DRM_DRIVER_IOCTL_DEF(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, DRM_RENDER_ALLOW),
 	DRM_DRIVER_IOCTL_DEF(I915_GEM_GET_TILING, i915_gem_get_tiling_ioctl, DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e4be9614758a..944475cd20a0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3249,8 +3249,9 @@ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv);
 int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv);
-int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv);
+long i915_gem_set_domain_ioctl(struct file *filp,
+			       unsigned int cmd,
+			       unsigned long data);
 int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
 			     struct drm_file *file_priv);
 int i915_gem_execbuffer(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index eab4a88ced5b..bebc5df70eb0 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1591,27 +1591,37 @@ static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj)
  * @data: ioctl data blob
  * @file: drm file
  */
-int
-i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
-			  struct drm_file *file)
+long
+i915_gem_set_domain_ioctl(struct file *filp,
+			  unsigned int cmd,
+			  unsigned long data)
 {
-	struct drm_i915_gem_set_domain *args = data;
+	struct drm_i915_gem_set_domain __user *user = (typeof(user))data;
+	struct drm_i915_gem_set_domain arg;
 	struct drm_i915_gem_object *obj;
-	uint32_t read_domains = args->read_domains;
-	uint32_t write_domain = args->write_domain;
+	struct drm_file *file = filp->private_data;
 	int err;
 
+	if (unlikely(!access_ok(VERIFY_READ, user, sizeof(*user))))
+		return -EFAULT;
+
+	user_access_begin();
+	unsafe_get_user(arg.handle, &user->handle, err_user);
+	unsafe_get_user(arg.read_domains, &user->read_domains, err_user);
+	unsafe_get_user(arg.write_domain, &user->write_domain, err_user);
+	user_access_end();
+
 	/* Only handle setting domains to types used by the CPU. */
-	if ((write_domain | read_domains) & I915_GEM_GPU_DOMAINS)
+	if ((arg.write_domain | arg.read_domains) & I915_GEM_GPU_DOMAINS)
 		return -EINVAL;
 
 	/* Having something in the write domain implies it's in the read
 	 * domain, and only that read domain.  Enforce that in the request.
 	 */
-	if (write_domain != 0 && read_domains != write_domain)
+	if (arg.write_domain != 0 && arg.read_domains != arg.write_domain)
 		return -EINVAL;
 
-	obj = i915_gem_object_lookup(file, args->handle);
+	obj = i915_gem_object_lookup(file, arg.handle);
 	if (!obj)
 		return -ENOENT;
 
@@ -1621,7 +1631,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
 	 */
 	err = i915_gem_object_wait(obj,
 				   I915_WAIT_INTERRUPTIBLE |
-				   (write_domain ? I915_WAIT_ALL : 0),
+				   (arg.write_domain ? I915_WAIT_ALL : 0),
 				   MAX_SCHEDULE_TIMEOUT,
 				   to_rps_client(file));
 	if (err)
@@ -1639,31 +1649,35 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
 	if (err)
 		goto out;
 
-	err = i915_mutex_lock_interruptible(dev);
+	err = i915_mutex_lock_interruptible(obj->base.dev);
 	if (err)
 		goto out_unpin;
 
-	if (read_domains & I915_GEM_DOMAIN_WC)
-		err = i915_gem_object_set_to_wc_domain(obj, write_domain);
-	else if (read_domains & I915_GEM_DOMAIN_GTT)
-		err = i915_gem_object_set_to_gtt_domain(obj, write_domain);
+	if (arg.read_domains & I915_GEM_DOMAIN_WC)
+		err = i915_gem_object_set_to_wc_domain(obj, arg.write_domain);
+	else if (arg.read_domains & I915_GEM_DOMAIN_GTT)
+		err = i915_gem_object_set_to_gtt_domain(obj, arg.write_domain);
 	else
-		err = i915_gem_object_set_to_cpu_domain(obj, write_domain);
+		err = i915_gem_object_set_to_cpu_domain(obj, arg.write_domain);
 
 	/* And bump the LRU for this access */
 	i915_gem_object_bump_inactive_ggtt(obj);
 
-	mutex_unlock(&dev->struct_mutex);
+	mutex_unlock(&obj->base.dev->struct_mutex);
 
-	if (write_domain != 0)
+	if (arg.write_domain)
 		intel_fb_obj_invalidate(obj,
-					fb_write_origin(obj, write_domain));
+					fb_write_origin(obj, arg.write_domain));
 
 out_unpin:
 	i915_gem_object_unpin_pages(obj);
 out:
 	i915_gem_object_put(obj);
 	return err;
+
+err_user:
+	user_access_end();
+	return -EFAULT;
 }
 
 /**
-- 
2.13.2



More information about the Intel-gfx-trybot mailing list