Loading drivers/gpu/drm/drm_bufs.c +65 −51 Original line number Diff line number Diff line Loading @@ -1258,11 +1258,11 @@ int drm_legacy_addbufs(struct drm_device *dev, void *data, * lock, preventing of allocating more buffers after this call. Information * about each requested buffer is then copied into user space. */ int drm_legacy_infobufs(struct drm_device *dev, void *data, struct drm_file *file_priv) int __drm_legacy_infobufs(struct drm_device *dev, void *data, int *p, int (*f)(void *, int, struct drm_buf_entry *)) { struct drm_device_dma *dma = dev->dma; struct drm_buf_info *request = data; int i; int count; Loading Loading @@ -1290,26 +1290,12 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data, DRM_DEBUG("count = %d\n", count); if (request->count >= count) { if (*p >= 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]; struct drm_buf_entry *from = &dma->bufs[i]; if (copy_to_user(&to->count, &from->buf_count, sizeof(from->buf_count)) || copy_to_user(&to->size, &from->buf_size, sizeof(from->buf_size)) || copy_to_user(&to->low_mark, &from->low_mark, sizeof(from->low_mark)) || copy_to_user(&to->high_mark, &from->high_mark, sizeof(from->high_mark))) if (from->buf_count) { if (f(data, count, from) < 0) return -EFAULT; DRM_DEBUG("%d %d %d %d %d\n", i, dma->bufs[i].buf_count, Loading @@ -1320,11 +1306,29 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data, } } } request->count = count; *p = count; return 0; } static int copy_one_buf(void *data, int count, struct drm_buf_entry *from) { struct drm_buf_info *request = data; struct drm_buf_desc __user *to = &request->list[count]; struct drm_buf_desc v = {.count = from->buf_count, .size = from->buf_size, .low_mark = from->low_mark, .high_mark = from->high_mark}; return copy_to_user(to, &v, offsetof(struct drm_buf_desc, flags)); } int drm_legacy_infobufs(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_buf_info *request = data; return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf); } /** * Specifies a low and high water mark for buffer allocation * Loading Loading @@ -1439,15 +1443,15 @@ int drm_legacy_freebufs(struct drm_device *dev, void *data, * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls * drm_mmap_dma(). */ int drm_legacy_mapbufs(struct drm_device *dev, void *data, int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p, void __user **v, int (*f)(void *, int, unsigned long, struct drm_buf *), struct drm_file *file_priv) { struct drm_device_dma *dma = dev->dma; int retcode = 0; const int zero = 0; unsigned long virtual; unsigned long address; struct drm_buf_map *request = data; int i; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) Loading @@ -1467,7 +1471,7 @@ int drm_legacy_mapbufs(struct drm_device *dev, void *data, dev->buf_use++; /* Can't allocate more after this call */ spin_unlock(&dev->buf_lock); if (request->count >= dma->buf_count) { if (*p >= dma->buf_count) { if ((dev->agp && (dma->flags & _DRM_DMA_USE_AGP)) || (drm_core_check_feature(dev, DRIVER_SG) && (dma->flags & _DRM_DMA_USE_SG))) { Loading @@ -1492,41 +1496,51 @@ int drm_legacy_mapbufs(struct drm_device *dev, void *data, retcode = (signed long)virtual; goto done; } request->virtual = (void __user *)virtual; *v = (void __user *)virtual; for (i = 0; i < dma->buf_count; i++) { if (copy_to_user(&request->list[i].idx, &dma->buflist[i]->idx, sizeof(request->list[0].idx))) { retcode = -EFAULT; goto done; } if (copy_to_user(&request->list[i].total, &dma->buflist[i]->total, sizeof(request->list[0].total))) { retcode = -EFAULT; goto done; } 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, &address, sizeof(address))) { if (f(data, i, virtual, dma->buflist[i]) < 0) { retcode = -EFAULT; goto done; } } } done: request->count = dma->buf_count; DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode); *p = dma->buf_count; DRM_DEBUG("%d buffers, retcode = %d\n", *p, retcode); return retcode; } static int map_one_buf(void *data, int idx, unsigned long virtual, struct drm_buf *buf) { struct drm_buf_map *request = data; unsigned long address = virtual + buf->offset; /* *** */ if (copy_to_user(&request->list[idx].idx, &buf->idx, sizeof(request->list[0].idx))) return -EFAULT; if (copy_to_user(&request->list[idx].total, &buf->total, sizeof(request->list[0].total))) return -EFAULT; if (clear_user(&request->list[idx].used, sizeof(int))) return -EFAULT; if (copy_to_user(&request->list[idx].address, &address, sizeof(address))) return -EFAULT; return 0; } int drm_legacy_mapbufs(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_buf_map *request = data; return __drm_legacy_mapbufs(dev, data, &request->count, &request->virtual, map_one_buf, file_priv); } int drm_legacy_dma_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { Loading drivers/gpu/drm/drm_internal.h +3 −0 Original line number Diff line number Diff line Loading @@ -143,3 +143,6 @@ static inline int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc) return 0; } #endif drm_ioctl_t drm_version; drm_ioctl_t drm_getunique; drm_ioctl_t drm_getclient; Loading
drivers/gpu/drm/drm_bufs.c +65 −51 Original line number Diff line number Diff line Loading @@ -1258,11 +1258,11 @@ int drm_legacy_addbufs(struct drm_device *dev, void *data, * lock, preventing of allocating more buffers after this call. Information * about each requested buffer is then copied into user space. */ int drm_legacy_infobufs(struct drm_device *dev, void *data, struct drm_file *file_priv) int __drm_legacy_infobufs(struct drm_device *dev, void *data, int *p, int (*f)(void *, int, struct drm_buf_entry *)) { struct drm_device_dma *dma = dev->dma; struct drm_buf_info *request = data; int i; int count; Loading Loading @@ -1290,26 +1290,12 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data, DRM_DEBUG("count = %d\n", count); if (request->count >= count) { if (*p >= 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]; struct drm_buf_entry *from = &dma->bufs[i]; if (copy_to_user(&to->count, &from->buf_count, sizeof(from->buf_count)) || copy_to_user(&to->size, &from->buf_size, sizeof(from->buf_size)) || copy_to_user(&to->low_mark, &from->low_mark, sizeof(from->low_mark)) || copy_to_user(&to->high_mark, &from->high_mark, sizeof(from->high_mark))) if (from->buf_count) { if (f(data, count, from) < 0) return -EFAULT; DRM_DEBUG("%d %d %d %d %d\n", i, dma->bufs[i].buf_count, Loading @@ -1320,11 +1306,29 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data, } } } request->count = count; *p = count; return 0; } static int copy_one_buf(void *data, int count, struct drm_buf_entry *from) { struct drm_buf_info *request = data; struct drm_buf_desc __user *to = &request->list[count]; struct drm_buf_desc v = {.count = from->buf_count, .size = from->buf_size, .low_mark = from->low_mark, .high_mark = from->high_mark}; return copy_to_user(to, &v, offsetof(struct drm_buf_desc, flags)); } int drm_legacy_infobufs(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_buf_info *request = data; return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf); } /** * Specifies a low and high water mark for buffer allocation * Loading Loading @@ -1439,15 +1443,15 @@ int drm_legacy_freebufs(struct drm_device *dev, void *data, * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls * drm_mmap_dma(). */ int drm_legacy_mapbufs(struct drm_device *dev, void *data, int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p, void __user **v, int (*f)(void *, int, unsigned long, struct drm_buf *), struct drm_file *file_priv) { struct drm_device_dma *dma = dev->dma; int retcode = 0; const int zero = 0; unsigned long virtual; unsigned long address; struct drm_buf_map *request = data; int i; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) Loading @@ -1467,7 +1471,7 @@ int drm_legacy_mapbufs(struct drm_device *dev, void *data, dev->buf_use++; /* Can't allocate more after this call */ spin_unlock(&dev->buf_lock); if (request->count >= dma->buf_count) { if (*p >= dma->buf_count) { if ((dev->agp && (dma->flags & _DRM_DMA_USE_AGP)) || (drm_core_check_feature(dev, DRIVER_SG) && (dma->flags & _DRM_DMA_USE_SG))) { Loading @@ -1492,41 +1496,51 @@ int drm_legacy_mapbufs(struct drm_device *dev, void *data, retcode = (signed long)virtual; goto done; } request->virtual = (void __user *)virtual; *v = (void __user *)virtual; for (i = 0; i < dma->buf_count; i++) { if (copy_to_user(&request->list[i].idx, &dma->buflist[i]->idx, sizeof(request->list[0].idx))) { retcode = -EFAULT; goto done; } if (copy_to_user(&request->list[i].total, &dma->buflist[i]->total, sizeof(request->list[0].total))) { retcode = -EFAULT; goto done; } 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, &address, sizeof(address))) { if (f(data, i, virtual, dma->buflist[i]) < 0) { retcode = -EFAULT; goto done; } } } done: request->count = dma->buf_count; DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode); *p = dma->buf_count; DRM_DEBUG("%d buffers, retcode = %d\n", *p, retcode); return retcode; } static int map_one_buf(void *data, int idx, unsigned long virtual, struct drm_buf *buf) { struct drm_buf_map *request = data; unsigned long address = virtual + buf->offset; /* *** */ if (copy_to_user(&request->list[idx].idx, &buf->idx, sizeof(request->list[0].idx))) return -EFAULT; if (copy_to_user(&request->list[idx].total, &buf->total, sizeof(request->list[0].total))) return -EFAULT; if (clear_user(&request->list[idx].used, sizeof(int))) return -EFAULT; if (copy_to_user(&request->list[idx].address, &address, sizeof(address))) return -EFAULT; return 0; } int drm_legacy_mapbufs(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_buf_map *request = data; return __drm_legacy_mapbufs(dev, data, &request->count, &request->virtual, map_one_buf, file_priv); } int drm_legacy_dma_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { Loading
drivers/gpu/drm/drm_internal.h +3 −0 Original line number Diff line number Diff line Loading @@ -143,3 +143,6 @@ static inline int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc) return 0; } #endif drm_ioctl_t drm_version; drm_ioctl_t drm_getunique; drm_ioctl_t drm_getclient;