1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include <linux/export.h>
32#include <linux/nospec.h>
33#include <linux/pci.h>
34#include <linux/uaccess.h>
35
36#include <drm/drm_agpsupport.h>
37#include <drm/drm_auth.h>
38#include <drm/drm_crtc.h>
39#include <drm/drm_drv.h>
40#include <drm/drm_file.h>
41#include <drm/drm_ioctl.h>
42#include <drm/drm_print.h>
43
44#include "drm_crtc_internal.h"
45#include "drm_internal.h"
46#include "drm_legacy.h"
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117int drm_getunique(struct drm_device *dev, void *data,
118 struct drm_file *file_priv)
119{
120 struct drm_unique *u = data;
121 struct drm_master *master = file_priv->master;
122
123 mutex_lock(&master->dev->master_mutex);
124 if (u->unique_len >= master->unique_len) {
125 if (copy_to_user(u->unique, master->unique, master->unique_len)) {
126 mutex_unlock(&master->dev->master_mutex);
127 return -EFAULT;
128 }
129 }
130 u->unique_len = master->unique_len;
131 mutex_unlock(&master->dev->master_mutex);
132
133 return 0;
134}
135
136static void
137drm_unset_busid(struct drm_device *dev,
138 struct drm_master *master)
139{
140 kfree(master->unique);
141 master->unique = NULL;
142 master->unique_len = 0;
143}
144
145static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
146{
147 struct drm_master *master = file_priv->master;
148 int ret;
149
150 if (master->unique != NULL)
151 drm_unset_busid(dev, master);
152
153 if (dev->dev && dev_is_pci(dev->dev)) {
154 ret = drm_pci_set_busid(dev, master);
155 if (ret) {
156 drm_unset_busid(dev, master);
157 return ret;
158 }
159 } else {
160 WARN_ON(!dev->unique);
161 master->unique = kstrdup(dev->unique, GFP_KERNEL);
162 if (master->unique)
163 master->unique_len = strlen(dev->unique);
164 }
165
166 return 0;
167}
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182int drm_getclient(struct drm_device *dev, void *data,
183 struct drm_file *file_priv)
184{
185 struct drm_client *client = data;
186
187
188
189
190
191
192
193
194
195
196
197
198 if (client->idx == 0) {
199 client->auth = file_priv->authenticated;
200 client->pid = task_pid_vnr(current);
201 client->uid = overflowuid;
202 client->magic = 0;
203 client->iocs = 0;
204
205 return 0;
206 } else {
207 return -EINVAL;
208 }
209}
210
211
212
213
214
215
216
217
218
219
220
221static int drm_getstats(struct drm_device *dev, void *data,
222 struct drm_file *file_priv)
223{
224 struct drm_stats *stats = data;
225
226
227 memset(stats, 0, sizeof(*stats));
228
229 return 0;
230}
231
232
233
234
235static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
236{
237 struct drm_get_cap *req = data;
238 struct drm_crtc *crtc;
239
240 req->value = 0;
241
242
243 switch (req->capability) {
244 case DRM_CAP_TIMESTAMP_MONOTONIC:
245 req->value = 1;
246 return 0;
247 case DRM_CAP_PRIME:
248 req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0;
249 req->value |= dev->driver->prime_handle_to_fd ? DRM_PRIME_CAP_EXPORT : 0;
250 return 0;
251 case DRM_CAP_SYNCOBJ:
252 req->value = drm_core_check_feature(dev, DRIVER_SYNCOBJ);
253 return 0;
254 case DRM_CAP_SYNCOBJ_TIMELINE:
255 req->value = drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE);
256 return 0;
257 }
258
259
260 if (!drm_core_check_feature(dev, DRIVER_MODESET))
261 return -EOPNOTSUPP;
262
263 switch (req->capability) {
264 case DRM_CAP_DUMB_BUFFER:
265 if (dev->driver->dumb_create)
266 req->value = 1;
267 break;
268 case DRM_CAP_VBLANK_HIGH_CRTC:
269 req->value = 1;
270 break;
271 case DRM_CAP_DUMB_PREFERRED_DEPTH:
272 req->value = dev->mode_config.preferred_depth;
273 break;
274 case DRM_CAP_DUMB_PREFER_SHADOW:
275 req->value = dev->mode_config.prefer_shadow;
276 break;
277 case DRM_CAP_ASYNC_PAGE_FLIP:
278 req->value = dev->mode_config.async_page_flip;
279 break;
280 case DRM_CAP_PAGE_FLIP_TARGET:
281 req->value = 1;
282 drm_for_each_crtc(crtc, dev) {
283 if (!crtc->funcs->page_flip_target)
284 req->value = 0;
285 }
286 break;
287 case DRM_CAP_CURSOR_WIDTH:
288 if (dev->mode_config.cursor_width)
289 req->value = dev->mode_config.cursor_width;
290 else
291 req->value = 64;
292 break;
293 case DRM_CAP_CURSOR_HEIGHT:
294 if (dev->mode_config.cursor_height)
295 req->value = dev->mode_config.cursor_height;
296 else
297 req->value = 64;
298 break;
299 case DRM_CAP_ADDFB2_MODIFIERS:
300 req->value = dev->mode_config.allow_fb_modifiers;
301 break;
302 case DRM_CAP_CRTC_IN_VBLANK_EVENT:
303 req->value = 1;
304 break;
305 default:
306 return -EINVAL;
307 }
308 return 0;
309}
310
311
312
313
314static int
315drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
316{
317 struct drm_set_client_cap *req = data;
318
319
320
321
322 if (!drm_core_check_feature(dev, DRIVER_MODESET))
323 return -EOPNOTSUPP;
324
325 switch (req->capability) {
326 case DRM_CLIENT_CAP_STEREO_3D:
327 if (req->value > 1)
328 return -EINVAL;
329 file_priv->stereo_allowed = req->value;
330 break;
331 case DRM_CLIENT_CAP_UNIVERSAL_PLANES:
332 if (req->value > 1)
333 return -EINVAL;
334 file_priv->universal_planes = req->value;
335 break;
336 case DRM_CLIENT_CAP_ATOMIC:
337 if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
338 return -EOPNOTSUPP;
339
340 if (current->comm[0] == 'X' && req->value == 1) {
341 pr_info("broken atomic modeset userspace detected, disabling atomic\n");
342 return -EOPNOTSUPP;
343 }
344 if (req->value > 2)
345 return -EINVAL;
346 file_priv->atomic = req->value;
347 file_priv->universal_planes = req->value;
348
349
350
351 file_priv->aspect_ratio_allowed = req->value;
352 break;
353 case DRM_CLIENT_CAP_ASPECT_RATIO:
354 if (req->value > 1)
355 return -EINVAL;
356 file_priv->aspect_ratio_allowed = req->value;
357 break;
358 case DRM_CLIENT_CAP_WRITEBACK_CONNECTORS:
359 if (!file_priv->atomic)
360 return -EINVAL;
361 if (req->value > 1)
362 return -EINVAL;
363 file_priv->writeback_connectors = req->value;
364 break;
365 default:
366 return -EINVAL;
367 }
368
369 return 0;
370}
371
372
373
374
375
376
377
378
379
380
381
382
383static int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv)
384{
385 struct drm_set_version *sv = data;
386 int if_version, retcode = 0;
387
388 mutex_lock(&dev->master_mutex);
389 if (sv->drm_di_major != -1) {
390 if (sv->drm_di_major != DRM_IF_MAJOR ||
391 sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) {
392 retcode = -EINVAL;
393 goto done;
394 }
395 if_version = DRM_IF_VERSION(sv->drm_di_major,
396 sv->drm_di_minor);
397 dev->if_version = max(if_version, dev->if_version);
398 if (sv->drm_di_minor >= 1) {
399
400
401
402
403 retcode = drm_set_busid(dev, file_priv);
404 if (retcode)
405 goto done;
406 }
407 }
408
409 if (sv->drm_dd_major != -1) {
410 if (sv->drm_dd_major != dev->driver->major ||
411 sv->drm_dd_minor < 0 || sv->drm_dd_minor >
412 dev->driver->minor) {
413 retcode = -EINVAL;
414 goto done;
415 }
416 }
417
418done:
419 sv->drm_di_major = DRM_IF_MAJOR;
420 sv->drm_di_minor = DRM_IF_MINOR;
421 sv->drm_dd_major = dev->driver->major;
422 sv->drm_dd_minor = dev->driver->minor;
423 mutex_unlock(&dev->master_mutex);
424
425 return retcode;
426}
427
428
429
430
431
432
433
434
435
436
437
438
439
440int drm_noop(struct drm_device *dev, void *data,
441 struct drm_file *file_priv)
442{
443 DRM_DEBUG("\n");
444 return 0;
445}
446EXPORT_SYMBOL(drm_noop);
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463int drm_invalid_op(struct drm_device *dev, void *data,
464 struct drm_file *file_priv)
465{
466 return -EINVAL;
467}
468EXPORT_SYMBOL(drm_invalid_op);
469
470
471
472
473static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value)
474{
475 int len;
476
477
478 len = strlen(value);
479 if (len > *buf_len)
480 len = *buf_len;
481
482
483
484 *buf_len = strlen(value);
485
486
487 if (len && buf)
488 if (copy_to_user(buf, value, len))
489 return -EFAULT;
490 return 0;
491}
492
493
494
495
496
497
498
499
500
501
502
503
504int drm_version(struct drm_device *dev, void *data,
505 struct drm_file *file_priv)
506{
507 struct drm_version *version = data;
508 int err;
509
510 version->version_major = dev->driver->major;
511 version->version_minor = dev->driver->minor;
512 version->version_patchlevel = dev->driver->patchlevel;
513 err = drm_copy_field(version->name, &version->name_len,
514 dev->driver->name);
515 if (!err)
516 err = drm_copy_field(version->date, &version->date_len,
517 dev->driver->date);
518 if (!err)
519 err = drm_copy_field(version->desc, &version->desc_len,
520 dev->driver->desc);
521
522 return err;
523}
524
525
526
527
528
529
530
531
532
533
534
535
536
537int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
538{
539
540 if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)))
541 return -EACCES;
542
543
544 if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) &&
545 !file_priv->authenticated))
546 return -EACCES;
547
548
549 if (unlikely((flags & DRM_MASTER) &&
550 !drm_is_current_master(file_priv)))
551 return -EACCES;
552
553
554 if (unlikely(!(flags & DRM_RENDER_ALLOW) &&
555 drm_is_render_client(file_priv)))
556 return -EACCES;
557
558 return 0;
559}
560EXPORT_SYMBOL(drm_ioctl_permit);
561
562#define DRM_IOCTL_DEF(ioctl, _func, _flags) \
563 [DRM_IOCTL_NR(ioctl)] = { \
564 .cmd = ioctl, \
565 .func = _func, \
566 .flags = _flags, \
567 .name = #ioctl \
568 }
569
570#if IS_ENABLED(CONFIG_DRM_LEGACY)
571#define DRM_LEGACY_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(ioctl, _func, _flags)
572#else
573#define DRM_LEGACY_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(ioctl, drm_invalid_op, _flags)
574#endif
575
576
577static const struct drm_ioctl_desc drm_ioctls[] = {
578 DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_RENDER_ALLOW),
579 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
580 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
581 DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
582
583 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_legacy_getmap_ioctl, 0),
584
585 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
586 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
587 DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_RENDER_ALLOW),
588 DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0),
589 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
590
591 DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
592 DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
593 DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
594 DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_MASTER),
595
596 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_legacy_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
597 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_legacy_rmmap_ioctl, DRM_AUTH),
598
599 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_legacy_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
600 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_legacy_getsareactx, DRM_AUTH),
601
602 DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, 0),
603 DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, 0),
604
605 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_legacy_addctx, DRM_AUTH|DRM_ROOT_ONLY),
606 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_legacy_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
607 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
608 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_legacy_getctx, DRM_AUTH),
609 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_legacy_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
610 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_legacy_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
611 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_legacy_resctx, DRM_AUTH),
612
613 DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
614 DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
615
616 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_LOCK, drm_legacy_lock, DRM_AUTH),
617 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_legacy_unlock, DRM_AUTH),
618
619 DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
620
621 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_legacy_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
622 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_legacy_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
623 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_legacy_infobufs, DRM_AUTH),
624 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_legacy_mapbufs, DRM_AUTH),
625 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_legacy_freebufs, DRM_AUTH),
626 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_DMA, drm_legacy_dma_ioctl, DRM_AUTH),
627 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_legacy_irq_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
628
629#if IS_ENABLED(CONFIG_AGP)
630 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
631 DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
632 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
633 DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
634 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
635 DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
636 DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
637 DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
638#endif
639
640 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_legacy_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
641 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_legacy_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
642
643 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank_ioctl, DRM_UNLOCKED),
644
645 DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_legacy_modeset_ctl_ioctl, 0),
646
647 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
648
649 DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_RENDER_ALLOW),
650 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
651 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
652
653 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, 0),
654
655 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_RENDER_ALLOW),
656 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_RENDER_ALLOW),
657
658 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, 0),
659 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, 0),
660 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER),
661 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, 0),
662 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER),
663 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER),
664 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, 0),
665 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER),
666 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, 0),
667 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, 0),
668 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER),
669 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER),
670 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, 0),
671 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_connector_property_set_ioctl, DRM_MASTER),
672 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, 0),
673 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, 0),
674 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB2, drm_mode_getfb2_ioctl, 0),
675 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, 0),
676 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2_ioctl, 0),
677 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb_ioctl, 0),
678 DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER),
679 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER),
680 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, 0),
681 DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, 0),
682 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, 0),
683 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, 0),
684 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER),
685 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER),
686 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATOMIC, drm_mode_atomic_ioctl, DRM_MASTER),
687 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATEPROPBLOB, drm_mode_createblob_ioctl, 0),
688 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROYPROPBLOB, drm_mode_destroyblob_ioctl, 0),
689
690 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_CREATE, drm_syncobj_create_ioctl,
691 DRM_RENDER_ALLOW),
692 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_DESTROY, drm_syncobj_destroy_ioctl,
693 DRM_RENDER_ALLOW),
694 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, drm_syncobj_handle_to_fd_ioctl,
695 DRM_RENDER_ALLOW),
696 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
697 DRM_RENDER_ALLOW),
698 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TRANSFER, drm_syncobj_transfer_ioctl,
699 DRM_RENDER_ALLOW),
700 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl,
701 DRM_RENDER_ALLOW),
702 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, drm_syncobj_timeline_wait_ioctl,
703 DRM_RENDER_ALLOW),
704 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_RESET, drm_syncobj_reset_ioctl,
705 DRM_RENDER_ALLOW),
706 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
707 DRM_RENDER_ALLOW),
708 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, drm_syncobj_timeline_signal_ioctl,
709 DRM_RENDER_ALLOW),
710 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
711 DRM_RENDER_ALLOW),
712 DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, 0),
713 DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, 0),
714 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER),
715 DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER),
716 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER),
717 DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER),
718};
719
720#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
771 u32 flags)
772{
773 struct drm_file *file_priv = file->private_data;
774 struct drm_device *dev = file_priv->minor->dev;
775 int retcode;
776
777 if (drm_dev_is_unplugged(dev))
778 return -ENODEV;
779
780 retcode = drm_ioctl_permit(flags, file_priv);
781 if (unlikely(retcode))
782 return retcode;
783
784
785 if (likely(!drm_core_check_feature(dev, DRIVER_LEGACY)) ||
786 (flags & DRM_UNLOCKED))
787 retcode = func(dev, kdata, file_priv);
788 else {
789 mutex_lock(&drm_global_mutex);
790 retcode = func(dev, kdata, file_priv);
791 mutex_unlock(&drm_global_mutex);
792 }
793 return retcode;
794}
795EXPORT_SYMBOL(drm_ioctl_kernel);
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810long drm_ioctl(struct file *filp,
811 unsigned int cmd, unsigned long arg)
812{
813 struct drm_file *file_priv = filp->private_data;
814 struct drm_device *dev;
815 const struct drm_ioctl_desc *ioctl = NULL;
816 drm_ioctl_t *func;
817 unsigned int nr = DRM_IOCTL_NR(cmd);
818 int retcode = -EINVAL;
819 char stack_kdata[128];
820 char *kdata = NULL;
821 unsigned int in_size, out_size, drv_size, ksize;
822 bool is_driver_ioctl;
823
824 dev = file_priv->minor->dev;
825
826 if (drm_dev_is_unplugged(dev))
827 return -ENODEV;
828
829 is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END;
830
831 if (is_driver_ioctl) {
832
833 unsigned int index = nr - DRM_COMMAND_BASE;
834
835 if (index >= dev->driver->num_ioctls)
836 goto err_i1;
837 index = array_index_nospec(index, dev->driver->num_ioctls);
838 ioctl = &dev->driver->ioctls[index];
839 } else {
840
841 if (nr >= DRM_CORE_IOCTL_COUNT)
842 goto err_i1;
843 nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT);
844 ioctl = &drm_ioctls[nr];
845 }
846
847 drv_size = _IOC_SIZE(ioctl->cmd);
848 out_size = in_size = _IOC_SIZE(cmd);
849 if ((cmd & ioctl->cmd & IOC_IN) == 0)
850 in_size = 0;
851 if ((cmd & ioctl->cmd & IOC_OUT) == 0)
852 out_size = 0;
853 ksize = max(max(in_size, out_size), drv_size);
854
855 DRM_DEBUG("comm=\"%s\" pid=%d, dev=0x%lx, auth=%d, %s\n",
856 current->comm, task_pid_nr(current),
857 (long)old_encode_dev(file_priv->minor->kdev->devt),
858 file_priv->authenticated, ioctl->name);
859
860
861 func = ioctl->func;
862
863 if (unlikely(!func)) {
864 DRM_DEBUG("no function\n");
865 retcode = -EINVAL;
866 goto err_i1;
867 }
868
869 if (ksize <= sizeof(stack_kdata)) {
870 kdata = stack_kdata;
871 } else {
872 kdata = kmalloc(ksize, GFP_KERNEL);
873 if (!kdata) {
874 retcode = -ENOMEM;
875 goto err_i1;
876 }
877 }
878
879 if (copy_from_user(kdata, (void __user *)arg, in_size) != 0) {
880 retcode = -EFAULT;
881 goto err_i1;
882 }
883
884 if (ksize > in_size)
885 memset(kdata + in_size, 0, ksize - in_size);
886
887 retcode = drm_ioctl_kernel(filp, func, kdata, ioctl->flags);
888 if (copy_to_user((void __user *)arg, kdata, out_size) != 0)
889 retcode = -EFAULT;
890
891 err_i1:
892 if (!ioctl)
893 DRM_DEBUG("invalid ioctl: comm=\"%s\", pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
894 current->comm, task_pid_nr(current),
895 (long)old_encode_dev(file_priv->minor->kdev->devt),
896 file_priv->authenticated, cmd, nr);
897
898 if (kdata != stack_kdata)
899 kfree(kdata);
900 if (retcode)
901 DRM_DEBUG("comm=\"%s\", pid=%d, ret=%d\n", current->comm,
902 task_pid_nr(current), retcode);
903 return retcode;
904}
905EXPORT_SYMBOL(drm_ioctl);
906
907
908
909
910
911
912
913
914
915
916
917
918
919bool drm_ioctl_flags(unsigned int nr, unsigned int *flags)
920{
921 if (nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END)
922 return false;
923
924 if (nr >= DRM_CORE_IOCTL_COUNT)
925 return false;
926 nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT);
927
928 *flags = drm_ioctls[nr].flags;
929 return true;
930}
931EXPORT_SYMBOL(drm_ioctl_flags);
932