|
@@ -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;
|
|
|
|