Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
drm_ioc32.c
Go to the documentation of this file.
1 
30 #include <linux/compat.h>
31 #include <linux/ratelimit.h>
32 #include <linux/export.h>
33 
34 #include <drm/drmP.h>
35 #include <drm/drm_core.h>
36 
37 #define DRM_IOCTL_VERSION32 DRM_IOWR(0x00, drm_version32_t)
38 #define DRM_IOCTL_GET_UNIQUE32 DRM_IOWR(0x01, drm_unique32_t)
39 #define DRM_IOCTL_GET_MAP32 DRM_IOWR(0x04, drm_map32_t)
40 #define DRM_IOCTL_GET_CLIENT32 DRM_IOWR(0x05, drm_client32_t)
41 #define DRM_IOCTL_GET_STATS32 DRM_IOR( 0x06, drm_stats32_t)
42 
43 #define DRM_IOCTL_SET_UNIQUE32 DRM_IOW( 0x10, drm_unique32_t)
44 #define DRM_IOCTL_ADD_MAP32 DRM_IOWR(0x15, drm_map32_t)
45 #define DRM_IOCTL_ADD_BUFS32 DRM_IOWR(0x16, drm_buf_desc32_t)
46 #define DRM_IOCTL_MARK_BUFS32 DRM_IOW( 0x17, drm_buf_desc32_t)
47 #define DRM_IOCTL_INFO_BUFS32 DRM_IOWR(0x18, drm_buf_info32_t)
48 #define DRM_IOCTL_MAP_BUFS32 DRM_IOWR(0x19, drm_buf_map32_t)
49 #define DRM_IOCTL_FREE_BUFS32 DRM_IOW( 0x1a, drm_buf_free32_t)
50 
51 #define DRM_IOCTL_RM_MAP32 DRM_IOW( 0x1b, drm_map32_t)
52 
53 #define DRM_IOCTL_SET_SAREA_CTX32 DRM_IOW( 0x1c, drm_ctx_priv_map32_t)
54 #define DRM_IOCTL_GET_SAREA_CTX32 DRM_IOWR(0x1d, drm_ctx_priv_map32_t)
55 
56 #define DRM_IOCTL_RES_CTX32 DRM_IOWR(0x26, drm_ctx_res32_t)
57 #define DRM_IOCTL_DMA32 DRM_IOWR(0x29, drm_dma32_t)
58 
59 #define DRM_IOCTL_AGP_ENABLE32 DRM_IOW( 0x32, drm_agp_mode32_t)
60 #define DRM_IOCTL_AGP_INFO32 DRM_IOR( 0x33, drm_agp_info32_t)
61 #define DRM_IOCTL_AGP_ALLOC32 DRM_IOWR(0x34, drm_agp_buffer32_t)
62 #define DRM_IOCTL_AGP_FREE32 DRM_IOW( 0x35, drm_agp_buffer32_t)
63 #define DRM_IOCTL_AGP_BIND32 DRM_IOW( 0x36, drm_agp_binding32_t)
64 #define DRM_IOCTL_AGP_UNBIND32 DRM_IOW( 0x37, drm_agp_binding32_t)
65 
66 #define DRM_IOCTL_SG_ALLOC32 DRM_IOW( 0x38, drm_scatter_gather32_t)
67 #define DRM_IOCTL_SG_FREE32 DRM_IOW( 0x39, drm_scatter_gather32_t)
68 
69 #define DRM_IOCTL_UPDATE_DRAW32 DRM_IOW( 0x3f, drm_update_draw32_t)
70 
71 #define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t)
72 
73 typedef struct drm_version_32 {
84 
85 static int compat_drm_version(struct file *file, unsigned int cmd,
86  unsigned long arg)
87 {
89  struct drm_version __user *version;
90  int err;
91 
92  if (copy_from_user(&v32, (void __user *)arg, sizeof(v32)))
93  return -EFAULT;
94 
95  version = compat_alloc_user_space(sizeof(*version));
96  if (!access_ok(VERIFY_WRITE, version, sizeof(*version)))
97  return -EFAULT;
98  if (__put_user(v32.name_len, &version->name_len)
99  || __put_user((void __user *)(unsigned long)v32.name,
100  &version->name)
101  || __put_user(v32.date_len, &version->date_len)
102  || __put_user((void __user *)(unsigned long)v32.date,
103  &version->date)
104  || __put_user(v32.desc_len, &version->desc_len)
105  || __put_user((void __user *)(unsigned long)v32.desc,
106  &version->desc))
107  return -EFAULT;
108 
109  err = drm_ioctl(file,
110  DRM_IOCTL_VERSION, (unsigned long)version);
111  if (err)
112  return err;
113 
114  if (__get_user(v32.version_major, &version->version_major)
115  || __get_user(v32.version_minor, &version->version_minor)
116  || __get_user(v32.version_patchlevel, &version->version_patchlevel)
117  || __get_user(v32.name_len, &version->name_len)
118  || __get_user(v32.date_len, &version->date_len)
119  || __get_user(v32.desc_len, &version->desc_len))
120  return -EFAULT;
121 
122  if (copy_to_user((void __user *)arg, &v32, sizeof(v32)))
123  return -EFAULT;
124  return 0;
125 }
126 
127 typedef struct drm_unique32 {
131 
132 static int compat_drm_getunique(struct file *file, unsigned int cmd,
133  unsigned long arg)
134 {
135  drm_unique32_t uq32;
136  struct drm_unique __user *u;
137  int err;
138 
139  if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
140  return -EFAULT;
141 
142  u = compat_alloc_user_space(sizeof(*u));
143  if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
144  return -EFAULT;
145  if (__put_user(uq32.unique_len, &u->unique_len)
146  || __put_user((void __user *)(unsigned long)uq32.unique,
147  &u->unique))
148  return -EFAULT;
149 
150  err = drm_ioctl(file, DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
151  if (err)
152  return err;
153 
154  if (__get_user(uq32.unique_len, &u->unique_len))
155  return -EFAULT;
156  if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32)))
157  return -EFAULT;
158  return 0;
159 }
160 
161 static int compat_drm_setunique(struct file *file, unsigned int cmd,
162  unsigned long arg)
163 {
164  drm_unique32_t uq32;
165  struct drm_unique __user *u;
166 
167  if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
168  return -EFAULT;
169 
170  u = compat_alloc_user_space(sizeof(*u));
171  if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
172  return -EFAULT;
173  if (__put_user(uq32.unique_len, &u->unique_len)
174  || __put_user((void __user *)(unsigned long)uq32.unique,
175  &u->unique))
176  return -EFAULT;
177 
178  return drm_ioctl(file, DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
179 }
180 
181 typedef struct drm_map32 {
187  int mtrr;
188 } drm_map32_t;
189 
190 static int compat_drm_getmap(struct file *file, unsigned int cmd,
191  unsigned long arg)
192 {
193  drm_map32_t __user *argp = (void __user *)arg;
194  drm_map32_t m32;
195  struct drm_map __user *map;
196  int idx, err;
197  void *handle;
198 
199  if (get_user(idx, &argp->offset))
200  return -EFAULT;
201 
202  map = compat_alloc_user_space(sizeof(*map));
203  if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
204  return -EFAULT;
205  if (__put_user(idx, &map->offset))
206  return -EFAULT;
207 
208  err = drm_ioctl(file, DRM_IOCTL_GET_MAP, (unsigned long)map);
209  if (err)
210  return err;
211 
212  if (__get_user(m32.offset, &map->offset)
213  || __get_user(m32.size, &map->size)
214  || __get_user(m32.type, &map->type)
215  || __get_user(m32.flags, &map->flags)
216  || __get_user(handle, &map->handle)
217  || __get_user(m32.mtrr, &map->mtrr))
218  return -EFAULT;
219 
220  m32.handle = (unsigned long)handle;
221  if (copy_to_user(argp, &m32, sizeof(m32)))
222  return -EFAULT;
223  return 0;
224 
225 }
226 
227 static int compat_drm_addmap(struct file *file, unsigned int cmd,
228  unsigned long arg)
229 {
230  drm_map32_t __user *argp = (void __user *)arg;
231  drm_map32_t m32;
232  struct drm_map __user *map;
233  int err;
234  void *handle;
235 
236  if (copy_from_user(&m32, argp, sizeof(m32)))
237  return -EFAULT;
238 
239  map = compat_alloc_user_space(sizeof(*map));
240  if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
241  return -EFAULT;
242  if (__put_user(m32.offset, &map->offset)
243  || __put_user(m32.size, &map->size)
244  || __put_user(m32.type, &map->type)
245  || __put_user(m32.flags, &map->flags))
246  return -EFAULT;
247 
248  err = drm_ioctl(file, DRM_IOCTL_ADD_MAP, (unsigned long)map);
249  if (err)
250  return err;
251 
252  if (__get_user(m32.offset, &map->offset)
253  || __get_user(m32.mtrr, &map->mtrr)
254  || __get_user(handle, &map->handle))
255  return -EFAULT;
256 
257  m32.handle = (unsigned long)handle;
258  if (m32.handle != (unsigned long)handle)
259  printk_ratelimited(KERN_ERR "compat_drm_addmap truncated handle"
260  " %p for type %d offset %x\n",
261  handle, m32.type, m32.offset);
262 
263  if (copy_to_user(argp, &m32, sizeof(m32)))
264  return -EFAULT;
265 
266  return 0;
267 }
268 
269 static int compat_drm_rmmap(struct file *file, unsigned int cmd,
270  unsigned long arg)
271 {
272  drm_map32_t __user *argp = (void __user *)arg;
273  struct drm_map __user *map;
274  u32 handle;
275 
276  if (get_user(handle, &argp->handle))
277  return -EFAULT;
278 
279  map = compat_alloc_user_space(sizeof(*map));
280  if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
281  return -EFAULT;
282  if (__put_user((void *)(unsigned long)handle, &map->handle))
283  return -EFAULT;
284 
285  return drm_ioctl(file, DRM_IOCTL_RM_MAP, (unsigned long)map);
286 }
287 
288 typedef struct drm_client32 {
289  int idx;
290  int auth;
296 
297 static int compat_drm_getclient(struct file *file, unsigned int cmd,
298  unsigned long arg)
299 {
300  drm_client32_t c32;
301  drm_client32_t __user *argp = (void __user *)arg;
302  struct drm_client __user *client;
303  int idx, err;
304 
305  if (get_user(idx, &argp->idx))
306  return -EFAULT;
307 
308  client = compat_alloc_user_space(sizeof(*client));
309  if (!access_ok(VERIFY_WRITE, client, sizeof(*client)))
310  return -EFAULT;
311  if (__put_user(idx, &client->idx))
312  return -EFAULT;
313 
314  err = drm_ioctl(file, DRM_IOCTL_GET_CLIENT, (unsigned long)client);
315  if (err)
316  return err;
317 
318  if (__get_user(c32.idx, &client->idx)
319  || __get_user(c32.auth, &client->auth)
320  || __get_user(c32.pid, &client->pid)
321  || __get_user(c32.uid, &client->uid)
322  || __get_user(c32.magic, &client->magic)
323  || __get_user(c32.iocs, &client->iocs))
324  return -EFAULT;
325 
326  if (copy_to_user(argp, &c32, sizeof(c32)))
327  return -EFAULT;
328  return 0;
329 }
330 
331 typedef struct drm_stats32 {
333  struct {
336  } data[15];
337 } drm_stats32_t;
338 
339 static int compat_drm_getstats(struct file *file, unsigned int cmd,
340  unsigned long arg)
341 {
343  drm_stats32_t __user *argp = (void __user *)arg;
344  struct drm_stats __user *stats;
345  int i, err;
346 
347  stats = compat_alloc_user_space(sizeof(*stats));
348  if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats)))
349  return -EFAULT;
350 
351  err = drm_ioctl(file, DRM_IOCTL_GET_STATS, (unsigned long)stats);
352  if (err)
353  return err;
354 
355  if (__get_user(s32.count, &stats->count))
356  return -EFAULT;
357  for (i = 0; i < 15; ++i)
358  if (__get_user(s32.data[i].value, &stats->data[i].value)
359  || __get_user(s32.data[i].type, &stats->data[i].type))
360  return -EFAULT;
361 
362  if (copy_to_user(argp, &s32, sizeof(s32)))
363  return -EFAULT;
364  return 0;
365 }
366 
367 typedef struct drm_buf_desc32 {
368  int count;
369  int size;
370  int low_mark;
371  int high_mark;
372  int flags;
375 
376 static int compat_drm_addbufs(struct file *file, unsigned int cmd,
377  unsigned long arg)
378 {
379  drm_buf_desc32_t __user *argp = (void __user *)arg;
380  struct drm_buf_desc __user *buf;
381  int err;
382  unsigned long agp_start;
383 
384  buf = compat_alloc_user_space(sizeof(*buf));
385  if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf))
386  || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)))
387  return -EFAULT;
388 
389  if (__copy_in_user(buf, argp, offsetof(drm_buf_desc32_t, agp_start))
390  || __get_user(agp_start, &argp->agp_start)
391  || __put_user(agp_start, &buf->agp_start))
392  return -EFAULT;
393 
394  err = drm_ioctl(file, DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
395  if (err)
396  return err;
397 
398  if (__copy_in_user(argp, buf, offsetof(drm_buf_desc32_t, agp_start))
399  || __get_user(agp_start, &buf->agp_start)
400  || __put_user(agp_start, &argp->agp_start))
401  return -EFAULT;
402 
403  return 0;
404 }
405 
406 static int compat_drm_markbufs(struct file *file, unsigned int cmd,
407  unsigned long arg)
408 {
409  drm_buf_desc32_t b32;
410  drm_buf_desc32_t __user *argp = (void __user *)arg;
411  struct drm_buf_desc __user *buf;
412 
413  if (copy_from_user(&b32, argp, sizeof(b32)))
414  return -EFAULT;
415 
416  buf = compat_alloc_user_space(sizeof(*buf));
417  if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)))
418  return -EFAULT;
419 
420  if (__put_user(b32.size, &buf->size)
421  || __put_user(b32.low_mark, &buf->low_mark)
422  || __put_user(b32.high_mark, &buf->high_mark))
423  return -EFAULT;
424 
425  return drm_ioctl(file, DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
426 }
427 
428 typedef struct drm_buf_info32 {
429  int count;
432 
433 static int compat_drm_infobufs(struct file *file, unsigned int cmd,
434  unsigned long arg)
435 {
436  drm_buf_info32_t req32;
437  drm_buf_info32_t __user *argp = (void __user *)arg;
439  struct drm_buf_info __user *request;
440  struct drm_buf_desc __user *list;
441  size_t nbytes;
442  int i, err;
443  int count, actual;
444 
445  if (copy_from_user(&req32, argp, sizeof(req32)))
446  return -EFAULT;
447 
448  count = req32.count;
449  to = (drm_buf_desc32_t __user *) (unsigned long)req32.list;
450  if (count < 0)
451  count = 0;
452  if (count > 0
453  && !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t)))
454  return -EFAULT;
455 
456  nbytes = sizeof(*request) + count * sizeof(struct drm_buf_desc);
457  request = compat_alloc_user_space(nbytes);
458  if (!access_ok(VERIFY_WRITE, request, nbytes))
459  return -EFAULT;
460  list = (struct drm_buf_desc *) (request + 1);
461 
462  if (__put_user(count, &request->count)
463  || __put_user(list, &request->list))
464  return -EFAULT;
465 
466  err = drm_ioctl(file, DRM_IOCTL_INFO_BUFS, (unsigned long)request);
467  if (err)
468  return err;
469 
470  if (__get_user(actual, &request->count))
471  return -EFAULT;
472  if (count >= actual)
473  for (i = 0; i < actual; ++i)
474  if (__copy_in_user(&to[i], &list[i],
475  offsetof(struct drm_buf_desc, flags)))
476  return -EFAULT;
477 
478  if (__put_user(actual, &argp->count))
479  return -EFAULT;
480 
481  return 0;
482 }
483 
484 typedef struct drm_buf_pub32 {
485  int idx;
486  int total;
487  int used;
490 
491 typedef struct drm_buf_map32 {
492  int count;
493  u32 virtual;
496 
497 static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
498  unsigned long arg)
499 {
500  drm_buf_map32_t __user *argp = (void __user *)arg;
501  drm_buf_map32_t req32;
502  drm_buf_pub32_t __user *list32;
503  struct drm_buf_map __user *request;
504  struct drm_buf_pub __user *list;
505  int i, err;
506  int count, actual;
507  size_t nbytes;
508  void __user *addr;
509 
510  if (copy_from_user(&req32, argp, sizeof(req32)))
511  return -EFAULT;
512  count = req32.count;
513  list32 = (void __user *)(unsigned long)req32.list;
514 
515  if (count < 0)
516  return -EINVAL;
517  nbytes = sizeof(*request) + count * sizeof(struct drm_buf_pub);
518  request = compat_alloc_user_space(nbytes);
519  if (!access_ok(VERIFY_WRITE, request, nbytes))
520  return -EFAULT;
521  list = (struct drm_buf_pub *) (request + 1);
522 
523  if (__put_user(count, &request->count)
524  || __put_user(list, &request->list))
525  return -EFAULT;
526 
527  err = drm_ioctl(file, DRM_IOCTL_MAP_BUFS, (unsigned long)request);
528  if (err)
529  return err;
530 
531  if (__get_user(actual, &request->count))
532  return -EFAULT;
533  if (count >= actual)
534  for (i = 0; i < actual; ++i)
535  if (__copy_in_user(&list32[i], &list[i],
536  offsetof(struct drm_buf_pub, address))
537  || __get_user(addr, &list[i].address)
538  || __put_user((unsigned long)addr,
539  &list32[i].address))
540  return -EFAULT;
541 
542  if (__put_user(actual, &argp->count)
543  || __get_user(addr, &request->virtual)
544  || __put_user((unsigned long)addr, &argp->virtual))
545  return -EFAULT;
546 
547  return 0;
548 }
549 
550 typedef struct drm_buf_free32 {
551  int count;
554 
555 static int compat_drm_freebufs(struct file *file, unsigned int cmd,
556  unsigned long arg)
557 {
558  drm_buf_free32_t req32;
559  struct drm_buf_free __user *request;
560  drm_buf_free32_t __user *argp = (void __user *)arg;
561 
562  if (copy_from_user(&req32, argp, sizeof(req32)))
563  return -EFAULT;
564 
565  request = compat_alloc_user_space(sizeof(*request));
566  if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
567  return -EFAULT;
568  if (__put_user(req32.count, &request->count)
569  || __put_user((int __user *)(unsigned long)req32.list,
570  &request->list))
571  return -EFAULT;
572 
573  return drm_ioctl(file, DRM_IOCTL_FREE_BUFS, (unsigned long)request);
574 }
575 
576 typedef struct drm_ctx_priv_map32 {
577  unsigned int ctx_id;
580 
581 static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
582  unsigned long arg)
583 {
584  drm_ctx_priv_map32_t req32;
585  struct drm_ctx_priv_map __user *request;
586  drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
587 
588  if (copy_from_user(&req32, argp, sizeof(req32)))
589  return -EFAULT;
590 
591  request = compat_alloc_user_space(sizeof(*request));
592  if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
593  return -EFAULT;
594  if (__put_user(req32.ctx_id, &request->ctx_id)
595  || __put_user((void *)(unsigned long)req32.handle,
596  &request->handle))
597  return -EFAULT;
598 
599  return drm_ioctl(file, DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
600 }
601 
602 static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
603  unsigned long arg)
604 {
606  drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
607  int err;
608  unsigned int ctx_id;
609  void *handle;
610 
611  if (!access_ok(VERIFY_WRITE, argp, sizeof(*argp))
612  || __get_user(ctx_id, &argp->ctx_id))
613  return -EFAULT;
614 
615  request = compat_alloc_user_space(sizeof(*request));
616  if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
617  return -EFAULT;
618  if (__put_user(ctx_id, &request->ctx_id))
619  return -EFAULT;
620 
621  err = drm_ioctl(file, DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
622  if (err)
623  return err;
624 
625  if (__get_user(handle, &request->handle)
626  || __put_user((unsigned long)handle, &argp->handle))
627  return -EFAULT;
628 
629  return 0;
630 }
631 
632 typedef struct drm_ctx_res32 {
633  int count;
636 
637 static int compat_drm_resctx(struct file *file, unsigned int cmd,
638  unsigned long arg)
639 {
640  drm_ctx_res32_t __user *argp = (void __user *)arg;
641  drm_ctx_res32_t res32;
642  struct drm_ctx_res __user *res;
643  int err;
644 
645  if (copy_from_user(&res32, argp, sizeof(res32)))
646  return -EFAULT;
647 
648  res = compat_alloc_user_space(sizeof(*res));
649  if (!access_ok(VERIFY_WRITE, res, sizeof(*res)))
650  return -EFAULT;
651  if (__put_user(res32.count, &res->count)
652  || __put_user((struct drm_ctx __user *) (unsigned long)res32.contexts,
653  &res->contexts))
654  return -EFAULT;
655 
656  err = drm_ioctl(file, DRM_IOCTL_RES_CTX, (unsigned long)res);
657  if (err)
658  return err;
659 
660  if (__get_user(res32.count, &res->count)
661  || __put_user(res32.count, &argp->count))
662  return -EFAULT;
663 
664  return 0;
665 }
666 
667 typedef struct drm_dma32 {
668  int context;
678 } drm_dma32_t;
679 
680 static int compat_drm_dma(struct file *file, unsigned int cmd,
681  unsigned long arg)
682 {
683  drm_dma32_t d32;
684  drm_dma32_t __user *argp = (void __user *)arg;
685  struct drm_dma __user *d;
686  int err;
687 
688  if (copy_from_user(&d32, argp, sizeof(d32)))
689  return -EFAULT;
690 
691  d = compat_alloc_user_space(sizeof(*d));
692  if (!access_ok(VERIFY_WRITE, d, sizeof(*d)))
693  return -EFAULT;
694 
695  if (__put_user(d32.context, &d->context)
696  || __put_user(d32.send_count, &d->send_count)
697  || __put_user((int __user *)(unsigned long)d32.send_indices,
698  &d->send_indices)
699  || __put_user((int __user *)(unsigned long)d32.send_sizes,
700  &d->send_sizes)
701  || __put_user(d32.flags, &d->flags)
703  || __put_user((int __user *)(unsigned long)d32.request_indices,
704  &d->request_indices)
705  || __put_user((int __user *)(unsigned long)d32.request_sizes,
706  &d->request_sizes))
707  return -EFAULT;
708 
709  err = drm_ioctl(file, DRM_IOCTL_DMA, (unsigned long)d);
710  if (err)
711  return err;
712 
713  if (__get_user(d32.request_size, &d->request_size)
714  || __get_user(d32.granted_count, &d->granted_count)
715  || __put_user(d32.request_size, &argp->request_size)
716  || __put_user(d32.granted_count, &argp->granted_count))
717  return -EFAULT;
718 
719  return 0;
720 }
721 
722 #if __OS_HAS_AGP
723 typedef struct drm_agp_mode32 {
724  u32 mode;
725 } drm_agp_mode32_t;
726 
727 static int compat_drm_agp_enable(struct file *file, unsigned int cmd,
728  unsigned long arg)
729 {
730  drm_agp_mode32_t __user *argp = (void __user *)arg;
731  drm_agp_mode32_t m32;
732  struct drm_agp_mode __user *mode;
733 
734  if (get_user(m32.mode, &argp->mode))
735  return -EFAULT;
736 
737  mode = compat_alloc_user_space(sizeof(*mode));
738  if (put_user(m32.mode, &mode->mode))
739  return -EFAULT;
740 
741  return drm_ioctl(file, DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
742 }
743 
744 typedef struct drm_agp_info32 {
745  int agp_version_major;
746  int agp_version_minor;
747  u32 mode;
748  u32 aperture_base; /* physical address */
749  u32 aperture_size; /* bytes */
750  u32 memory_allowed; /* bytes */
751  u32 memory_used;
752 
753  /* PCI information */
754  unsigned short id_vendor;
755  unsigned short id_device;
756 } drm_agp_info32_t;
757 
758 static int compat_drm_agp_info(struct file *file, unsigned int cmd,
759  unsigned long arg)
760 {
761  drm_agp_info32_t __user *argp = (void __user *)arg;
762  drm_agp_info32_t i32;
763  struct drm_agp_info __user *info;
764  int err;
765 
766  info = compat_alloc_user_space(sizeof(*info));
767  if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
768  return -EFAULT;
769 
770  err = drm_ioctl(file, DRM_IOCTL_AGP_INFO, (unsigned long)info);
771  if (err)
772  return err;
773 
774  if (__get_user(i32.agp_version_major, &info->agp_version_major)
775  || __get_user(i32.agp_version_minor, &info->agp_version_minor)
776  || __get_user(i32.mode, &info->mode)
777  || __get_user(i32.aperture_base, &info->aperture_base)
778  || __get_user(i32.aperture_size, &info->aperture_size)
779  || __get_user(i32.memory_allowed, &info->memory_allowed)
780  || __get_user(i32.memory_used, &info->memory_used)
781  || __get_user(i32.id_vendor, &info->id_vendor)
782  || __get_user(i32.id_device, &info->id_device))
783  return -EFAULT;
784 
785  if (copy_to_user(argp, &i32, sizeof(i32)))
786  return -EFAULT;
787 
788  return 0;
789 }
790 
791 typedef struct drm_agp_buffer32 {
792  u32 size;
793  u32 handle;
794  u32 type;
795  u32 physical;
796 } drm_agp_buffer32_t;
797 
798 static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
799  unsigned long arg)
800 {
801  drm_agp_buffer32_t __user *argp = (void __user *)arg;
802  drm_agp_buffer32_t req32;
803  struct drm_agp_buffer __user *request;
804  int err;
805 
806  if (copy_from_user(&req32, argp, sizeof(req32)))
807  return -EFAULT;
808 
809  request = compat_alloc_user_space(sizeof(*request));
810  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
811  || __put_user(req32.size, &request->size)
812  || __put_user(req32.type, &request->type))
813  return -EFAULT;
814 
815  err = drm_ioctl(file, DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
816  if (err)
817  return err;
818 
819  if (__get_user(req32.handle, &request->handle)
820  || __get_user(req32.physical, &request->physical)
821  || copy_to_user(argp, &req32, sizeof(req32))) {
822  drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request);
823  return -EFAULT;
824  }
825 
826  return 0;
827 }
828 
829 static int compat_drm_agp_free(struct file *file, unsigned int cmd,
830  unsigned long arg)
831 {
832  drm_agp_buffer32_t __user *argp = (void __user *)arg;
833  struct drm_agp_buffer __user *request;
834  u32 handle;
835 
836  request = compat_alloc_user_space(sizeof(*request));
837  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
838  || get_user(handle, &argp->handle)
839  || __put_user(handle, &request->handle))
840  return -EFAULT;
841 
842  return drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request);
843 }
844 
845 typedef struct drm_agp_binding32 {
846  u32 handle;
847  u32 offset;
848 } drm_agp_binding32_t;
849 
850 static int compat_drm_agp_bind(struct file *file, unsigned int cmd,
851  unsigned long arg)
852 {
853  drm_agp_binding32_t __user *argp = (void __user *)arg;
854  drm_agp_binding32_t req32;
856 
857  if (copy_from_user(&req32, argp, sizeof(req32)))
858  return -EFAULT;
859 
860  request = compat_alloc_user_space(sizeof(*request));
861  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
862  || __put_user(req32.handle, &request->handle)
863  || __put_user(req32.offset, &request->offset))
864  return -EFAULT;
865 
866  return drm_ioctl(file, DRM_IOCTL_AGP_BIND, (unsigned long)request);
867 }
868 
869 static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
870  unsigned long arg)
871 {
872  drm_agp_binding32_t __user *argp = (void __user *)arg;
874  u32 handle;
875 
876  request = compat_alloc_user_space(sizeof(*request));
877  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
878  || get_user(handle, &argp->handle)
879  || __put_user(handle, &request->handle))
880  return -EFAULT;
881 
882  return drm_ioctl(file, DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
883 }
884 #endif /* __OS_HAS_AGP */
885 
886 typedef struct drm_scatter_gather32 {
890 
891 static int compat_drm_sg_alloc(struct file *file, unsigned int cmd,
892  unsigned long arg)
893 {
894  drm_scatter_gather32_t __user *argp = (void __user *)arg;
895  struct drm_scatter_gather __user *request;
896  int err;
897  unsigned long x;
898 
899  request = compat_alloc_user_space(sizeof(*request));
900  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
901  || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))
902  || __get_user(x, &argp->size)
903  || __put_user(x, &request->size))
904  return -EFAULT;
905 
906  err = drm_ioctl(file, DRM_IOCTL_SG_ALLOC, (unsigned long)request);
907  if (err)
908  return err;
909 
910  /* XXX not sure about the handle conversion here... */
911  if (__get_user(x, &request->handle)
912  || __put_user(x >> PAGE_SHIFT, &argp->handle))
913  return -EFAULT;
914 
915  return 0;
916 }
917 
918 static int compat_drm_sg_free(struct file *file, unsigned int cmd,
919  unsigned long arg)
920 {
921  drm_scatter_gather32_t __user *argp = (void __user *)arg;
923  unsigned long x;
924 
925  request = compat_alloc_user_space(sizeof(*request));
926  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
927  || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))
928  || __get_user(x, &argp->handle)
929  || __put_user(x << PAGE_SHIFT, &request->handle))
930  return -EFAULT;
931 
932  return drm_ioctl(file, DRM_IOCTL_SG_FREE, (unsigned long)request);
933 }
934 
935 #if defined(CONFIG_X86) || defined(CONFIG_IA64)
936 typedef struct drm_update_draw32 {
938  unsigned int type;
939  unsigned int num;
940  /* 64-bit version has a 32-bit pad here */
941  u64 data;
942 } __attribute__((packed)) drm_update_draw32_t;
943 
944 static int compat_drm_update_draw(struct file *file, unsigned int cmd,
945  unsigned long arg)
946 {
947  drm_update_draw32_t update32;
949  int err;
950 
951  if (copy_from_user(&update32, (void __user *)arg, sizeof(update32)))
952  return -EFAULT;
953 
954  request = compat_alloc_user_space(sizeof(*request));
955  if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) ||
956  __put_user(update32.handle, &request->handle) ||
957  __put_user(update32.type, &request->type) ||
958  __put_user(update32.num, &request->num) ||
959  __put_user(update32.data, &request->data))
960  return -EFAULT;
961 
962  err = drm_ioctl(file, DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
963  return err;
964 }
965 #endif
966 
969  unsigned int sequence;
971 };
972 
975  unsigned int sequence;
978 };
979 
980 typedef union drm_wait_vblank32 {
984 
985 static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
986  unsigned long arg)
987 {
988  drm_wait_vblank32_t __user *argp = (void __user *)arg;
989  drm_wait_vblank32_t req32;
991  int err;
992 
993  if (copy_from_user(&req32, argp, sizeof(req32)))
994  return -EFAULT;
995 
996  request = compat_alloc_user_space(sizeof(*request));
997  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
998  || __put_user(req32.request.type, &request->request.type)
999  || __put_user(req32.request.sequence, &request->request.sequence)
1000  || __put_user(req32.request.signal, &request->request.signal))
1001  return -EFAULT;
1002 
1003  err = drm_ioctl(file, DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
1004  if (err)
1005  return err;
1006 
1007  if (__get_user(req32.reply.type, &request->reply.type)
1008  || __get_user(req32.reply.sequence, &request->reply.sequence)
1009  || __get_user(req32.reply.tval_sec, &request->reply.tval_sec)
1010  || __get_user(req32.reply.tval_usec, &request->reply.tval_usec))
1011  return -EFAULT;
1012 
1013  if (copy_to_user(argp, &req32, sizeof(req32)))
1014  return -EFAULT;
1015 
1016  return 0;
1017 }
1018 
1019 drm_ioctl_compat_t *drm_compat_ioctls[] = {
1020  [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version,
1021  [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique,
1022  [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap,
1023  [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT32)] = compat_drm_getclient,
1024  [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS32)] = compat_drm_getstats,
1025  [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE32)] = compat_drm_setunique,
1026  [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP32)] = compat_drm_addmap,
1027  [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS32)] = compat_drm_addbufs,
1028  [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS32)] = compat_drm_markbufs,
1029  [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS32)] = compat_drm_infobufs,
1030  [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS32)] = compat_drm_mapbufs,
1031  [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS32)] = compat_drm_freebufs,
1032  [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP32)] = compat_drm_rmmap,
1033  [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX32)] = compat_drm_setsareactx,
1034  [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX32)] = compat_drm_getsareactx,
1035  [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX32)] = compat_drm_resctx,
1036  [DRM_IOCTL_NR(DRM_IOCTL_DMA32)] = compat_drm_dma,
1037 #if __OS_HAS_AGP
1038  [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE32)] = compat_drm_agp_enable,
1039  [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO32)] = compat_drm_agp_info,
1040  [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC32)] = compat_drm_agp_alloc,
1041  [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE32)] = compat_drm_agp_free,
1042  [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND32)] = compat_drm_agp_bind,
1043  [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND32)] = compat_drm_agp_unbind,
1044 #endif
1045  [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc,
1046  [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free,
1047 #if defined(CONFIG_X86) || defined(CONFIG_IA64)
1048  [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw,
1049 #endif
1050  [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
1051 };
1052 
1062 long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1063 {
1064  unsigned int nr = DRM_IOCTL_NR(cmd);
1065  drm_ioctl_compat_t *fn;
1066  int ret;
1067 
1068  /* Assume that ioctls without an explicit compat routine will just
1069  * work. This may not always be a good assumption, but it's better
1070  * than always failing.
1071  */
1072  if (nr >= ARRAY_SIZE(drm_compat_ioctls))
1073  return drm_ioctl(filp, cmd, arg);
1074 
1075  fn = drm_compat_ioctls[nr];
1076 
1077  if (fn != NULL)
1078  ret = (*fn) (filp, cmd, arg);
1079  else
1080  ret = drm_ioctl(filp, cmd, arg);
1081 
1082  return ret;
1083 }
1084