[PATCH 47/54] fast-reg-ioctl

Chris Wilson chris at chris-wilson.co.uk
Sun Jun 4 12:08:30 UTC 2017


---
 drivers/gpu/drm/i915/i915_drv.c     |  2 +-
 drivers/gpu/drm/i915/i915_drv.h     |  5 ++--
 drivers/gpu/drm/i915/intel_uncore.c | 58 +++++++++++++++++++++++++------------
 3 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a3b190439516..abd64ed1c66b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2574,7 +2574,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_DRIVER_IOCTL_DEF(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
-	DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
+	DRM_DRIVER_IOCTL_DEF(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
 	DRM_DRIVER_IOCTL_DEF(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e4111272bff7..9204ec629e46 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3843,8 +3843,9 @@ extern int intel_set_rps(struct drm_i915_private *dev_priv, u8 val);
 extern bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv,
 				  bool enable);
 
-int i915_reg_read_ioctl(struct drm_device *dev, void *data,
-			struct drm_file *file);
+long i915_reg_read_ioctl(struct file *filp,
+			 unsigned int cmd,
+			 unsigned long data);
 
 /* overlay */
 extern struct intel_overlay_error_state *
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 9882724bc2b6..6c5b89649cf7 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -1254,18 +1254,29 @@ static const struct register_whitelist {
 	  .size = 8, .gen_bitmask = GEN_RANGE(4, 9) },
 };
 
-int i915_reg_read_ioctl(struct drm_device *dev,
-			void *data, struct drm_file *file)
-{
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct drm_i915_reg_read *reg = data;
+long i915_reg_read_ioctl(struct file *filp,
+			 unsigned int cmd,
+			 unsigned long data)
+{
+	struct drm_file *drm_file = filp->private_data;
+	struct drm_i915_file_private *file = drm_file->driver_priv;
+	struct drm_i915_private *dev_priv = file->dev_priv;
+	struct drm_i915_reg_read __user *user = (typeof(user))data;
 	struct register_whitelist const *entry = whitelist;
-	unsigned size;
+	unsigned int offset, size;
 	i915_reg_t offset_ldw, offset_udw;
-	int i, ret = 0;
+	u64 val;
+	int i, ret;
+
+	if (unlikely(!access_ok(VERIFY_WRITE, user, sizeof(*user))))
+		return -EFAULT;
+
+	user_access_begin();
+	unsafe_get_user(offset, &user->offset, err_user);
+	user_access_end();
 
 	for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) {
-		if (i915_mmio_reg_offset(entry->offset_ldw) == (reg->offset & -entry->size) &&
+		if (i915_mmio_reg_offset(entry->offset_ldw) == (offset & -entry->size) &&
 		    (INTEL_INFO(dev_priv)->gen_mask & entry->gen_bitmask))
 			break;
 	}
@@ -1280,34 +1291,43 @@ int i915_reg_read_ioctl(struct drm_device *dev,
 	offset_ldw = entry->offset_ldw;
 	offset_udw = entry->offset_udw;
 	size = entry->size;
-	size |= reg->offset ^ i915_mmio_reg_offset(offset_ldw);
+	size |= offset ^ i915_mmio_reg_offset(offset_ldw);
 
+	ret = 0;
 	intel_runtime_pm_get(dev_priv);
-
 	switch (size) {
 	case 8 | 1:
-		reg->val = I915_READ64_2x32(offset_ldw, offset_udw);
+		val = I915_READ64_2x32(offset_ldw, offset_udw);
 		break;
 	case 8:
-		reg->val = I915_READ64(offset_ldw);
+		val = I915_READ64(offset_ldw);
 		break;
 	case 4:
-		reg->val = I915_READ(offset_ldw);
+		val = I915_READ(offset_ldw);
 		break;
 	case 2:
-		reg->val = I915_READ16(offset_ldw);
+		val = I915_READ16(offset_ldw);
 		break;
 	case 1:
-		reg->val = I915_READ8(offset_ldw);
+		val = I915_READ8(offset_ldw);
 		break;
 	default:
 		ret = -EINVAL;
-		goto out;
+		break;
 	}
-
-out:
 	intel_runtime_pm_put(dev_priv);
-	return ret;
+	if (unlikely(ret))
+		return ret;
+
+	user_access_begin();
+	unsafe_put_user(val, &user->val, err_user);
+	user_access_end();
+
+	return 0;
+
+err_user:
+	user_access_end();
+	return -EFAULT;
 }
 
 static void gen3_stop_rings(struct drm_i915_private *dev_priv)
-- 
2.11.0



More information about the Intel-gfx-trybot mailing list