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

Commit 647416f9 authored by Kees Cook's avatar Kees Cook Committed by Daniel Vetter
Browse files

drm/i915: use simple attribute in debugfs routines



This replaces the manual read/write routines in debugfs with the common
simple attribute helpers. Doing this gets rid of repeated copy/pasting
of copy_from_user and value formatting code.

Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
[danvet: Squash in follow-up fix from Kees Cook to fix u64 divides on
32bit platforms.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 5c67eeb6
Loading
Loading
Loading
Loading
+104 −302
Original line number Original line Diff line number Diff line
@@ -866,76 +866,42 @@ static const struct file_operations i915_error_state_fops = {
	.release = i915_error_state_release,
	.release = i915_error_state_release,
};
};


static ssize_t
static int
i915_next_seqno_read(struct file *filp,
i915_next_seqno_get(void *data, u64 *val)
		 char __user *ubuf,
		 size_t max,
		 loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[80];
	int len;
	int ret;
	int ret;


	ret = mutex_lock_interruptible(&dev->struct_mutex);
	ret = mutex_lock_interruptible(&dev->struct_mutex);
	if (ret)
	if (ret)
		return ret;
		return ret;


	len = snprintf(buf, sizeof(buf),
	*val = dev_priv->next_seqno;
		       "next_seqno :  0x%x\n",
		       dev_priv->next_seqno);

	mutex_unlock(&dev->struct_mutex);
	mutex_unlock(&dev->struct_mutex);


	if (len > sizeof(buf))
	return 0;
		len = sizeof(buf);

	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
}
}


static ssize_t
static int
i915_next_seqno_write(struct file *filp,
i915_next_seqno_set(void *data, u64 val)
		      const char __user *ubuf,
		      size_t cnt,
		      loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	char buf[20];
	u32 val = 1;
	int ret;
	int ret;


	if (cnt > 0) {
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		ret = kstrtouint(buf, 0, &val);
		if (ret < 0)
			return ret;
	}

	ret = mutex_lock_interruptible(&dev->struct_mutex);
	ret = mutex_lock_interruptible(&dev->struct_mutex);
	if (ret)
	if (ret)
		return ret;
		return ret;


	ret = i915_gem_set_seqno(dev, val);
	ret = i915_gem_set_seqno(dev, val);

	mutex_unlock(&dev->struct_mutex);
	mutex_unlock(&dev->struct_mutex);


	return ret ?: cnt;
	return ret;
}
}


static const struct file_operations i915_next_seqno_fops = {
DEFINE_SIMPLE_ATTRIBUTE(i915_next_seqno_fops,
	.owner = THIS_MODULE,
			i915_next_seqno_get, i915_next_seqno_set,
	.open = simple_open,
			"next_seqno :  0x%llx\n");
	.read = i915_next_seqno_read,
	.write = i915_next_seqno_write,
	.llseek = default_llseek,
};


static int i915_rstdby_delays(struct seq_file *m, void *unused)
static int i915_rstdby_delays(struct seq_file *m, void *unused)
{
{
@@ -1697,105 +1663,51 @@ static int i915_dpio_info(struct seq_file *m, void *data)
	return 0;
	return 0;
}
}


static ssize_t
static int
i915_wedged_read(struct file *filp,
i915_wedged_get(void *data, u64 *val)
		 char __user *ubuf,
		 size_t max,
		 loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[80];
	int len;

	len = snprintf(buf, sizeof(buf),
		       "wedged :  %d\n",
		       atomic_read(&dev_priv->gpu_error.reset_counter));


	if (len > sizeof(buf))
	*val = atomic_read(&dev_priv->gpu_error.reset_counter);
		len = sizeof(buf);


	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
	return 0;
}
}


static ssize_t
static int
i915_wedged_write(struct file *filp,
i915_wedged_set(void *data, u64 val)
		  const char __user *ubuf,
		  size_t cnt,
		  loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	char buf[20];
	int val = 1;

	if (cnt > 0) {
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}


	DRM_INFO("Manually setting wedged to %d\n", val);
	DRM_INFO("Manually setting wedged to %llu\n", val);
	i915_handle_error(dev, val);
	i915_handle_error(dev, val);


	return cnt;
	return 0;
}
}


static const struct file_operations i915_wedged_fops = {
DEFINE_SIMPLE_ATTRIBUTE(i915_wedged_fops,
	.owner = THIS_MODULE,
			i915_wedged_get, i915_wedged_set,
	.open = simple_open,
			"wedged :  %llu\n");
	.read = i915_wedged_read,
	.write = i915_wedged_write,
	.llseek = default_llseek,
};


static ssize_t
static int
i915_ring_stop_read(struct file *filp,
i915_ring_stop_get(void *data, u64 *val)
		    char __user *ubuf,
		    size_t max,
		    loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[20];
	int len;


	len = snprintf(buf, sizeof(buf),
	*val = dev_priv->gpu_error.stop_rings;
		       "0x%08x\n", dev_priv->gpu_error.stop_rings);


	if (len > sizeof(buf))
	return 0;
		len = sizeof(buf);

	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
}
}


static ssize_t
static int
i915_ring_stop_write(struct file *filp,
i915_ring_stop_set(void *data, u64 val)
		     const char __user *ubuf,
		     size_t cnt,
		     loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_private *dev_priv = dev->dev_private;
	char buf[20];
	int ret;
	int val = 0, ret;

	if (cnt > 0) {
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}


	DRM_DEBUG_DRIVER("Stopping rings 0x%08x\n", val);
	DRM_DEBUG_DRIVER("Stopping rings 0x%08llx\n", val);


	ret = mutex_lock_interruptible(&dev->struct_mutex);
	ret = mutex_lock_interruptible(&dev->struct_mutex);
	if (ret)
	if (ret)
@@ -1804,16 +1716,12 @@ i915_ring_stop_write(struct file *filp,
	dev_priv->gpu_error.stop_rings = val;
	dev_priv->gpu_error.stop_rings = val;
	mutex_unlock(&dev->struct_mutex);
	mutex_unlock(&dev->struct_mutex);


	return cnt;
	return 0;
}
}


static const struct file_operations i915_ring_stop_fops = {
DEFINE_SIMPLE_ATTRIBUTE(i915_ring_stop_fops,
	.owner = THIS_MODULE,
			i915_ring_stop_get, i915_ring_stop_set,
	.open = simple_open,
			"0x%08llx\n");
	.read = i915_ring_stop_read,
	.write = i915_ring_stop_write,
	.llseek = default_llseek,
};


#define DROP_UNBOUND 0x1
#define DROP_UNBOUND 0x1
#define DROP_BOUND 0x2
#define DROP_BOUND 0x2
@@ -1823,46 +1731,23 @@ static const struct file_operations i915_ring_stop_fops = {
		  DROP_BOUND | \
		  DROP_BOUND | \
		  DROP_RETIRE | \
		  DROP_RETIRE | \
		  DROP_ACTIVE)
		  DROP_ACTIVE)
static ssize_t
static int
i915_drop_caches_read(struct file *filp,
i915_drop_caches_get(void *data, u64 *val)
		      char __user *ubuf,
		      size_t max,
		      loff_t *ppos)
{
{
	char buf[20];
	*val = DROP_ALL;
	int len;

	len = snprintf(buf, sizeof(buf), "0x%08x\n", DROP_ALL);
	if (len > sizeof(buf))
		len = sizeof(buf);


	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
	return 0;
}
}


static ssize_t
static int
i915_drop_caches_write(struct file *filp,
i915_drop_caches_set(void *data, u64 val)
		       const char __user *ubuf,
		       size_t cnt,
		       loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_gem_object *obj, *next;
	struct drm_i915_gem_object *obj, *next;
	char buf[20];
	int ret;
	int val = 0, ret;

	if (cnt > 0) {
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}


	DRM_DEBUG_DRIVER("Dropping caches: 0x%08x\n", val);
	DRM_DEBUG_DRIVER("Dropping caches: 0x%08llx\n", val);


	/* No need to check and wait for gpu resets, only libdrm auto-restarts
	/* No need to check and wait for gpu resets, only libdrm auto-restarts
	 * on ioctls on -EAGAIN. */
	 * on ioctls on -EAGAIN. */
@@ -1900,27 +1785,19 @@ i915_drop_caches_write(struct file *filp,
unlock:
unlock:
	mutex_unlock(&dev->struct_mutex);
	mutex_unlock(&dev->struct_mutex);


	return ret ?: cnt;
	return ret;
}
}


static const struct file_operations i915_drop_caches_fops = {
DEFINE_SIMPLE_ATTRIBUTE(i915_drop_caches_fops,
	.owner = THIS_MODULE,
			i915_drop_caches_get, i915_drop_caches_set,
	.open = simple_open,
			"0x%08llx\n");
	.read = i915_drop_caches_read,
	.write = i915_drop_caches_write,
	.llseek = default_llseek,
};


static ssize_t
static int
i915_max_freq_read(struct file *filp,
i915_max_freq_get(void *data, u64 *val)
		   char __user *ubuf,
		   size_t max,
		   loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[80];
	int ret;
	int len, ret;


	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;
		return -ENODEV;
@@ -1929,42 +1806,23 @@ i915_max_freq_read(struct file *filp,
	if (ret)
	if (ret)
		return ret;
		return ret;


	len = snprintf(buf, sizeof(buf),
	*val = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
		       "max freq: %d\n", dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER);
	mutex_unlock(&dev_priv->rps.hw_lock);
	mutex_unlock(&dev_priv->rps.hw_lock);


	if (len > sizeof(buf))
	return 0;
		len = sizeof(buf);

	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
}
}


static ssize_t
static int
i915_max_freq_write(struct file *filp,
i915_max_freq_set(void *data, u64 val)
		  const char __user *ubuf,
		  size_t cnt,
		  loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_private *dev_priv = dev->dev_private;
	char buf[20];
	int ret;
	int val = 1, ret;


	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;
		return -ENODEV;


	if (cnt > 0) {
	DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val);
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}

	DRM_DEBUG_DRIVER("Manually setting max freq to %d\n", val);


	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
	if (ret)
	if (ret)
@@ -1973,30 +1831,24 @@ i915_max_freq_write(struct file *filp,
	/*
	/*
	 * Turbo will still be enabled, but won't go above the set value.
	 * Turbo will still be enabled, but won't go above the set value.
	 */
	 */
	dev_priv->rps.max_delay = val / GT_FREQUENCY_MULTIPLIER;
	do_div(val, GT_FREQUENCY_MULTIPLIER);

	dev_priv->rps.max_delay = val;
	gen6_set_rps(dev, val / GT_FREQUENCY_MULTIPLIER);
	gen6_set_rps(dev, val);
	mutex_unlock(&dev_priv->rps.hw_lock);
	mutex_unlock(&dev_priv->rps.hw_lock);


	return cnt;
	return 0;
}
}


static const struct file_operations i915_max_freq_fops = {
DEFINE_SIMPLE_ATTRIBUTE(i915_max_freq_fops,
	.owner = THIS_MODULE,
			i915_max_freq_get, i915_max_freq_set,
	.open = simple_open,
			"max freq: %llu\n");
	.read = i915_max_freq_read,
	.write = i915_max_freq_write,
	.llseek = default_llseek,
};


static ssize_t
static int
i915_min_freq_read(struct file *filp, char __user *ubuf, size_t max,
i915_min_freq_get(void *data, u64 *val)
		   loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[80];
	int ret;
	int len, ret;


	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;
		return -ENODEV;
@@ -2005,40 +1857,23 @@ i915_min_freq_read(struct file *filp, char __user *ubuf, size_t max,
	if (ret)
	if (ret)
		return ret;
		return ret;


	len = snprintf(buf, sizeof(buf),
	*val = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER;
		       "min freq: %d\n", dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER);
	mutex_unlock(&dev_priv->rps.hw_lock);
	mutex_unlock(&dev_priv->rps.hw_lock);


	if (len > sizeof(buf))
	return 0;
		len = sizeof(buf);

	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
}
}


static ssize_t
static int
i915_min_freq_write(struct file *filp, const char __user *ubuf, size_t cnt,
i915_min_freq_set(void *data, u64 val)
		    loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_private *dev_priv = dev->dev_private;
	char buf[20];
	int ret;
	int val = 1, ret;


	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;
		return -ENODEV;


	if (cnt > 0) {
	DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val);
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}

	DRM_DEBUG_DRIVER("Manually setting min freq to %d\n", val);


	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
	if (ret)
	if (ret)
@@ -2047,33 +1882,25 @@ i915_min_freq_write(struct file *filp, const char __user *ubuf, size_t cnt,
	/*
	/*
	 * Turbo will still be enabled, but won't go below the set value.
	 * Turbo will still be enabled, but won't go below the set value.
	 */
	 */
	dev_priv->rps.min_delay = val / GT_FREQUENCY_MULTIPLIER;
	do_div(val, GT_FREQUENCY_MULTIPLIER);

	dev_priv->rps.min_delay = val;
	gen6_set_rps(dev, val / GT_FREQUENCY_MULTIPLIER);
	gen6_set_rps(dev, val);
	mutex_unlock(&dev_priv->rps.hw_lock);
	mutex_unlock(&dev_priv->rps.hw_lock);


	return cnt;
	return 0;
}
}


static const struct file_operations i915_min_freq_fops = {
DEFINE_SIMPLE_ATTRIBUTE(i915_min_freq_fops,
	.owner = THIS_MODULE,
			i915_min_freq_get, i915_min_freq_set,
	.open = simple_open,
			"min freq: %llu\n");
	.read = i915_min_freq_read,
	.write = i915_min_freq_write,
	.llseek = default_llseek,
};


static ssize_t
static int
i915_cache_sharing_read(struct file *filp,
i915_cache_sharing_get(void *data, u64 *val)
		   char __user *ubuf,
		   size_t max,
		   loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[80];
	u32 snpcr;
	u32 snpcr;
	int len, ret;
	int ret;


	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;
		return -ENODEV;
@@ -2085,46 +1912,25 @@ i915_cache_sharing_read(struct file *filp,
	snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
	snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
	mutex_unlock(&dev_priv->dev->struct_mutex);
	mutex_unlock(&dev_priv->dev->struct_mutex);


	len = snprintf(buf, sizeof(buf),
	*val = (snpcr & GEN6_MBC_SNPCR_MASK) >> GEN6_MBC_SNPCR_SHIFT;
		       "%d\n", (snpcr & GEN6_MBC_SNPCR_MASK) >>
		       GEN6_MBC_SNPCR_SHIFT);

	if (len > sizeof(buf))
		len = sizeof(buf);


	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
	return 0;
}
}


static ssize_t
static int
i915_cache_sharing_write(struct file *filp,
i915_cache_sharing_set(void *data, u64 val)
		  const char __user *ubuf,
		  size_t cnt,
		  loff_t *ppos)
{
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_private *dev_priv = dev->dev_private;
	char buf[20];
	u32 snpcr;
	u32 snpcr;
	int val = 1;


	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;
		return -ENODEV;


	if (cnt > 0) {
	if (val > 3)
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}

	if (val < 0 || val > 3)
		return -EINVAL;
		return -EINVAL;


	DRM_DEBUG_DRIVER("Manually setting uncore sharing to %d\n", val);
	DRM_DEBUG_DRIVER("Manually setting uncore sharing to %llu\n", val);


	/* Update the cache sharing policy here as well */
	/* Update the cache sharing policy here as well */
	snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
	snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
@@ -2132,16 +1938,12 @@ i915_cache_sharing_write(struct file *filp,
	snpcr |= (val << GEN6_MBC_SNPCR_SHIFT);
	snpcr |= (val << GEN6_MBC_SNPCR_SHIFT);
	I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr);
	I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr);


	return cnt;
	return 0;
}
}


static const struct file_operations i915_cache_sharing_fops = {
DEFINE_SIMPLE_ATTRIBUTE(i915_cache_sharing_fops,
	.owner = THIS_MODULE,
			i915_cache_sharing_get, i915_cache_sharing_set,
	.open = simple_open,
			"%llu\n");
	.read = i915_cache_sharing_read,
	.write = i915_cache_sharing_write,
	.llseek = default_llseek,
};


/* As the drm_debugfs_init() routines are called before dev->dev_private is
/* As the drm_debugfs_init() routines are called before dev->dev_private is
 * allocated we need to hook into the minor for release. */
 * allocated we need to hook into the minor for release. */