Commit 5c7640ab authored by Al Viro's avatar Al Viro

switch compat_drm_infobufs() to drm_ioctl_kernel()

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 8c4fe499
...@@ -1258,11 +1258,11 @@ int drm_legacy_addbufs(struct drm_device *dev, void *data, ...@@ -1258,11 +1258,11 @@ int drm_legacy_addbufs(struct drm_device *dev, void *data,
* lock, preventing of allocating more buffers after this call. Information * lock, preventing of allocating more buffers after this call. Information
* about each requested buffer is then copied into user space. * about each requested buffer is then copied into user space.
*/ */
int drm_legacy_infobufs(struct drm_device *dev, void *data, int __drm_legacy_infobufs(struct drm_device *dev,
struct drm_file *file_priv) void *data, int *p,
int (*f)(void *, int, struct drm_buf_entry *))
{ {
struct drm_device_dma *dma = dev->dma; struct drm_device_dma *dma = dev->dma;
struct drm_buf_info *request = data;
int i; int i;
int count; int count;
...@@ -1290,26 +1290,12 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data, ...@@ -1290,26 +1290,12 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data,
DRM_DEBUG("count = %d\n", count); DRM_DEBUG("count = %d\n", count);
if (request->count >= count) { if (*p >= count) {
for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { 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]; struct drm_buf_entry *from = &dma->bufs[i];
if (copy_to_user(&to->count, if (from->buf_count) {
&from->buf_count, if (f(data, count, from) < 0)
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)))
return -EFAULT; return -EFAULT;
DRM_DEBUG("%d %d %d %d %d\n", DRM_DEBUG("%d %d %d %d %d\n",
i, i,
dma->bufs[i].buf_count, dma->bufs[i].buf_count,
...@@ -1320,11 +1306,29 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data, ...@@ -1320,11 +1306,29 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data,
} }
} }
} }
request->count = count; *p = count;
return 0; 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 * Specifies a low and high water mark for buffer allocation
* *
......
...@@ -396,52 +396,42 @@ typedef struct drm_buf_info32 { ...@@ -396,52 +396,42 @@ typedef struct drm_buf_info32 {
u32 list; u32 list;
} drm_buf_info32_t; } drm_buf_info32_t;
static int copy_one_buf32(void *data, int count, struct drm_buf_entry *from)
{
drm_buf_info32_t *request = data;
drm_buf_desc32_t __user *to = compat_ptr(request->list);
drm_buf_desc32_t v = {.count = from->buf_count,
.size = from->buf_size,
.low_mark = from->low_mark,
.high_mark = from->high_mark};
return copy_to_user(to + count, &v, offsetof(drm_buf_desc32_t, flags));
}
static int drm_legacy_infobufs32(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
drm_buf_info32_t *request = data;
return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf32);
}
static int compat_drm_infobufs(struct file *file, unsigned int cmd, static int compat_drm_infobufs(struct file *file, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
drm_buf_info32_t req32; drm_buf_info32_t req32;
drm_buf_info32_t __user *argp = (void __user *)arg; drm_buf_info32_t __user *argp = (void __user *)arg;
drm_buf_desc32_t __user *to; int err;
struct drm_buf_info __user *request;
struct drm_buf_desc __user *list;
size_t nbytes;
int i, err;
int count, actual;
if (copy_from_user(&req32, argp, sizeof(req32))) if (copy_from_user(&req32, argp, sizeof(req32)))
return -EFAULT; return -EFAULT;
count = req32.count; if (req32.count < 0)
to = (drm_buf_desc32_t __user *) (unsigned long)req32.list; req32.count = 0;
if (count < 0)
count = 0;
if (count > 0
&& !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t)))
return -EFAULT;
nbytes = sizeof(*request) + count * sizeof(struct drm_buf_desc); err = drm_ioctl_kernel(file, drm_legacy_infobufs32, &req32, DRM_AUTH);
request = compat_alloc_user_space(nbytes);
if (!request)
return -EFAULT;
list = (struct drm_buf_desc *) (request + 1);
if (__put_user(count, &request->count)
|| __put_user(list, &request->list))
return -EFAULT;
err = drm_ioctl(file, DRM_IOCTL_INFO_BUFS, (unsigned long)request);
if (err) if (err)
return err; return err;
if (__get_user(actual, &request->count)) if (put_user(req32.count, &argp->count))
return -EFAULT;
if (count >= actual)
for (i = 0; i < actual; ++i)
if (__copy_in_user(&to[i], &list[i],
offsetof(struct drm_buf_desc, flags)))
return -EFAULT;
if (__put_user(actual, &argp->count))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -1053,7 +1043,7 @@ static struct { ...@@ -1053,7 +1043,7 @@ static struct {
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP32)].fn = compat_drm_addmap, [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP32)].fn = compat_drm_addmap,
DRM_IOCTL32_DEF(DRM_IOCTL_ADD_BUFS, compat_drm_addbufs), DRM_IOCTL32_DEF(DRM_IOCTL_ADD_BUFS, compat_drm_addbufs),
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS32)].fn = compat_drm_markbufs, [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS32)].fn = compat_drm_markbufs,
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS32)].fn = compat_drm_infobufs, DRM_IOCTL32_DEF(DRM_IOCTL_INFO_BUFS, compat_drm_infobufs),
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS32)].fn = compat_drm_mapbufs, [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS32)].fn = compat_drm_mapbufs,
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS32)].fn = compat_drm_freebufs, [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS32)].fn = compat_drm_freebufs,
[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP32)].fn = compat_drm_rmmap, [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP32)].fn = compat_drm_rmmap,
......
...@@ -74,6 +74,9 @@ int drm_legacy_freebufs(struct drm_device *d, void *v, struct drm_file *f); ...@@ -74,6 +74,9 @@ int drm_legacy_freebufs(struct drm_device *d, void *v, struct drm_file *f);
int drm_legacy_mapbufs(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_mapbufs(struct drm_device *d, void *v, struct drm_file *f);
int drm_legacy_dma_ioctl(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_dma_ioctl(struct drm_device *d, void *v, struct drm_file *f);
int __drm_legacy_infobufs(struct drm_device *, void *, int *,
int (*)(void *, int, struct drm_buf_entry *));
#ifdef CONFIG_DRM_VM #ifdef CONFIG_DRM_VM
void drm_legacy_vma_flush(struct drm_device *d); void drm_legacy_vma_flush(struct drm_device *d);
#else #else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment