1 /* 2 * \file drm_ioc32.c 3 * 4 * 32-bit ioctl compatibility routines for the DRM. 5 * 6 * \author Paul Mackerras <paulus@samba.org> 7 * 8 * Copyright (C) Paul Mackerras 2005. 9 * All Rights Reserved. 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining a 12 * copy of this software and associated documentation files (the "Software"), 13 * to deal in the Software without restriction, including without limitation 14 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15 * and/or sell copies of the Software, and to permit persons to whom the 16 * Software is furnished to do so, subject to the following conditions: 17 * 18 * The above copyright notice and this permission notice (including the next 19 * paragraph) shall be included in all copies or substantial portions of the 20 * Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 25 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 28 * IN THE SOFTWARE. 29 */ 30 #include <linux/compat.h> 31 #include <linux/ratelimit.h> 32 #include <linux/export.h> 33 34 #include <drm/drmP.h> 35 #include "drm_legacy.h" 36 #include "drm_internal.h" 37 #include "drm_crtc_internal.h" 38 39 #define DRM_IOCTL_VERSION32 DRM_IOWR(0x00, drm_version32_t) 40 #define DRM_IOCTL_GET_UNIQUE32 DRM_IOWR(0x01, drm_unique32_t) 41 #define DRM_IOCTL_GET_MAP32 DRM_IOWR(0x04, drm_map32_t) 42 #define DRM_IOCTL_GET_CLIENT32 DRM_IOWR(0x05, drm_client32_t) 43 #define DRM_IOCTL_GET_STATS32 DRM_IOR( 0x06, drm_stats32_t) 44 45 #define DRM_IOCTL_SET_UNIQUE32 DRM_IOW( 0x10, drm_unique32_t) 46 #define DRM_IOCTL_ADD_MAP32 DRM_IOWR(0x15, drm_map32_t) 47 #define DRM_IOCTL_ADD_BUFS32 DRM_IOWR(0x16, drm_buf_desc32_t) 48 #define DRM_IOCTL_MARK_BUFS32 DRM_IOW( 0x17, drm_buf_desc32_t) 49 #define DRM_IOCTL_INFO_BUFS32 DRM_IOWR(0x18, drm_buf_info32_t) 50 #define DRM_IOCTL_MAP_BUFS32 DRM_IOWR(0x19, drm_buf_map32_t) 51 #define DRM_IOCTL_FREE_BUFS32 DRM_IOW( 0x1a, drm_buf_free32_t) 52 53 #define DRM_IOCTL_RM_MAP32 DRM_IOW( 0x1b, drm_map32_t) 54 55 #define DRM_IOCTL_SET_SAREA_CTX32 DRM_IOW( 0x1c, drm_ctx_priv_map32_t) 56 #define DRM_IOCTL_GET_SAREA_CTX32 DRM_IOWR(0x1d, drm_ctx_priv_map32_t) 57 58 #define DRM_IOCTL_RES_CTX32 DRM_IOWR(0x26, drm_ctx_res32_t) 59 #define DRM_IOCTL_DMA32 DRM_IOWR(0x29, drm_dma32_t) 60 61 #define DRM_IOCTL_AGP_ENABLE32 DRM_IOW( 0x32, drm_agp_mode32_t) 62 #define DRM_IOCTL_AGP_INFO32 DRM_IOR( 0x33, drm_agp_info32_t) 63 #define DRM_IOCTL_AGP_ALLOC32 DRM_IOWR(0x34, drm_agp_buffer32_t) 64 #define DRM_IOCTL_AGP_FREE32 DRM_IOW( 0x35, drm_agp_buffer32_t) 65 #define DRM_IOCTL_AGP_BIND32 DRM_IOW( 0x36, drm_agp_binding32_t) 66 #define DRM_IOCTL_AGP_UNBIND32 DRM_IOW( 0x37, drm_agp_binding32_t) 67 68 #define DRM_IOCTL_SG_ALLOC32 DRM_IOW( 0x38, drm_scatter_gather32_t) 69 #define DRM_IOCTL_SG_FREE32 DRM_IOW( 0x39, drm_scatter_gather32_t) 70 71 #define DRM_IOCTL_UPDATE_DRAW32 DRM_IOW( 0x3f, drm_update_draw32_t) 72 73 #define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t) 74 75 #define DRM_IOCTL_MODE_ADDFB232 DRM_IOWR(0xb8, drm_mode_fb_cmd232_t) 76 77 typedef struct drm_version_32 { 78 int version_major; /* Major version */ 79 int version_minor; /* Minor version */ 80 int version_patchlevel; /* Patch level */ 81 u32 name_len; /* Length of name buffer */ 82 u32 name; /* Name of driver */ 83 u32 date_len; /* Length of date buffer */ 84 u32 date; /* User-space buffer to hold date */ 85 u32 desc_len; /* Length of desc buffer */ 86 u32 desc; /* User-space buffer to hold desc */ 87 } drm_version32_t; 88 89 static int compat_drm_version(struct file *file, unsigned int cmd, 90 unsigned long arg) 91 { 92 drm_version32_t v32; 93 struct drm_version v; 94 int err; 95 96 if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) 97 return -EFAULT; 98 99 v = (struct drm_version) { 100 .name_len = v32.name_len, 101 .name = compat_ptr(v32.name), 102 .date_len = v32.date_len, 103 .date = compat_ptr(v32.date), 104 .desc_len = v32.desc_len, 105 .desc = compat_ptr(v32.desc), 106 }; 107 err = drm_ioctl_kernel(file, drm_version, &v, 108 DRM_UNLOCKED|DRM_RENDER_ALLOW); 109 if (err) 110 return err; 111 112 v32.version_major = v.version_major; 113 v32.version_minor = v.version_minor; 114 v32.version_patchlevel = v.version_patchlevel; 115 v32.name_len = v.name_len; 116 v32.date_len = v.date_len; 117 v32.desc_len = v.desc_len; 118 if (copy_to_user((void __user *)arg, &v32, sizeof(v32))) 119 return -EFAULT; 120 return 0; 121 } 122 123 typedef struct drm_unique32 { 124 u32 unique_len; /* Length of unique */ 125 u32 unique; /* Unique name for driver instantiation */ 126 } drm_unique32_t; 127 128 static int compat_drm_getunique(struct file *file, unsigned int cmd, 129 unsigned long arg) 130 { 131 drm_unique32_t uq32; 132 struct drm_unique uq; 133 int err; 134 135 if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) 136 return -EFAULT; 137 uq = (struct drm_unique){ 138 .unique_len = uq32.unique_len, 139 .unique = compat_ptr(uq32.unique), 140 }; 141 142 err = drm_ioctl_kernel(file, drm_getunique, &uq, DRM_UNLOCKED); 143 if (err) 144 return err; 145 146 uq32.unique_len = uq.unique_len; 147 if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32))) 148 return -EFAULT; 149 return 0; 150 } 151 152 static int compat_drm_setunique(struct file *file, unsigned int cmd, 153 unsigned long arg) 154 { 155 /* it's dead */ 156 return -EINVAL; 157 } 158 159 #if IS_ENABLED(CONFIG_DRM_LEGACY) 160 typedef struct drm_map32 { 161 u32 offset; /* Requested physical address (0 for SAREA) */ 162 u32 size; /* Requested physical size (bytes) */ 163 enum drm_map_type type; /* Type of memory to map */ 164 enum drm_map_flags flags; /* Flags */ 165 u32 handle; /* User-space: "Handle" to pass to mmap() */ 166 int mtrr; /* MTRR slot used */ 167 } drm_map32_t; 168 169 static int compat_drm_getmap(struct file *file, unsigned int cmd, 170 unsigned long arg) 171 { 172 drm_map32_t __user *argp = (void __user *)arg; 173 drm_map32_t m32; 174 struct drm_map map; 175 int err; 176 177 if (copy_from_user(&m32, argp, sizeof(m32))) 178 return -EFAULT; 179 180 map.offset = m32.offset; 181 err = drm_ioctl_kernel(file, drm_legacy_getmap_ioctl, &map, DRM_UNLOCKED); 182 if (err) 183 return err; 184 185 m32.offset = map.offset; 186 m32.size = map.size; 187 m32.type = map.type; 188 m32.flags = map.flags; 189 m32.handle = ptr_to_compat((void __user *)map.handle); 190 m32.mtrr = map.mtrr; 191 if (copy_to_user(argp, &m32, sizeof(m32))) 192 return -EFAULT; 193 return 0; 194 195 } 196 197 static int compat_drm_addmap(struct file *file, unsigned int cmd, 198 unsigned long arg) 199 { 200 drm_map32_t __user *argp = (void __user *)arg; 201 drm_map32_t m32; 202 struct drm_map map; 203 int err; 204 205 if (copy_from_user(&m32, argp, sizeof(m32))) 206 return -EFAULT; 207 208 map.offset = m32.offset; 209 map.size = m32.size; 210 map.type = m32.type; 211 map.flags = m32.flags; 212 213 err = drm_ioctl_kernel(file, drm_legacy_addmap_ioctl, &map, 214 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 215 if (err) 216 return err; 217 218 m32.offset = map.offset; 219 m32.mtrr = map.mtrr; 220 m32.handle = ptr_to_compat((void __user *)map.handle); 221 if (map.handle != compat_ptr(m32.handle)) 222 pr_err_ratelimited("compat_drm_addmap truncated handle %p for type %d offset %x\n", 223 map.handle, m32.type, m32.offset); 224 225 if (copy_to_user(argp, &m32, sizeof(m32))) 226 return -EFAULT; 227 228 return 0; 229 } 230 231 static int compat_drm_rmmap(struct file *file, unsigned int cmd, 232 unsigned long arg) 233 { 234 drm_map32_t __user *argp = (void __user *)arg; 235 struct drm_map map; 236 u32 handle; 237 238 if (get_user(handle, &argp->handle)) 239 return -EFAULT; 240 map.handle = compat_ptr(handle); 241 return drm_ioctl_kernel(file, drm_legacy_rmmap_ioctl, &map, DRM_AUTH); 242 } 243 #endif 244 245 typedef struct drm_client32 { 246 int idx; /* Which client desired? */ 247 int auth; /* Is client authenticated? */ 248 u32 pid; /* Process ID */ 249 u32 uid; /* User ID */ 250 u32 magic; /* Magic */ 251 u32 iocs; /* Ioctl count */ 252 } drm_client32_t; 253 254 static int compat_drm_getclient(struct file *file, unsigned int cmd, 255 unsigned long arg) 256 { 257 drm_client32_t c32; 258 drm_client32_t __user *argp = (void __user *)arg; 259 struct drm_client client; 260 int err; 261 262 if (copy_from_user(&c32, argp, sizeof(c32))) 263 return -EFAULT; 264 265 client.idx = c32.idx; 266 267 err = drm_ioctl_kernel(file, drm_getclient, &client, DRM_UNLOCKED); 268 if (err) 269 return err; 270 271 c32.idx = client.idx; 272 c32.auth = client.auth; 273 c32.pid = client.pid; 274 c32.uid = client.uid; 275 c32.magic = client.magic; 276 c32.iocs = client.iocs; 277 278 if (copy_to_user(argp, &c32, sizeof(c32))) 279 return -EFAULT; 280 return 0; 281 } 282 283 typedef struct drm_stats32 { 284 u32 count; 285 struct { 286 u32 value; 287 enum drm_stat_type type; 288 } data[15]; 289 } drm_stats32_t; 290 291 static int compat_drm_getstats(struct file *file, unsigned int cmd, 292 unsigned long arg) 293 { 294 drm_stats32_t __user *argp = (void __user *)arg; 295 int err; 296 297 err = drm_ioctl_kernel(file, drm_noop, NULL, DRM_UNLOCKED); 298 if (err) 299 return err; 300 301 if (clear_user(argp, sizeof(drm_stats32_t))) 302 return -EFAULT; 303 return 0; 304 } 305 306 #if IS_ENABLED(CONFIG_DRM_LEGACY) 307 typedef struct drm_buf_desc32 { 308 int count; /* Number of buffers of this size */ 309 int size; /* Size in bytes */ 310 int low_mark; /* Low water mark */ 311 int high_mark; /* High water mark */ 312 int flags; 313 u32 agp_start; /* Start address in the AGP aperture */ 314 } drm_buf_desc32_t; 315 316 static int compat_drm_addbufs(struct file *file, unsigned int cmd, 317 unsigned long arg) 318 { 319 drm_buf_desc32_t __user *argp = (void __user *)arg; 320 drm_buf_desc32_t desc32; 321 struct drm_buf_desc desc; 322 int err; 323 324 if (copy_from_user(&desc32, argp, sizeof(drm_buf_desc32_t))) 325 return -EFAULT; 326 327 desc = (struct drm_buf_desc){ 328 desc32.count, desc32.size, desc32.low_mark, desc32.high_mark, 329 desc32.flags, desc32.agp_start 330 }; 331 332 err = drm_ioctl_kernel(file, drm_legacy_addbufs, &desc, 333 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 334 if (err) 335 return err; 336 337 desc32 = (drm_buf_desc32_t){ 338 desc.count, desc.size, desc.low_mark, desc.high_mark, 339 desc.flags, desc.agp_start 340 }; 341 if (copy_to_user(argp, &desc32, sizeof(drm_buf_desc32_t))) 342 return -EFAULT; 343 344 return 0; 345 } 346 347 static int compat_drm_markbufs(struct file *file, unsigned int cmd, 348 unsigned long arg) 349 { 350 drm_buf_desc32_t b32; 351 drm_buf_desc32_t __user *argp = (void __user *)arg; 352 struct drm_buf_desc buf; 353 354 if (copy_from_user(&b32, argp, sizeof(b32))) 355 return -EFAULT; 356 357 buf.size = b32.size; 358 buf.low_mark = b32.low_mark; 359 buf.high_mark = b32.high_mark; 360 361 return drm_ioctl_kernel(file, drm_legacy_markbufs, &buf, 362 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 363 } 364 365 typedef struct drm_buf_info32 { 366 int count; /**< Entries in list */ 367 u32 list; 368 } drm_buf_info32_t; 369 370 static int copy_one_buf32(void *data, int count, struct drm_buf_entry *from) 371 { 372 drm_buf_info32_t *request = data; 373 drm_buf_desc32_t __user *to = compat_ptr(request->list); 374 drm_buf_desc32_t v = {.count = from->buf_count, 375 .size = from->buf_size, 376 .low_mark = from->low_mark, 377 .high_mark = from->high_mark}; 378 return copy_to_user(to + count, &v, offsetof(drm_buf_desc32_t, flags)); 379 } 380 381 static int drm_legacy_infobufs32(struct drm_device *dev, void *data, 382 struct drm_file *file_priv) 383 { 384 drm_buf_info32_t *request = data; 385 return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf32); 386 } 387 388 static int compat_drm_infobufs(struct file *file, unsigned int cmd, 389 unsigned long arg) 390 { 391 drm_buf_info32_t req32; 392 drm_buf_info32_t __user *argp = (void __user *)arg; 393 int err; 394 395 if (copy_from_user(&req32, argp, sizeof(req32))) 396 return -EFAULT; 397 398 if (req32.count < 0) 399 req32.count = 0; 400 401 err = drm_ioctl_kernel(file, drm_legacy_infobufs32, &req32, DRM_AUTH); 402 if (err) 403 return err; 404 405 if (put_user(req32.count, &argp->count)) 406 return -EFAULT; 407 408 return 0; 409 } 410 411 typedef struct drm_buf_pub32 { 412 int idx; /**< Index into the master buffer list */ 413 int total; /**< Buffer size */ 414 int used; /**< Amount of buffer in use (for DMA) */ 415 u32 address; /**< Address of buffer */ 416 } drm_buf_pub32_t; 417 418 typedef struct drm_buf_map32 { 419 int count; /**< Length of the buffer list */ 420 u32 virtual; /**< Mmap'd area in user-virtual */ 421 u32 list; /**< Buffer information */ 422 } drm_buf_map32_t; 423 424 static int map_one_buf32(void *data, int idx, unsigned long virtual, 425 struct drm_buf *buf) 426 { 427 drm_buf_map32_t *request = data; 428 drm_buf_pub32_t __user *to = compat_ptr(request->list) + idx; 429 drm_buf_pub32_t v; 430 431 v.idx = buf->idx; 432 v.total = buf->total; 433 v.used = 0; 434 v.address = virtual + buf->offset; 435 if (copy_to_user(to, &v, sizeof(v))) 436 return -EFAULT; 437 return 0; 438 } 439 440 static int drm_legacy_mapbufs32(struct drm_device *dev, void *data, 441 struct drm_file *file_priv) 442 { 443 drm_buf_map32_t *request = data; 444 void __user *v; 445 int err = __drm_legacy_mapbufs(dev, data, &request->count, 446 &v, map_one_buf32, 447 file_priv); 448 request->virtual = ptr_to_compat(v); 449 return err; 450 } 451 452 static int compat_drm_mapbufs(struct file *file, unsigned int cmd, 453 unsigned long arg) 454 { 455 drm_buf_map32_t __user *argp = (void __user *)arg; 456 drm_buf_map32_t req32; 457 int err; 458 459 if (copy_from_user(&req32, argp, sizeof(req32))) 460 return -EFAULT; 461 if (req32.count < 0) 462 return -EINVAL; 463 464 err = drm_ioctl_kernel(file, drm_legacy_mapbufs32, &req32, DRM_AUTH); 465 if (err) 466 return err; 467 468 if (put_user(req32.count, &argp->count) 469 || put_user(req32.virtual, &argp->virtual)) 470 return -EFAULT; 471 472 return 0; 473 } 474 475 typedef struct drm_buf_free32 { 476 int count; 477 u32 list; 478 } drm_buf_free32_t; 479 480 static int compat_drm_freebufs(struct file *file, unsigned int cmd, 481 unsigned long arg) 482 { 483 drm_buf_free32_t req32; 484 struct drm_buf_free request; 485 drm_buf_free32_t __user *argp = (void __user *)arg; 486 487 if (copy_from_user(&req32, argp, sizeof(req32))) 488 return -EFAULT; 489 490 request.count = req32.count; 491 request.list = compat_ptr(req32.list); 492 return drm_ioctl_kernel(file, drm_legacy_freebufs, &request, DRM_AUTH); 493 } 494 495 typedef struct drm_ctx_priv_map32 { 496 unsigned int ctx_id; /**< Context requesting private mapping */ 497 u32 handle; /**< Handle of map */ 498 } drm_ctx_priv_map32_t; 499 500 static int compat_drm_setsareactx(struct file *file, unsigned int cmd, 501 unsigned long arg) 502 { 503 drm_ctx_priv_map32_t req32; 504 struct drm_ctx_priv_map request; 505 drm_ctx_priv_map32_t __user *argp = (void __user *)arg; 506 507 if (copy_from_user(&req32, argp, sizeof(req32))) 508 return -EFAULT; 509 510 request.ctx_id = req32.ctx_id; 511 request.handle = compat_ptr(req32.handle); 512 return drm_ioctl_kernel(file, drm_legacy_setsareactx, &request, 513 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 514 } 515 516 static int compat_drm_getsareactx(struct file *file, unsigned int cmd, 517 unsigned long arg) 518 { 519 struct drm_ctx_priv_map req; 520 drm_ctx_priv_map32_t req32; 521 drm_ctx_priv_map32_t __user *argp = (void __user *)arg; 522 int err; 523 524 if (copy_from_user(&req32, argp, sizeof(req32))) 525 return -EFAULT; 526 527 req.ctx_id = req32.ctx_id; 528 err = drm_ioctl_kernel(file, drm_legacy_getsareactx, &req, DRM_AUTH); 529 if (err) 530 return err; 531 532 req32.handle = ptr_to_compat((void __user *)req.handle); 533 if (copy_to_user(argp, &req32, sizeof(req32))) 534 return -EFAULT; 535 536 return 0; 537 } 538 539 typedef struct drm_ctx_res32 { 540 int count; 541 u32 contexts; 542 } drm_ctx_res32_t; 543 544 static int compat_drm_resctx(struct file *file, unsigned int cmd, 545 unsigned long arg) 546 { 547 drm_ctx_res32_t __user *argp = (void __user *)arg; 548 drm_ctx_res32_t res32; 549 struct drm_ctx_res res; 550 int err; 551 552 if (copy_from_user(&res32, argp, sizeof(res32))) 553 return -EFAULT; 554 555 res.count = res32.count; 556 res.contexts = compat_ptr(res32.contexts); 557 err = drm_ioctl_kernel(file, drm_legacy_resctx, &res, DRM_AUTH); 558 if (err) 559 return err; 560 561 res32.count = res.count; 562 if (copy_to_user(argp, &res32, sizeof(res32))) 563 return -EFAULT; 564 565 return 0; 566 } 567 568 typedef struct drm_dma32 { 569 int context; /**< Context handle */ 570 int send_count; /**< Number of buffers to send */ 571 u32 send_indices; /**< List of handles to buffers */ 572 u32 send_sizes; /**< Lengths of data to send */ 573 enum drm_dma_flags flags; /**< Flags */ 574 int request_count; /**< Number of buffers requested */ 575 int request_size; /**< Desired size for buffers */ 576 u32 request_indices; /**< Buffer information */ 577 u32 request_sizes; 578 int granted_count; /**< Number of buffers granted */ 579 } drm_dma32_t; 580 581 static int compat_drm_dma(struct file *file, unsigned int cmd, 582 unsigned long arg) 583 { 584 drm_dma32_t d32; 585 drm_dma32_t __user *argp = (void __user *)arg; 586 struct drm_dma d; 587 int err; 588 589 if (copy_from_user(&d32, argp, sizeof(d32))) 590 return -EFAULT; 591 592 d.context = d32.context; 593 d.send_count = d32.send_count; 594 d.send_indices = compat_ptr(d32.send_indices); 595 d.send_sizes = compat_ptr(d32.send_sizes); 596 d.flags = d32.flags; 597 d.request_count = d32.request_count; 598 d.request_indices = compat_ptr(d32.request_indices); 599 d.request_sizes = compat_ptr(d32.request_sizes); 600 err = drm_ioctl_kernel(file, drm_legacy_dma_ioctl, &d, DRM_AUTH); 601 if (err) 602 return err; 603 604 if (put_user(d.request_size, &argp->request_size) 605 || put_user(d.granted_count, &argp->granted_count)) 606 return -EFAULT; 607 608 return 0; 609 } 610 #endif 611 612 #if IS_ENABLED(CONFIG_AGP) 613 typedef struct drm_agp_mode32 { 614 u32 mode; /**< AGP mode */ 615 } drm_agp_mode32_t; 616 617 static int compat_drm_agp_enable(struct file *file, unsigned int cmd, 618 unsigned long arg) 619 { 620 drm_agp_mode32_t __user *argp = (void __user *)arg; 621 struct drm_agp_mode mode; 622 623 if (get_user(mode.mode, &argp->mode)) 624 return -EFAULT; 625 626 return drm_ioctl_kernel(file, drm_agp_enable_ioctl, &mode, 627 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 628 } 629 630 typedef struct drm_agp_info32 { 631 int agp_version_major; 632 int agp_version_minor; 633 u32 mode; 634 u32 aperture_base; /* physical address */ 635 u32 aperture_size; /* bytes */ 636 u32 memory_allowed; /* bytes */ 637 u32 memory_used; 638 639 /* PCI information */ 640 unsigned short id_vendor; 641 unsigned short id_device; 642 } drm_agp_info32_t; 643 644 static int compat_drm_agp_info(struct file *file, unsigned int cmd, 645 unsigned long arg) 646 { 647 drm_agp_info32_t __user *argp = (void __user *)arg; 648 drm_agp_info32_t i32; 649 struct drm_agp_info info; 650 int err; 651 652 err = drm_ioctl_kernel(file, drm_agp_info_ioctl, &info, DRM_AUTH); 653 if (err) 654 return err; 655 656 i32.agp_version_major = info.agp_version_major; 657 i32.agp_version_minor = info.agp_version_minor; 658 i32.mode = info.mode; 659 i32.aperture_base = info.aperture_base; 660 i32.aperture_size = info.aperture_size; 661 i32.memory_allowed = info.memory_allowed; 662 i32.memory_used = info.memory_used; 663 i32.id_vendor = info.id_vendor; 664 i32.id_device = info.id_device; 665 if (copy_to_user(argp, &i32, sizeof(i32))) 666 return -EFAULT; 667 668 return 0; 669 } 670 671 typedef struct drm_agp_buffer32 { 672 u32 size; /**< In bytes -- will round to page boundary */ 673 u32 handle; /**< Used for binding / unbinding */ 674 u32 type; /**< Type of memory to allocate */ 675 u32 physical; /**< Physical used by i810 */ 676 } drm_agp_buffer32_t; 677 678 static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, 679 unsigned long arg) 680 { 681 drm_agp_buffer32_t __user *argp = (void __user *)arg; 682 drm_agp_buffer32_t req32; 683 struct drm_agp_buffer request; 684 int err; 685 686 if (copy_from_user(&req32, argp, sizeof(req32))) 687 return -EFAULT; 688 689 request.size = req32.size; 690 request.type = req32.type; 691 err = drm_ioctl_kernel(file, drm_agp_alloc_ioctl, &request, 692 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 693 if (err) 694 return err; 695 696 req32.handle = request.handle; 697 req32.physical = request.physical; 698 if (copy_to_user(argp, &req32, sizeof(req32))) { 699 drm_ioctl_kernel(file, drm_agp_free_ioctl, &request, 700 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 701 return -EFAULT; 702 } 703 704 return 0; 705 } 706 707 static int compat_drm_agp_free(struct file *file, unsigned int cmd, 708 unsigned long arg) 709 { 710 drm_agp_buffer32_t __user *argp = (void __user *)arg; 711 struct drm_agp_buffer request; 712 713 if (get_user(request.handle, &argp->handle)) 714 return -EFAULT; 715 716 return drm_ioctl_kernel(file, drm_agp_free_ioctl, &request, 717 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 718 } 719 720 typedef struct drm_agp_binding32 { 721 u32 handle; /**< From drm_agp_buffer */ 722 u32 offset; /**< In bytes -- will round to page boundary */ 723 } drm_agp_binding32_t; 724 725 static int compat_drm_agp_bind(struct file *file, unsigned int cmd, 726 unsigned long arg) 727 { 728 drm_agp_binding32_t __user *argp = (void __user *)arg; 729 drm_agp_binding32_t req32; 730 struct drm_agp_binding request; 731 732 if (copy_from_user(&req32, argp, sizeof(req32))) 733 return -EFAULT; 734 735 request.handle = req32.handle; 736 request.offset = req32.offset; 737 return drm_ioctl_kernel(file, drm_agp_bind_ioctl, &request, 738 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 739 } 740 741 static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, 742 unsigned long arg) 743 { 744 drm_agp_binding32_t __user *argp = (void __user *)arg; 745 struct drm_agp_binding request; 746 747 if (get_user(request.handle, &argp->handle)) 748 return -EFAULT; 749 750 return drm_ioctl_kernel(file, drm_agp_unbind_ioctl, &request, 751 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 752 } 753 #endif /* CONFIG_AGP */ 754 755 #if IS_ENABLED(CONFIG_DRM_LEGACY) 756 typedef struct drm_scatter_gather32 { 757 u32 size; /**< In bytes -- will round to page boundary */ 758 u32 handle; /**< Used for mapping / unmapping */ 759 } drm_scatter_gather32_t; 760 761 static int compat_drm_sg_alloc(struct file *file, unsigned int cmd, 762 unsigned long arg) 763 { 764 drm_scatter_gather32_t __user *argp = (void __user *)arg; 765 struct drm_scatter_gather request; 766 int err; 767 768 if (get_user(request.size, &argp->size)) 769 return -EFAULT; 770 771 err = drm_ioctl_kernel(file, drm_legacy_sg_alloc, &request, 772 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 773 if (err) 774 return err; 775 776 /* XXX not sure about the handle conversion here... */ 777 if (put_user(request.handle >> PAGE_SHIFT, &argp->handle)) 778 return -EFAULT; 779 780 return 0; 781 } 782 783 static int compat_drm_sg_free(struct file *file, unsigned int cmd, 784 unsigned long arg) 785 { 786 drm_scatter_gather32_t __user *argp = (void __user *)arg; 787 struct drm_scatter_gather request; 788 unsigned long x; 789 790 if (get_user(x, &argp->handle)) 791 return -EFAULT; 792 request.handle = x << PAGE_SHIFT; 793 return drm_ioctl_kernel(file, drm_legacy_sg_free, &request, 794 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 795 } 796 #endif 797 #if defined(CONFIG_X86) 798 typedef struct drm_update_draw32 { 799 drm_drawable_t handle; 800 unsigned int type; 801 unsigned int num; 802 /* 64-bit version has a 32-bit pad here */ 803 u64 data; /**< Pointer */ 804 } __attribute__((packed)) drm_update_draw32_t; 805 806 static int compat_drm_update_draw(struct file *file, unsigned int cmd, 807 unsigned long arg) 808 { 809 drm_update_draw32_t update32; 810 if (copy_from_user(&update32, (void __user *)arg, sizeof(update32))) 811 return -EFAULT; 812 813 return drm_ioctl_kernel(file, drm_noop, NULL, 814 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 815 } 816 #endif 817 818 struct drm_wait_vblank_request32 { 819 enum drm_vblank_seq_type type; 820 unsigned int sequence; 821 u32 signal; 822 }; 823 824 struct drm_wait_vblank_reply32 { 825 enum drm_vblank_seq_type type; 826 unsigned int sequence; 827 s32 tval_sec; 828 s32 tval_usec; 829 }; 830 831 typedef union drm_wait_vblank32 { 832 struct drm_wait_vblank_request32 request; 833 struct drm_wait_vblank_reply32 reply; 834 } drm_wait_vblank32_t; 835 836 static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, 837 unsigned long arg) 838 { 839 drm_wait_vblank32_t __user *argp = (void __user *)arg; 840 drm_wait_vblank32_t req32; 841 union drm_wait_vblank req; 842 int err; 843 844 if (copy_from_user(&req32, argp, sizeof(req32))) 845 return -EFAULT; 846 847 req.request.type = req32.request.type; 848 req.request.sequence = req32.request.sequence; 849 req.request.signal = req32.request.signal; 850 err = drm_ioctl_kernel(file, drm_wait_vblank_ioctl, &req, DRM_UNLOCKED); 851 if (err) 852 return err; 853 854 req32.reply.type = req.reply.type; 855 req32.reply.sequence = req.reply.sequence; 856 req32.reply.tval_sec = req.reply.tval_sec; 857 req32.reply.tval_usec = req.reply.tval_usec; 858 if (copy_to_user(argp, &req32, sizeof(req32))) 859 return -EFAULT; 860 861 return 0; 862 } 863 864 #if defined(CONFIG_X86) 865 typedef struct drm_mode_fb_cmd232 { 866 u32 fb_id; 867 u32 width; 868 u32 height; 869 u32 pixel_format; 870 u32 flags; 871 u32 handles[4]; 872 u32 pitches[4]; 873 u32 offsets[4]; 874 u64 modifier[4]; 875 } __attribute__((packed)) drm_mode_fb_cmd232_t; 876 877 static int compat_drm_mode_addfb2(struct file *file, unsigned int cmd, 878 unsigned long arg) 879 { 880 struct drm_mode_fb_cmd232 __user *argp = (void __user *)arg; 881 struct drm_mode_fb_cmd2 req64; 882 int err; 883 884 if (copy_from_user(&req64, argp, 885 offsetof(drm_mode_fb_cmd232_t, modifier))) 886 return -EFAULT; 887 888 if (copy_from_user(&req64.modifier, &argp->modifier, 889 sizeof(req64.modifier))) 890 return -EFAULT; 891 892 err = drm_ioctl_kernel(file, drm_mode_addfb2, &req64, 893 DRM_UNLOCKED); 894 if (err) 895 return err; 896 897 if (put_user(req64.fb_id, &argp->fb_id)) 898 return -EFAULT; 899 900 return 0; 901 } 902 #endif 903 904 static struct { 905 drm_ioctl_compat_t *fn; 906 char *name; 907 } drm_compat_ioctls[] = { 908 #define DRM_IOCTL32_DEF(n, f) [DRM_IOCTL_NR(n##32)] = {.fn = f, .name = #n} 909 DRM_IOCTL32_DEF(DRM_IOCTL_VERSION, compat_drm_version), 910 DRM_IOCTL32_DEF(DRM_IOCTL_GET_UNIQUE, compat_drm_getunique), 911 #if IS_ENABLED(CONFIG_DRM_LEGACY) 912 DRM_IOCTL32_DEF(DRM_IOCTL_GET_MAP, compat_drm_getmap), 913 #endif 914 DRM_IOCTL32_DEF(DRM_IOCTL_GET_CLIENT, compat_drm_getclient), 915 DRM_IOCTL32_DEF(DRM_IOCTL_GET_STATS, compat_drm_getstats), 916 DRM_IOCTL32_DEF(DRM_IOCTL_SET_UNIQUE, compat_drm_setunique), 917 #if IS_ENABLED(CONFIG_DRM_LEGACY) 918 DRM_IOCTL32_DEF(DRM_IOCTL_ADD_MAP, compat_drm_addmap), 919 DRM_IOCTL32_DEF(DRM_IOCTL_ADD_BUFS, compat_drm_addbufs), 920 DRM_IOCTL32_DEF(DRM_IOCTL_MARK_BUFS, compat_drm_markbufs), 921 DRM_IOCTL32_DEF(DRM_IOCTL_INFO_BUFS, compat_drm_infobufs), 922 DRM_IOCTL32_DEF(DRM_IOCTL_MAP_BUFS, compat_drm_mapbufs), 923 DRM_IOCTL32_DEF(DRM_IOCTL_FREE_BUFS, compat_drm_freebufs), 924 DRM_IOCTL32_DEF(DRM_IOCTL_RM_MAP, compat_drm_rmmap), 925 DRM_IOCTL32_DEF(DRM_IOCTL_SET_SAREA_CTX, compat_drm_setsareactx), 926 DRM_IOCTL32_DEF(DRM_IOCTL_GET_SAREA_CTX, compat_drm_getsareactx), 927 DRM_IOCTL32_DEF(DRM_IOCTL_RES_CTX, compat_drm_resctx), 928 DRM_IOCTL32_DEF(DRM_IOCTL_DMA, compat_drm_dma), 929 #endif 930 #if IS_ENABLED(CONFIG_AGP) 931 DRM_IOCTL32_DEF(DRM_IOCTL_AGP_ENABLE, compat_drm_agp_enable), 932 DRM_IOCTL32_DEF(DRM_IOCTL_AGP_INFO, compat_drm_agp_info), 933 DRM_IOCTL32_DEF(DRM_IOCTL_AGP_ALLOC, compat_drm_agp_alloc), 934 DRM_IOCTL32_DEF(DRM_IOCTL_AGP_FREE, compat_drm_agp_free), 935 DRM_IOCTL32_DEF(DRM_IOCTL_AGP_BIND, compat_drm_agp_bind), 936 DRM_IOCTL32_DEF(DRM_IOCTL_AGP_UNBIND, compat_drm_agp_unbind), 937 #endif 938 #if IS_ENABLED(CONFIG_DRM_LEGACY) 939 DRM_IOCTL32_DEF(DRM_IOCTL_SG_ALLOC, compat_drm_sg_alloc), 940 DRM_IOCTL32_DEF(DRM_IOCTL_SG_FREE, compat_drm_sg_free), 941 #endif 942 #if defined(CONFIG_X86) || defined(CONFIG_IA64) 943 DRM_IOCTL32_DEF(DRM_IOCTL_UPDATE_DRAW, compat_drm_update_draw), 944 #endif 945 DRM_IOCTL32_DEF(DRM_IOCTL_WAIT_VBLANK, compat_drm_wait_vblank), 946 #if defined(CONFIG_X86) || defined(CONFIG_IA64) 947 DRM_IOCTL32_DEF(DRM_IOCTL_MODE_ADDFB2, compat_drm_mode_addfb2), 948 #endif 949 }; 950 951 /** 952 * drm_compat_ioctl - 32bit IOCTL compatibility handler for DRM drivers 953 * @filp: file this ioctl is called on 954 * @cmd: ioctl cmd number 955 * @arg: user argument 956 * 957 * Compatibility handler for 32 bit userspace running on 64 kernels. All actual 958 * IOCTL handling is forwarded to drm_ioctl(), while marshalling structures as 959 * appropriate. Note that this only handles DRM core IOCTLs, if the driver has 960 * botched IOCTL itself, it must handle those by wrapping this function. 961 * 962 * Returns: 963 * Zero on success, negative error code on failure. 964 */ 965 long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 966 { 967 unsigned int nr = DRM_IOCTL_NR(cmd); 968 struct drm_file *file_priv = filp->private_data; 969 drm_ioctl_compat_t *fn; 970 int ret; 971 972 /* Assume that ioctls without an explicit compat routine will just 973 * work. This may not always be a good assumption, but it's better 974 * than always failing. 975 */ 976 if (nr >= ARRAY_SIZE(drm_compat_ioctls)) 977 return drm_ioctl(filp, cmd, arg); 978 979 fn = drm_compat_ioctls[nr].fn; 980 if (!fn) 981 return drm_ioctl(filp, cmd, arg); 982 983 DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n", 984 task_pid_nr(current), 985 (long)old_encode_dev(file_priv->minor->kdev->devt), 986 file_priv->authenticated, 987 drm_compat_ioctls[nr].name); 988 ret = (*fn)(filp, cmd, arg); 989 if (ret) 990 DRM_DEBUG("ret = %d\n", ret); 991 return ret; 992 } 993 EXPORT_SYMBOL(drm_compat_ioctl); 994