]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blobdiff - drivers/char/drm/drm_bufs.c
Use helpers to obtain task pid in printks
[mirror_ubuntu-focal-kernel.git] / drivers / char / drm / drm_bufs.c
index 8d17dbce56edbc293964278a1b63ff50af220897..d24a6c2c2c24e10f33d7498fccd30e16a8574ec0 100644 (file)
@@ -64,7 +64,7 @@ static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
        return NULL;
 }
 
-static int drm_map_handle(struct drm_device *dev, drm_hash_item_t *hash,
+static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
                          unsigned long user_token, int hashed_handle)
 {
        int use_hashed_handle;
@@ -92,7 +92,7 @@ static int drm_map_handle(struct drm_device *dev, drm_hash_item_t *hash,
  * Ioctl to specify a range of memory that is available for mapping by a non-root process.
  *
  * \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
  * \param cmd command.
  * \param arg pointer to a drm_map structure.
  * \return zero on success or a negative value on error.
@@ -177,8 +177,14 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
                                                     MTRR_TYPE_WRCOMB, 1);
                        }
                }
-               if (map->type == _DRM_REGISTERS)
+               if (map->type == _DRM_REGISTERS) {
                        map->handle = ioremap(map->offset, map->size);
+                       if (!map->handle) {
+                               drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+                               return -ENOMEM;
+                       }
+               }
+                               
                break;
        case _DRM_SHM:
                list = drm_find_matching_map(dev, map);
@@ -326,38 +332,24 @@ int drm_addmap(struct drm_device * dev, unsigned int offset,
 
 EXPORT_SYMBOL(drm_addmap);
 
-int drm_addmap_ioctl(struct inode *inode, struct file *filp,
-                    unsigned int cmd, unsigned long arg)
+int drm_addmap_ioctl(struct drm_device *dev, void *data,
+                    struct drm_file *file_priv)
 {
-       struct drm_file *priv = filp->private_data;
-       struct drm_device *dev = priv->head->dev;
-       struct drm_map map;
+       struct drm_map *map = data;
        struct drm_map_list *maplist;
-       struct drm_map __user *argp = (void __user *)arg;
        int err;
 
-       if (!(filp->f_mode & 3))
-               return -EACCES; /* Require read/write */
-
-       if (copy_from_user(&map, argp, sizeof(map))) {
-               return -EFAULT;
-       }
-
-       if (!(capable(CAP_SYS_ADMIN) || map.type == _DRM_AGP))
+       if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP))
                return -EPERM;
 
-       err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags,
-                             &maplist);
+       err = drm_addmap_core(dev, map->offset, map->size, map->type,
+                             map->flags, &maplist);
 
        if (err)
                return err;
 
-       if (copy_to_user(argp, maplist->map, sizeof(struct drm_map)))
-               return -EFAULT;
-
        /* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */
-       if (put_user((void *)(unsigned long)maplist->user_token, &argp->handle))
-               return -EFAULT;
+       map->handle = (void *)(unsigned long)maplist->user_token;
        return 0;
 }
 
@@ -366,7 +358,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
  * isn't in use.
  *
  * \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
  * \param cmd command.
  * \param arg pointer to a struct drm_map structure.
  * \return zero on success or a negative value on error.
@@ -447,24 +439,18 @@ int drm_rmmap(struct drm_device *dev, drm_local_map_t *map)
  * gets used by drivers that the server doesn't need to care about.  This seems
  * unlikely.
  */
-int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
-                   unsigned int cmd, unsigned long arg)
+int drm_rmmap_ioctl(struct drm_device *dev, void *data,
+                   struct drm_file *file_priv)
 {
-       struct drm_file *priv = filp->private_data;
-       struct drm_device *dev = priv->head->dev;
-       struct drm_map request;
+       struct drm_map *request = data;
        drm_local_map_t *map = NULL;
        struct drm_map_list *r_list;
        int ret;
 
-       if (copy_from_user(&request, (struct drm_map __user *) arg, sizeof(request))) {
-               return -EFAULT;
-       }
-
        mutex_lock(&dev->struct_mutex);
        list_for_each_entry(r_list, &dev->maplist, head) {
                if (r_list->map &&
-                   r_list->user_token == (unsigned long)request.handle &&
+                   r_list->user_token == (unsigned long)request->handle &&
                    r_list->map->flags & _DRM_REMOVABLE) {
                        map = r_list->map;
                        break;
@@ -479,11 +465,6 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
                return -EINVAL;
        }
 
-       if (!map) {
-               mutex_unlock(&dev->struct_mutex);
-               return -EINVAL;
-       }
-
        /* Register and framebuffer maps are permanent */
        if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
                mutex_unlock(&dev->struct_mutex);
@@ -660,7 +641,7 @@ int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request)
                buf->waiting = 0;
                buf->pending = 0;
                init_waitqueue_head(&buf->dma_wait);
-               buf->filp = NULL;
+               buf->file_priv = NULL;
 
                buf->dev_priv_size = dev->driver->dev_priv_size;
                buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
@@ -871,7 +852,7 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request)
                        buf->waiting = 0;
                        buf->pending = 0;
                        init_waitqueue_head(&buf->dma_wait);
-                       buf->filp = NULL;
+                       buf->file_priv = NULL;
 
                        buf->dev_priv_size = dev->driver->dev_priv_size;
                        buf->dev_private = drm_alloc(buf->dev_priv_size,
@@ -1049,7 +1030,7 @@ static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request
                buf->waiting = 0;
                buf->pending = 0;
                init_waitqueue_head(&buf->dma_wait);
-               buf->filp = NULL;
+               buf->file_priv = NULL;
 
                buf->dev_priv_size = dev->driver->dev_priv_size;
                buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
@@ -1210,7 +1191,7 @@ static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request
                buf->waiting = 0;
                buf->pending = 0;
                init_waitqueue_head(&buf->dma_wait);
-               buf->filp = NULL;
+               buf->file_priv = NULL;
 
                buf->dev_priv_size = dev->driver->dev_priv_size;
                buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
@@ -1274,7 +1255,7 @@ static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request
  * Add buffers for DMA transfers (ioctl).
  *
  * \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
  * \param cmd command.
  * \param arg pointer to a struct drm_buf_desc request.
  * \return zero on success or a negative number on failure.
@@ -1284,38 +1265,27 @@ static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request
  * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
  * PCI memory respectively.
  */
-int drm_addbufs(struct inode *inode, struct file *filp,
-               unsigned int cmd, unsigned long arg)
+int drm_addbufs(struct drm_device *dev, void *data,
+               struct drm_file *file_priv)
 {
-       struct drm_buf_desc request;
-       struct drm_file *priv = filp->private_data;
-       struct drm_device *dev = priv->head->dev;
+       struct drm_buf_desc *request = data;
        int ret;
 
        if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
                return -EINVAL;
 
-       if (copy_from_user(&request, (struct drm_buf_desc __user *) arg,
-                          sizeof(request)))
-               return -EFAULT;
-
 #if __OS_HAS_AGP
-       if (request.flags & _DRM_AGP_BUFFER)
-               ret = drm_addbufs_agp(dev, &request);
+       if (request->flags & _DRM_AGP_BUFFER)
+               ret = drm_addbufs_agp(dev, request);
        else
 #endif
-       if (request.flags & _DRM_SG_BUFFER)
-               ret = drm_addbufs_sg(dev, &request);
-       else if (request.flags & _DRM_FB_BUFFER)
-               ret = drm_addbufs_fb(dev, &request);
+       if (request->flags & _DRM_SG_BUFFER)
+               ret = drm_addbufs_sg(dev, request);
+       else if (request->flags & _DRM_FB_BUFFER)
+               ret = drm_addbufs_fb(dev, request);
        else
-               ret = drm_addbufs_pci(dev, &request);
+               ret = drm_addbufs_pci(dev, request);
 
-       if (ret == 0) {
-               if (copy_to_user((void __user *)arg, &request, sizeof(request))) {
-                       ret = -EFAULT;
-               }
-       }
        return ret;
 }
 
@@ -1327,7 +1297,7 @@ int drm_addbufs(struct inode *inode, struct file *filp,
  * large buffers can be used for image transfer).
  *
  * \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
  * \param cmd command.
  * \param arg pointer to a drm_buf_info structure.
  * \return zero on success or a negative number on failure.
@@ -1336,14 +1306,11 @@ int drm_addbufs(struct inode *inode, struct file *filp,
  * lock, preventing of allocating more buffers after this call. Information
  * about each requested buffer is then copied into user space.
  */
-int drm_infobufs(struct inode *inode, struct file *filp,
-                unsigned int cmd, unsigned long arg)
+int drm_infobufs(struct drm_device *dev, void *data,
+                struct drm_file *file_priv)
 {
-       struct drm_file *priv = filp->private_data;
-       struct drm_device *dev = priv->head->dev;
        struct drm_device_dma *dma = dev->dma;
-       struct drm_buf_info request;
-       struct drm_buf_info __user *argp = (void __user *)arg;
+       struct drm_buf_info *request = data;
        int i;
        int count;
 
@@ -1361,9 +1328,6 @@ int drm_infobufs(struct inode *inode, struct file *filp,
        ++dev->buf_use;         /* Can't allocate more after this call */
        spin_unlock(&dev->count_lock);
 
-       if (copy_from_user(&request, argp, sizeof(request)))
-               return -EFAULT;
-
        for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
                if (dma->bufs[i].buf_count)
                        ++count;
@@ -1371,11 +1335,11 @@ int drm_infobufs(struct inode *inode, struct file *filp,
 
        DRM_DEBUG("count = %d\n", count);
 
-       if (request.count >= count) {
+       if (request->count >= count) {
                for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
                        if (dma->bufs[i].buf_count) {
                                struct drm_buf_desc __user *to =
-                                   &request.list[count];
+                                   &request->list[count];
                                struct drm_buf_entry *from = &dma->bufs[i];
                                struct drm_freelist *list = &dma->bufs[i].freelist;
                                if (copy_to_user(&to->count,
@@ -1402,10 +1366,7 @@ int drm_infobufs(struct inode *inode, struct file *filp,
                        }
                }
        }
-       request.count = count;
-
-       if (copy_to_user(argp, &request, sizeof(request)))
-               return -EFAULT;
+       request->count = count;
 
        return 0;
 }
@@ -1414,7 +1375,7 @@ int drm_infobufs(struct inode *inode, struct file *filp,
  * Specifies a low and high water mark for buffer allocation
  *
  * \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
  * \param cmd command.
  * \param arg a pointer to a drm_buf_desc structure.
  * \return zero on success or a negative number on failure.
@@ -1424,13 +1385,11 @@ int drm_infobufs(struct inode *inode, struct file *filp,
  *
  * \note This ioctl is deprecated and mostly never used.
  */
-int drm_markbufs(struct inode *inode, struct file *filp,
-                unsigned int cmd, unsigned long arg)
+int drm_markbufs(struct drm_device *dev, void *data,
+                struct drm_file *file_priv)
 {
-       struct drm_file *priv = filp->private_data;
-       struct drm_device *dev = priv->head->dev;
        struct drm_device_dma *dma = dev->dma;
-       struct drm_buf_desc request;
+       struct drm_buf_desc *request = data;
        int order;
        struct drm_buf_entry *entry;
 
@@ -1440,24 +1399,20 @@ int drm_markbufs(struct inode *inode, struct file *filp,
        if (!dma)
                return -EINVAL;
 
-       if (copy_from_user(&request,
-                          (struct drm_buf_desc __user *) arg, sizeof(request)))
-               return -EFAULT;
-
        DRM_DEBUG("%d, %d, %d\n",
-                 request.size, request.low_mark, request.high_mark);
-       order = drm_order(request.size);
+                 request->size, request->low_mark, request->high_mark);
+       order = drm_order(request->size);
        if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
                return -EINVAL;
        entry = &dma->bufs[order];
 
-       if (request.low_mark < 0 || request.low_mark > entry->buf_count)
+       if (request->low_mark < 0 || request->low_mark > entry->buf_count)
                return -EINVAL;
-       if (request.high_mark < 0 || request.high_mark > entry->buf_count)
+       if (request->high_mark < 0 || request->high_mark > entry->buf_count)
                return -EINVAL;
 
-       entry->freelist.low_mark = request.low_mark;
-       entry->freelist.high_mark = request.high_mark;
+       entry->freelist.low_mark = request->low_mark;
+       entry->freelist.high_mark = request->high_mark;
 
        return 0;
 }
@@ -1466,7 +1421,7 @@ int drm_markbufs(struct inode *inode, struct file *filp,
  * Unreserve the buffers in list, previously reserved using drmDMA.
  *
  * \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
  * \param cmd command.
  * \param arg pointer to a drm_buf_free structure.
  * \return zero on success or a negative number on failure.
@@ -1474,13 +1429,11 @@ int drm_markbufs(struct inode *inode, struct file *filp,
  * Calls free_buffer() for each used buffer.
  * This function is primarily used for debugging.
  */
-int drm_freebufs(struct inode *inode, struct file *filp,
-                unsigned int cmd, unsigned long arg)
+int drm_freebufs(struct drm_device *dev, void *data,
+                struct drm_file *file_priv)
 {
-       struct drm_file *priv = filp->private_data;
-       struct drm_device *dev = priv->head->dev;
        struct drm_device_dma *dma = dev->dma;
-       struct drm_buf_free request;
+       struct drm_buf_free *request = data;
        int i;
        int idx;
        struct drm_buf *buf;
@@ -1491,13 +1444,9 @@ int drm_freebufs(struct inode *inode, struct file *filp,
        if (!dma)
                return -EINVAL;
 
-       if (copy_from_user(&request,
-                          (struct drm_buf_free __user *) arg, sizeof(request)))
-               return -EFAULT;
-
-       DRM_DEBUG("%d\n", request.count);
-       for (i = 0; i < request.count; i++) {
-               if (copy_from_user(&idx, &request.list[i], sizeof(idx)))
+       DRM_DEBUG("%d\n", request->count);
+       for (i = 0; i < request->count; i++) {
+               if (copy_from_user(&idx, &request->list[i], sizeof(idx)))
                        return -EFAULT;
                if (idx < 0 || idx >= dma->buf_count) {
                        DRM_ERROR("Index %d (of %d max)\n",
@@ -1505,9 +1454,9 @@ int drm_freebufs(struct inode *inode, struct file *filp,
                        return -EINVAL;
                }
                buf = dma->buflist[idx];
-               if (buf->filp != filp) {
+               if (buf->file_priv != file_priv) {
                        DRM_ERROR("Process %d freeing buffer not owned\n",
-                                 current->pid);
+                                 task_pid_nr(current));
                        return -EINVAL;
                }
                drm_free_buffer(dev, buf);
@@ -1520,7 +1469,7 @@ int drm_freebufs(struct inode *inode, struct file *filp,
  * Maps all of the DMA buffers into client-virtual space (ioctl).
  *
  * \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
  * \param cmd command.
  * \param arg pointer to a drm_buf_map structure.
  * \return zero on success or a negative number on failure.
@@ -1530,18 +1479,15 @@ int drm_freebufs(struct inode *inode, struct file *filp,
  * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
  * drm_mmap_dma().
  */
-int drm_mapbufs(struct inode *inode, struct file *filp,
-               unsigned int cmd, unsigned long arg)
+int drm_mapbufs(struct drm_device *dev, void *data,
+               struct drm_file *file_priv)
 {
-       struct drm_file *priv = filp->private_data;
-       struct drm_device *dev = priv->head->dev;
        struct drm_device_dma *dma = dev->dma;
-       struct drm_buf_map __user *argp = (void __user *)arg;
        int retcode = 0;
        const int zero = 0;
        unsigned long virtual;
        unsigned long address;
-       struct drm_buf_map request;
+       struct drm_buf_map *request = data;
        int i;
 
        if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
@@ -1558,10 +1504,7 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
        dev->buf_use++;         /* Can't allocate more after this call */
        spin_unlock(&dev->count_lock);
 
-       if (copy_from_user(&request, argp, sizeof(request)))
-               return -EFAULT;
-
-       if (request.count >= dma->buf_count) {
+       if (request->count >= dma->buf_count) {
                if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP))
                    || (drm_core_check_feature(dev, DRIVER_SG)
                        && (dma->flags & _DRM_DMA_USE_SG))
@@ -1574,15 +1517,15 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
                                retcode = -EINVAL;
                                goto done;
                        }
-
                        down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, map->size,
+                       virtual = do_mmap(file_priv->filp, 0, map->size,
                                          PROT_READ | PROT_WRITE,
-                                         MAP_SHARED, token);
+                                         MAP_SHARED,
+                                         token);
                        up_write(&current->mm->mmap_sem);
                } else {
                        down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, dma->byte_count,
+                       virtual = do_mmap(file_priv->filp, 0, dma->byte_count,
                                          PROT_READ | PROT_WRITE,
                                          MAP_SHARED, 0);
                        up_write(&current->mm->mmap_sem);
@@ -1592,28 +1535,28 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
                        retcode = (signed long)virtual;
                        goto done;
                }
-               request.virtual = (void __user *)virtual;
+               request->virtual = (void __user *)virtual;
 
                for (i = 0; i < dma->buf_count; i++) {
-                       if (copy_to_user(&request.list[i].idx,
+                       if (copy_to_user(&request->list[i].idx,
                                         &dma->buflist[i]->idx,
-                                        sizeof(request.list[0].idx))) {
+                                        sizeof(request->list[0].idx))) {
                                retcode = -EFAULT;
                                goto done;
                        }
-                       if (copy_to_user(&request.list[i].total,
+                       if (copy_to_user(&request->list[i].total,
                                         &dma->buflist[i]->total,
-                                        sizeof(request.list[0].total))) {
+                                        sizeof(request->list[0].total))) {
                                retcode = -EFAULT;
                                goto done;
                        }
-                       if (copy_to_user(&request.list[i].used,
+                       if (copy_to_user(&request->list[i].used,
                                         &zero, sizeof(zero))) {
                                retcode = -EFAULT;
                                goto done;
                        }
                        address = virtual + dma->buflist[i]->offset;    /* *** */
-                       if (copy_to_user(&request.list[i].address,
+                       if (copy_to_user(&request->list[i].address,
                                         &address, sizeof(address))) {
                                retcode = -EFAULT;
                                goto done;
@@ -1621,11 +1564,8 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
                }
        }
       done:
-       request.count = dma->buf_count;
-       DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
-
-       if (copy_to_user(argp, &request, sizeof(request)))
-               return -EFAULT;
+       request->count = dma->buf_count;
+       DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode);
 
        return retcode;
 }