0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <linux/export.h>
0032 #include <linux/nospec.h>
0033 #include <linux/pci.h>
0034 #include <linux/uaccess.h>
0035
0036 #include <drm/drm_auth.h>
0037 #include <drm/drm_crtc.h>
0038 #include <drm/drm_drv.h>
0039 #include <drm/drm_file.h>
0040 #include <drm/drm_ioctl.h>
0041 #include <drm/drm_print.h>
0042
0043 #include "drm_crtc_internal.h"
0044 #include "drm_internal.h"
0045 #include "drm_legacy.h"
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 int drm_getunique(struct drm_device *dev, void *data,
0117 struct drm_file *file_priv)
0118 {
0119 struct drm_unique *u = data;
0120 struct drm_master *master;
0121
0122 mutex_lock(&dev->master_mutex);
0123 master = file_priv->master;
0124 if (u->unique_len >= master->unique_len) {
0125 if (copy_to_user(u->unique, master->unique, master->unique_len)) {
0126 mutex_unlock(&dev->master_mutex);
0127 return -EFAULT;
0128 }
0129 }
0130 u->unique_len = master->unique_len;
0131 mutex_unlock(&dev->master_mutex);
0132
0133 return 0;
0134 }
0135
0136 static void
0137 drm_unset_busid(struct drm_device *dev,
0138 struct drm_master *master)
0139 {
0140 kfree(master->unique);
0141 master->unique = NULL;
0142 master->unique_len = 0;
0143 }
0144
0145 static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
0146 {
0147 struct drm_master *master = file_priv->master;
0148 int ret;
0149
0150 if (master->unique != NULL)
0151 drm_unset_busid(dev, master);
0152
0153 if (dev->dev && dev_is_pci(dev->dev)) {
0154 ret = drm_pci_set_busid(dev, master);
0155 if (ret) {
0156 drm_unset_busid(dev, master);
0157 return ret;
0158 }
0159 } else {
0160 WARN_ON(!dev->unique);
0161 master->unique = kstrdup(dev->unique, GFP_KERNEL);
0162 if (master->unique)
0163 master->unique_len = strlen(dev->unique);
0164 }
0165
0166 return 0;
0167 }
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 int drm_getclient(struct drm_device *dev, void *data,
0183 struct drm_file *file_priv)
0184 {
0185 struct drm_client *client = data;
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 if (client->idx == 0) {
0199 client->auth = file_priv->authenticated;
0200 client->pid = task_pid_vnr(current);
0201 client->uid = overflowuid;
0202 client->magic = 0;
0203 client->iocs = 0;
0204
0205 return 0;
0206 } else {
0207 return -EINVAL;
0208 }
0209 }
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221 static int drm_getstats(struct drm_device *dev, void *data,
0222 struct drm_file *file_priv)
0223 {
0224 struct drm_stats *stats = data;
0225
0226
0227 memset(stats, 0, sizeof(*stats));
0228
0229 return 0;
0230 }
0231
0232
0233
0234
0235 static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
0236 {
0237 struct drm_get_cap *req = data;
0238 struct drm_crtc *crtc;
0239
0240 req->value = 0;
0241
0242
0243 switch (req->capability) {
0244 case DRM_CAP_TIMESTAMP_MONOTONIC:
0245 req->value = 1;
0246 return 0;
0247 case DRM_CAP_PRIME:
0248 req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0;
0249 req->value |= dev->driver->prime_handle_to_fd ? DRM_PRIME_CAP_EXPORT : 0;
0250 return 0;
0251 case DRM_CAP_SYNCOBJ:
0252 req->value = drm_core_check_feature(dev, DRIVER_SYNCOBJ);
0253 return 0;
0254 case DRM_CAP_SYNCOBJ_TIMELINE:
0255 req->value = drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE);
0256 return 0;
0257 }
0258
0259
0260 if (!drm_core_check_feature(dev, DRIVER_MODESET))
0261 return -EOPNOTSUPP;
0262
0263 switch (req->capability) {
0264 case DRM_CAP_DUMB_BUFFER:
0265 if (dev->driver->dumb_create)
0266 req->value = 1;
0267 break;
0268 case DRM_CAP_VBLANK_HIGH_CRTC:
0269 req->value = 1;
0270 break;
0271 case DRM_CAP_DUMB_PREFERRED_DEPTH:
0272 req->value = dev->mode_config.preferred_depth;
0273 break;
0274 case DRM_CAP_DUMB_PREFER_SHADOW:
0275 req->value = dev->mode_config.prefer_shadow;
0276 break;
0277 case DRM_CAP_ASYNC_PAGE_FLIP:
0278 req->value = dev->mode_config.async_page_flip;
0279 break;
0280 case DRM_CAP_PAGE_FLIP_TARGET:
0281 req->value = 1;
0282 drm_for_each_crtc(crtc, dev) {
0283 if (!crtc->funcs->page_flip_target)
0284 req->value = 0;
0285 }
0286 break;
0287 case DRM_CAP_CURSOR_WIDTH:
0288 if (dev->mode_config.cursor_width)
0289 req->value = dev->mode_config.cursor_width;
0290 else
0291 req->value = 64;
0292 break;
0293 case DRM_CAP_CURSOR_HEIGHT:
0294 if (dev->mode_config.cursor_height)
0295 req->value = dev->mode_config.cursor_height;
0296 else
0297 req->value = 64;
0298 break;
0299 case DRM_CAP_ADDFB2_MODIFIERS:
0300 req->value = !dev->mode_config.fb_modifiers_not_supported;
0301 break;
0302 case DRM_CAP_CRTC_IN_VBLANK_EVENT:
0303 req->value = 1;
0304 break;
0305 default:
0306 return -EINVAL;
0307 }
0308 return 0;
0309 }
0310
0311
0312
0313
0314 static int
0315 drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
0316 {
0317 struct drm_set_client_cap *req = data;
0318
0319
0320
0321
0322 if (!drm_core_check_feature(dev, DRIVER_MODESET))
0323 return -EOPNOTSUPP;
0324
0325 switch (req->capability) {
0326 case DRM_CLIENT_CAP_STEREO_3D:
0327 if (req->value > 1)
0328 return -EINVAL;
0329 file_priv->stereo_allowed = req->value;
0330 break;
0331 case DRM_CLIENT_CAP_UNIVERSAL_PLANES:
0332 if (req->value > 1)
0333 return -EINVAL;
0334 file_priv->universal_planes = req->value;
0335 break;
0336 case DRM_CLIENT_CAP_ATOMIC:
0337 if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
0338 return -EOPNOTSUPP;
0339
0340 if (current->comm[0] == 'X' && req->value == 1) {
0341 pr_info("broken atomic modeset userspace detected, disabling atomic\n");
0342 return -EOPNOTSUPP;
0343 }
0344 if (req->value > 2)
0345 return -EINVAL;
0346 file_priv->atomic = req->value;
0347 file_priv->universal_planes = req->value;
0348
0349
0350
0351 file_priv->aspect_ratio_allowed = req->value;
0352 break;
0353 case DRM_CLIENT_CAP_ASPECT_RATIO:
0354 if (req->value > 1)
0355 return -EINVAL;
0356 file_priv->aspect_ratio_allowed = req->value;
0357 break;
0358 case DRM_CLIENT_CAP_WRITEBACK_CONNECTORS:
0359 if (!file_priv->atomic)
0360 return -EINVAL;
0361 if (req->value > 1)
0362 return -EINVAL;
0363 file_priv->writeback_connectors = req->value;
0364 break;
0365 default:
0366 return -EINVAL;
0367 }
0368
0369 return 0;
0370 }
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383 static int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv)
0384 {
0385 struct drm_set_version *sv = data;
0386 int if_version, retcode = 0;
0387
0388 mutex_lock(&dev->master_mutex);
0389 if (sv->drm_di_major != -1) {
0390 if (sv->drm_di_major != DRM_IF_MAJOR ||
0391 sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) {
0392 retcode = -EINVAL;
0393 goto done;
0394 }
0395 if_version = DRM_IF_VERSION(sv->drm_di_major,
0396 sv->drm_di_minor);
0397 dev->if_version = max(if_version, dev->if_version);
0398 if (sv->drm_di_minor >= 1) {
0399
0400
0401
0402
0403 retcode = drm_set_busid(dev, file_priv);
0404 if (retcode)
0405 goto done;
0406 }
0407 }
0408
0409 if (sv->drm_dd_major != -1) {
0410 if (sv->drm_dd_major != dev->driver->major ||
0411 sv->drm_dd_minor < 0 || sv->drm_dd_minor >
0412 dev->driver->minor) {
0413 retcode = -EINVAL;
0414 goto done;
0415 }
0416 }
0417
0418 done:
0419 sv->drm_di_major = DRM_IF_MAJOR;
0420 sv->drm_di_minor = DRM_IF_MINOR;
0421 sv->drm_dd_major = dev->driver->major;
0422 sv->drm_dd_minor = dev->driver->minor;
0423 mutex_unlock(&dev->master_mutex);
0424
0425 return retcode;
0426 }
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440 int drm_noop(struct drm_device *dev, void *data,
0441 struct drm_file *file_priv)
0442 {
0443 DRM_DEBUG("\n");
0444 return 0;
0445 }
0446 EXPORT_SYMBOL(drm_noop);
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463 int drm_invalid_op(struct drm_device *dev, void *data,
0464 struct drm_file *file_priv)
0465 {
0466 return -EINVAL;
0467 }
0468 EXPORT_SYMBOL(drm_invalid_op);
0469
0470
0471
0472
0473 static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value)
0474 {
0475 int len;
0476
0477
0478 len = strlen(value);
0479 if (len > *buf_len)
0480 len = *buf_len;
0481
0482
0483
0484 *buf_len = strlen(value);
0485
0486
0487 if (len && buf)
0488 if (copy_to_user(buf, value, len))
0489 return -EFAULT;
0490 return 0;
0491 }
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504 int drm_version(struct drm_device *dev, void *data,
0505 struct drm_file *file_priv)
0506 {
0507 struct drm_version *version = data;
0508 int err;
0509
0510 version->version_major = dev->driver->major;
0511 version->version_minor = dev->driver->minor;
0512 version->version_patchlevel = dev->driver->patchlevel;
0513 err = drm_copy_field(version->name, &version->name_len,
0514 dev->driver->name);
0515 if (!err)
0516 err = drm_copy_field(version->date, &version->date_len,
0517 dev->driver->date);
0518 if (!err)
0519 err = drm_copy_field(version->desc, &version->desc_len,
0520 dev->driver->desc);
0521
0522 return err;
0523 }
0524
0525 static int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
0526 {
0527
0528 if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)))
0529 return -EACCES;
0530
0531
0532 if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) &&
0533 !file_priv->authenticated))
0534 return -EACCES;
0535
0536
0537 if (unlikely((flags & DRM_MASTER) &&
0538 !drm_is_current_master(file_priv)))
0539 return -EACCES;
0540
0541
0542 if (unlikely(!(flags & DRM_RENDER_ALLOW) &&
0543 drm_is_render_client(file_priv)))
0544 return -EACCES;
0545
0546 return 0;
0547 }
0548
0549 #define DRM_IOCTL_DEF(ioctl, _func, _flags) \
0550 [DRM_IOCTL_NR(ioctl)] = { \
0551 .cmd = ioctl, \
0552 .func = _func, \
0553 .flags = _flags, \
0554 .name = #ioctl \
0555 }
0556
0557 #if IS_ENABLED(CONFIG_DRM_LEGACY)
0558 #define DRM_LEGACY_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(ioctl, _func, _flags)
0559 #else
0560 #define DRM_LEGACY_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(ioctl, drm_invalid_op, _flags)
0561 #endif
0562
0563
0564 static const struct drm_ioctl_desc drm_ioctls[] = {
0565 DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_RENDER_ALLOW),
0566 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
0567 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
0568 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_legacy_irq_by_busid,
0569 DRM_MASTER|DRM_ROOT_ONLY),
0570
0571 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_legacy_getmap_ioctl, 0),
0572
0573 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
0574 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
0575 DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_RENDER_ALLOW),
0576 DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0),
0577 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
0578
0579 DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0580 DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0581 DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0582 DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_MASTER),
0583
0584 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_legacy_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0585 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_legacy_rmmap_ioctl, DRM_AUTH),
0586
0587 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_legacy_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0588 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_legacy_getsareactx, DRM_AUTH),
0589
0590 DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, 0),
0591 DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, 0),
0592
0593 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_legacy_addctx, DRM_AUTH|DRM_ROOT_ONLY),
0594 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_legacy_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0595 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0596 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_legacy_getctx, DRM_AUTH),
0597 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_legacy_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0598 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_legacy_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0599 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_legacy_resctx, DRM_AUTH),
0600
0601 DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0602 DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0603
0604 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_LOCK, drm_legacy_lock, DRM_AUTH),
0605 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_legacy_unlock, DRM_AUTH),
0606
0607 DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
0608
0609 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_legacy_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0610 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_legacy_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0611 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_legacy_infobufs, DRM_AUTH),
0612 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_legacy_mapbufs, DRM_AUTH),
0613 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_legacy_freebufs, DRM_AUTH),
0614 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_DMA, drm_legacy_dma_ioctl, DRM_AUTH),
0615 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_legacy_irq_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0616
0617 #if IS_ENABLED(CONFIG_AGP)
0618 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_legacy_agp_acquire_ioctl,
0619 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0620 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_legacy_agp_release_ioctl,
0621 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0622 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_legacy_agp_enable_ioctl,
0623 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0624 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_legacy_agp_info_ioctl, DRM_AUTH),
0625 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_legacy_agp_alloc_ioctl,
0626 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0627 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_legacy_agp_free_ioctl,
0628 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0629 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_legacy_agp_bind_ioctl,
0630 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0631 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_legacy_agp_unbind_ioctl,
0632 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0633 #endif
0634
0635 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_legacy_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0636 DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_legacy_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0637
0638 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank_ioctl, DRM_UNLOCKED),
0639
0640 DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_legacy_modeset_ctl_ioctl, 0),
0641
0642 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
0643
0644 DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_RENDER_ALLOW),
0645 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
0646 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
0647
0648 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, 0),
0649
0650 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_RENDER_ALLOW),
0651 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_RENDER_ALLOW),
0652
0653 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, 0),
0654 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, 0),
0655 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER),
0656 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, 0),
0657 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER),
0658 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER),
0659 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, 0),
0660 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER),
0661 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, 0),
0662 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, 0),
0663 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER),
0664 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER),
0665 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, 0),
0666 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_connector_property_set_ioctl, DRM_MASTER),
0667 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, 0),
0668 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, 0),
0669 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB2, drm_mode_getfb2_ioctl, 0),
0670 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, 0),
0671 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2_ioctl, 0),
0672 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb_ioctl, 0),
0673 DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER),
0674 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER),
0675 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, 0),
0676 DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, 0),
0677 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, 0),
0678 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, 0),
0679 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER),
0680 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER),
0681 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATOMIC, drm_mode_atomic_ioctl, DRM_MASTER),
0682 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATEPROPBLOB, drm_mode_createblob_ioctl, 0),
0683 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROYPROPBLOB, drm_mode_destroyblob_ioctl, 0),
0684
0685 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_CREATE, drm_syncobj_create_ioctl,
0686 DRM_RENDER_ALLOW),
0687 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_DESTROY, drm_syncobj_destroy_ioctl,
0688 DRM_RENDER_ALLOW),
0689 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, drm_syncobj_handle_to_fd_ioctl,
0690 DRM_RENDER_ALLOW),
0691 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
0692 DRM_RENDER_ALLOW),
0693 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TRANSFER, drm_syncobj_transfer_ioctl,
0694 DRM_RENDER_ALLOW),
0695 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl,
0696 DRM_RENDER_ALLOW),
0697 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, drm_syncobj_timeline_wait_ioctl,
0698 DRM_RENDER_ALLOW),
0699 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_RESET, drm_syncobj_reset_ioctl,
0700 DRM_RENDER_ALLOW),
0701 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
0702 DRM_RENDER_ALLOW),
0703 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, drm_syncobj_timeline_signal_ioctl,
0704 DRM_RENDER_ALLOW),
0705 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
0706 DRM_RENDER_ALLOW),
0707 DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, 0),
0708 DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, 0),
0709 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER),
0710 DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER),
0711 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER),
0712 DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER),
0713 };
0714
0715 #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE(drm_ioctls)
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765 long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
0766 u32 flags)
0767 {
0768 struct drm_file *file_priv = file->private_data;
0769 struct drm_device *dev = file_priv->minor->dev;
0770 int retcode;
0771
0772 if (drm_dev_is_unplugged(dev))
0773 return -ENODEV;
0774
0775 retcode = drm_ioctl_permit(flags, file_priv);
0776 if (unlikely(retcode))
0777 return retcode;
0778
0779
0780 if (likely(!drm_core_check_feature(dev, DRIVER_LEGACY)) ||
0781 (flags & DRM_UNLOCKED))
0782 retcode = func(dev, kdata, file_priv);
0783 else {
0784 mutex_lock(&drm_global_mutex);
0785 retcode = func(dev, kdata, file_priv);
0786 mutex_unlock(&drm_global_mutex);
0787 }
0788 return retcode;
0789 }
0790 EXPORT_SYMBOL(drm_ioctl_kernel);
0791
0792
0793
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805 long drm_ioctl(struct file *filp,
0806 unsigned int cmd, unsigned long arg)
0807 {
0808 struct drm_file *file_priv = filp->private_data;
0809 struct drm_device *dev;
0810 const struct drm_ioctl_desc *ioctl = NULL;
0811 drm_ioctl_t *func;
0812 unsigned int nr = DRM_IOCTL_NR(cmd);
0813 int retcode = -EINVAL;
0814 char stack_kdata[128];
0815 char *kdata = NULL;
0816 unsigned int in_size, out_size, drv_size, ksize;
0817 bool is_driver_ioctl;
0818
0819 dev = file_priv->minor->dev;
0820
0821 if (drm_dev_is_unplugged(dev))
0822 return -ENODEV;
0823
0824 if (DRM_IOCTL_TYPE(cmd) != DRM_IOCTL_BASE)
0825 return -ENOTTY;
0826
0827 is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END;
0828
0829 if (is_driver_ioctl) {
0830
0831 unsigned int index = nr - DRM_COMMAND_BASE;
0832
0833 if (index >= dev->driver->num_ioctls)
0834 goto err_i1;
0835 index = array_index_nospec(index, dev->driver->num_ioctls);
0836 ioctl = &dev->driver->ioctls[index];
0837 } else {
0838
0839 if (nr >= DRM_CORE_IOCTL_COUNT)
0840 goto err_i1;
0841 nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT);
0842 ioctl = &drm_ioctls[nr];
0843 }
0844
0845 drv_size = _IOC_SIZE(ioctl->cmd);
0846 out_size = in_size = _IOC_SIZE(cmd);
0847 if ((cmd & ioctl->cmd & IOC_IN) == 0)
0848 in_size = 0;
0849 if ((cmd & ioctl->cmd & IOC_OUT) == 0)
0850 out_size = 0;
0851 ksize = max(max(in_size, out_size), drv_size);
0852
0853 DRM_DEBUG("comm=\"%s\" pid=%d, dev=0x%lx, auth=%d, %s\n",
0854 current->comm, task_pid_nr(current),
0855 (long)old_encode_dev(file_priv->minor->kdev->devt),
0856 file_priv->authenticated, ioctl->name);
0857
0858
0859 func = ioctl->func;
0860
0861 if (unlikely(!func)) {
0862 DRM_DEBUG("no function\n");
0863 retcode = -EINVAL;
0864 goto err_i1;
0865 }
0866
0867 if (ksize <= sizeof(stack_kdata)) {
0868 kdata = stack_kdata;
0869 } else {
0870 kdata = kmalloc(ksize, GFP_KERNEL);
0871 if (!kdata) {
0872 retcode = -ENOMEM;
0873 goto err_i1;
0874 }
0875 }
0876
0877 if (copy_from_user(kdata, (void __user *)arg, in_size) != 0) {
0878 retcode = -EFAULT;
0879 goto err_i1;
0880 }
0881
0882 if (ksize > in_size)
0883 memset(kdata + in_size, 0, ksize - in_size);
0884
0885 retcode = drm_ioctl_kernel(filp, func, kdata, ioctl->flags);
0886 if (copy_to_user((void __user *)arg, kdata, out_size) != 0)
0887 retcode = -EFAULT;
0888
0889 err_i1:
0890 if (!ioctl)
0891 DRM_DEBUG("invalid ioctl: comm=\"%s\", pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
0892 current->comm, task_pid_nr(current),
0893 (long)old_encode_dev(file_priv->minor->kdev->devt),
0894 file_priv->authenticated, cmd, nr);
0895
0896 if (kdata != stack_kdata)
0897 kfree(kdata);
0898 if (retcode)
0899 DRM_DEBUG("comm=\"%s\", pid=%d, ret=%d\n", current->comm,
0900 task_pid_nr(current), retcode);
0901 return retcode;
0902 }
0903 EXPORT_SYMBOL(drm_ioctl);
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917 bool drm_ioctl_flags(unsigned int nr, unsigned int *flags)
0918 {
0919 if (nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END)
0920 return false;
0921
0922 if (nr >= DRM_CORE_IOCTL_COUNT)
0923 return false;
0924 nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT);
0925
0926 *flags = drm_ioctls[nr].flags;
0927 return true;
0928 }
0929 EXPORT_SYMBOL(drm_ioctl_flags);