mga: switch compat ioctls to drm_ioctl_kernel()
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 4 Jun 2017 01:33:26 +0000 (21:33 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 4 Jul 2017 17:16:28 +0000 (13:16 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
drivers/gpu/drm/drm_ioctl.c
drivers/gpu/drm/mga/mga_drv.h
drivers/gpu/drm/mga/mga_ioc32.c
drivers/gpu/drm/mga/mga_state.c

index 8a8b3075b8b27c61e40cc89335c5d629bc5f8fe2..33582115377638299889eb5f29b3d0783f57c804 100644 (file)
@@ -719,6 +719,7 @@ long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
        }
        return retcode;
 }
+EXPORT_SYMBOL(drm_ioctl_kernel);
 
 /**
  * drm_ioctl - ioctl callback implementation for DRM drivers
index 45cf363d25ad41021e207db7017c40c6a0c53946..a45bb22275a7bfaf2a3f9641a7316ed1b5748aba 100644 (file)
@@ -159,6 +159,8 @@ extern int mga_dma_bootstrap(struct drm_device *dev, void *data,
                             struct drm_file *file_priv);
 extern int mga_dma_init(struct drm_device *dev, void *data,
                        struct drm_file *file_priv);
+extern int mga_getparam(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv);
 extern int mga_dma_flush(struct drm_device *dev, void *data,
                         struct drm_file *file_priv);
 extern int mga_dma_reset(struct drm_device *dev, void *data,
index 729bfd56b55f49d9bd71a501f6717659a2f47af1..85f1a9cd3f85995b3df271e5f6f2b8951c27b580 100644 (file)
@@ -61,46 +61,25 @@ static int compat_mga_init(struct file *file, unsigned int cmd,
                           unsigned long arg)
 {
        drm_mga_init32_t init32;
-       drm_mga_init_t __user *init;
-       int err = 0, i;
+       drm_mga_init_t init;
 
        if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
                return -EFAULT;
 
-       init = compat_alloc_user_space(sizeof(*init));
-       if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
-           || __put_user(init32.func, &init->func)
-           || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
-           || __put_user(init32.chipset, &init->chipset)
-           || __put_user(init32.sgram, &init->sgram)
-           || __put_user(init32.maccess, &init->maccess)
-           || __put_user(init32.fb_cpp, &init->fb_cpp)
-           || __put_user(init32.front_offset, &init->front_offset)
-           || __put_user(init32.front_pitch, &init->front_pitch)
-           || __put_user(init32.back_offset, &init->back_offset)
-           || __put_user(init32.back_pitch, &init->back_pitch)
-           || __put_user(init32.depth_cpp, &init->depth_cpp)
-           || __put_user(init32.depth_offset, &init->depth_offset)
-           || __put_user(init32.depth_pitch, &init->depth_pitch)
-           || __put_user(init32.fb_offset, &init->fb_offset)
-           || __put_user(init32.mmio_offset, &init->mmio_offset)
-           || __put_user(init32.status_offset, &init->status_offset)
-           || __put_user(init32.warp_offset, &init->warp_offset)
-           || __put_user(init32.primary_offset, &init->primary_offset)
-           || __put_user(init32.buffers_offset, &init->buffers_offset))
-               return -EFAULT;
-
-       for (i = 0; i < MGA_NR_TEX_HEAPS; i++) {
-               err |=
-                   __put_user(init32.texture_offset[i],
-                              &init->texture_offset[i]);
-               err |=
-                   __put_user(init32.texture_size[i], &init->texture_size[i]);
-       }
-       if (err)
-               return -EFAULT;
-
-       return drm_ioctl(file, DRM_IOCTL_MGA_INIT, (unsigned long)init);
+       init.func = init32.func;
+       init.sarea_priv_offset = init32.sarea_priv_offset;
+       memcpy(&init.chipset, &init32.chipset,
+               offsetof(drm_mga_init_t, fb_offset) -
+               offsetof(drm_mga_init_t, chipset));
+       init.fb_offset = init32.fb_offset;
+       init.mmio_offset = init32.mmio_offset;
+       init.status_offset = init32.status_offset;
+       init.warp_offset = init32.warp_offset;
+       init.primary_offset = init32.primary_offset;
+       init.buffers_offset = init32.buffers_offset;
+
+       return drm_ioctl_kernel(file, mga_dma_init, &init,
+                               DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
 }
 
 typedef struct drm_mga_getparam32 {
@@ -112,19 +91,14 @@ static int compat_mga_getparam(struct file *file, unsigned int cmd,
                               unsigned long arg)
 {
        drm_mga_getparam32_t getparam32;
-       drm_mga_getparam_t __user *getparam;
+       drm_mga_getparam_t getparam;
 
        if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
                return -EFAULT;
 
-       getparam = compat_alloc_user_space(sizeof(*getparam));
-       if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
-           || __put_user(getparam32.param, &getparam->param)
-           || __put_user((void __user *)(unsigned long)getparam32.value,
-                         &getparam->value))
-               return -EFAULT;
-
-       return drm_ioctl(file, DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
+       getparam.param = getparam32.param;
+       getparam.value = compat_ptr(getparam32.value);
+       return drm_ioctl_kernel(file, mga_getparam, &getparam, DRM_AUTH);
 }
 
 typedef struct drm_mga_drm_bootstrap32 {
@@ -141,48 +115,33 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd,
                                    unsigned long arg)
 {
        drm_mga_dma_bootstrap32_t dma_bootstrap32;
-       drm_mga_dma_bootstrap_t __user *dma_bootstrap;
+       drm_mga_dma_bootstrap_t __user dma_bootstrap;
        int err;
 
        if (copy_from_user(&dma_bootstrap32, (void __user *)arg,
                           sizeof(dma_bootstrap32)))
                return -EFAULT;
 
-       dma_bootstrap = compat_alloc_user_space(sizeof(*dma_bootstrap));
-       if (!access_ok(VERIFY_WRITE, dma_bootstrap, sizeof(*dma_bootstrap))
-           || __put_user(dma_bootstrap32.texture_handle,
-                         &dma_bootstrap->texture_handle)
-           || __put_user(dma_bootstrap32.texture_size,
-                         &dma_bootstrap->texture_size)
-           || __put_user(dma_bootstrap32.primary_size,
-                         &dma_bootstrap->primary_size)
-           || __put_user(dma_bootstrap32.secondary_bin_count,
-                         &dma_bootstrap->secondary_bin_count)
-           || __put_user(dma_bootstrap32.secondary_bin_size,
-                         &dma_bootstrap->secondary_bin_size)
-           || __put_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode)
-           || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
-               return -EFAULT;
+       dma_bootstrap.texture_handle = dma_bootstrap32.texture_handle;
+       dma_bootstrap.texture_size = dma_bootstrap32.texture_size;
+       dma_bootstrap.primary_size = dma_bootstrap32.primary_size;
+       dma_bootstrap.secondary_bin_count = dma_bootstrap32.secondary_bin_count;
+       dma_bootstrap.secondary_bin_size = dma_bootstrap32.secondary_bin_size;
+       dma_bootstrap.agp_mode = dma_bootstrap32.agp_mode;
+       dma_bootstrap.agp_size = dma_bootstrap32.agp_size;
 
-       err = drm_ioctl(file, DRM_IOCTL_MGA_DMA_BOOTSTRAP,
-                       (unsigned long)dma_bootstrap);
+       err = drm_ioctl_kernel(file, mga_dma_bootstrap, &dma_bootstrap,
+                               DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
        if (err)
                return err;
 
-       if (__get_user(dma_bootstrap32.texture_handle,
-                      &dma_bootstrap->texture_handle)
-           || __get_user(dma_bootstrap32.texture_size,
-                         &dma_bootstrap->texture_size)
-           || __get_user(dma_bootstrap32.primary_size,
-                         &dma_bootstrap->primary_size)
-           || __get_user(dma_bootstrap32.secondary_bin_count,
-                         &dma_bootstrap->secondary_bin_count)
-           || __get_user(dma_bootstrap32.secondary_bin_size,
-                         &dma_bootstrap->secondary_bin_size)
-           || __get_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode)
-           || __get_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
-               return -EFAULT;
-
+       dma_bootstrap32.texture_handle = dma_bootstrap.texture_handle;
+       dma_bootstrap32.texture_size = dma_bootstrap.texture_size;
+       dma_bootstrap32.primary_size = dma_bootstrap.primary_size;
+       dma_bootstrap32.secondary_bin_count = dma_bootstrap.secondary_bin_count;
+       dma_bootstrap32.secondary_bin_size = dma_bootstrap.secondary_bin_size;
+       dma_bootstrap32.agp_mode = dma_bootstrap.agp_mode;
+       dma_bootstrap32.agp_size = dma_bootstrap.agp_size;
        if (copy_to_user((void __user *)arg, &dma_bootstrap32,
                         sizeof(dma_bootstrap32)))
                return -EFAULT;
@@ -190,10 +149,14 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd,
        return 0;
 }
 
-drm_ioctl_compat_t *mga_compat_ioctls[] = {
-       [DRM_MGA_INIT] = compat_mga_init,
-       [DRM_MGA_GETPARAM] = compat_mga_getparam,
-       [DRM_MGA_DMA_BOOTSTRAP] = compat_mga_dma_bootstrap,
+static struct {
+       drm_ioctl_compat_t *fn;
+       char *name;
+} mga_compat_ioctls[] = {
+#define DRM_IOCTL32_DEF(n, f)[DRM_##n] = {.fn = f, .name = #n}
+       DRM_IOCTL32_DEF(MGA_INIT, compat_mga_init),
+       DRM_IOCTL32_DEF(MGA_GETPARAM, compat_mga_getparam),
+       DRM_IOCTL32_DEF(MGA_DMA_BOOTSTRAP, compat_mga_dma_bootstrap),
 };
 
 /**
@@ -208,19 +171,27 @@ drm_ioctl_compat_t *mga_compat_ioctls[] = {
 long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        unsigned int nr = DRM_IOCTL_NR(cmd);
+       struct drm_file *file_priv = filp->private_data;
        drm_ioctl_compat_t *fn = NULL;
        int ret;
 
        if (nr < DRM_COMMAND_BASE)
                return drm_compat_ioctl(filp, cmd, arg);
 
-       if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(mga_compat_ioctls))
-               fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE];
-
-       if (fn != NULL)
-               ret = (*fn) (filp, cmd, arg);
-       else
-               ret = drm_ioctl(filp, cmd, arg);
-
+       if (nr >= DRM_COMMAND_BASE + ARRAY_SIZE(mga_compat_ioctls))
+               return drm_ioctl(filp, cmd, arg);
+
+       fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE].fn;
+       if (!fn)
+               return drm_ioctl(filp, cmd, arg);
+
+       DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
+                 task_pid_nr(current),
+                 (long)old_encode_dev(file_priv->minor->kdev->devt),
+                 file_priv->authenticated,
+                 mga_compat_ioctls[nr - DRM_COMMAND_BASE].name);
+       ret = (*fn) (filp, cmd, arg);
+       if (ret)
+               DRM_DEBUG("ret = %d\n", ret);
        return ret;
 }
index 792f924496fc8cecd9fb7e16f8e2d58973476885..e5f6b735f575c702d7fdbe0cedebe96a490301e9 100644 (file)
@@ -1005,7 +1005,7 @@ static int mga_dma_blit(struct drm_device *dev, void *data, struct drm_file *fil
        return 0;
 }
 
-static int mga_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
+int mga_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_getparam_t *param = data;