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

Commit 7f0dfc16 authored by Al Viro's avatar Al Viro
Browse files

new helper: drm_ioctl_kernel()



drm_ioctl() guts sans copying the structure to/from userland
and parsing the ioctl cmd.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 2ea659a9
Loading
Loading
Loading
Loading
+27 −14
Original line number Diff line number Diff line
@@ -694,6 +694,32 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 * structure.
 */

long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
		      u32 flags)
{
	struct drm_file *file_priv = file->private_data;
	struct drm_device *dev = file_priv->minor->dev;
	int retcode;

	if (drm_device_is_unplugged(dev))
		return -ENODEV;

	retcode = drm_ioctl_permit(flags, file_priv);
	if (unlikely(retcode))
		return retcode;

	/* Enforce sane locking for modern driver ioctls. */
	if (!drm_core_check_feature(dev, DRIVER_LEGACY) ||
	    (flags & DRM_UNLOCKED))
		retcode = func(dev, kdata, file_priv);
	else {
		mutex_lock(&drm_global_mutex);
		retcode = func(dev, kdata, file_priv);
		mutex_unlock(&drm_global_mutex);
	}
	return retcode;
}

/**
 * drm_ioctl - ioctl callback implementation for DRM drivers
 * @filp: file this ioctl is called on
@@ -762,10 +788,6 @@ long drm_ioctl(struct file *filp,
		goto err_i1;
	}

	retcode = drm_ioctl_permit(ioctl->flags, file_priv);
	if (unlikely(retcode))
		goto err_i1;

	if (ksize <= sizeof(stack_kdata)) {
		kdata = stack_kdata;
	} else {
@@ -784,16 +806,7 @@ long drm_ioctl(struct file *filp,
	if (ksize > in_size)
		memset(kdata + in_size, 0, ksize - in_size);

	/* Enforce sane locking for modern driver ioctls. */
	if (!drm_core_check_feature(dev, DRIVER_LEGACY) ||
	    (ioctl->flags & DRM_UNLOCKED))
		retcode = func(dev, kdata, file_priv);
	else {
		mutex_lock(&drm_global_mutex);
		retcode = func(dev, kdata, file_priv);
		mutex_unlock(&drm_global_mutex);
	}

	retcode = drm_ioctl_kernel(filp, func, kdata, ioctl->flags);
	if (copy_to_user((void __user *)arg, kdata, out_size) != 0)
		retcode = -EFAULT;

+1 −0
Original line number Diff line number Diff line
@@ -172,6 +172,7 @@ struct drm_ioctl_desc {

int drm_ioctl_permit(u32 flags, struct drm_file *file_priv);
long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
long drm_ioctl_kernel(struct file *, drm_ioctl_t, void *, u32);
#ifdef CONFIG_COMPAT
long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
#else