1/*************************************************************************** 2 3 Copyright 2013 Intel Corporation. All Rights Reserved. 4 5 Permission is hereby granted, free of charge, to any person obtaining a 6 copy of this software and associated documentation files (the 7 "Software"), to deal in the Software without restriction, including 8 without limitation the rights to use, copy, modify, merge, publish, 9 distribute, sub license, and/or sell copies of the Software, and to 10 permit persons to whom the Software is furnished to do so, subject to 11 the following conditions: 12 13 The above copyright notice and this permission notice (including the 14 next paragraph) shall be included in all copies or substantial portions 15 of the Software. 16 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 21 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 **************************************************************************/ 26 27#ifdef HAVE_CONFIG_H 28#include "config.h" 29#endif 30 31#include <sys/types.h> 32#include <sys/stat.h> 33#include <assert.h> 34#include <string.h> 35#include <unistd.h> 36#include <fcntl.h> 37#include <stdlib.h> 38#include <dirent.h> 39#include <errno.h> 40 41#if MAJOR_IN_MKDEV 42#include <sys/mkdev.h> 43#elif MAJOR_IN_SYSMACROS 44#include <sys/sysmacros.h> 45#endif 46 47#include <pciaccess.h> 48 49#include <xorg-server.h> 50#include <xf86.h> 51#include <xf86drm.h> 52#include <xf86drmMode.h> 53#include <xf86_OSproc.h> 54#include <i915_drm.h> 55 56#ifdef XSERVER_PLATFORM_BUS 57#include <xf86platformBus.h> 58#endif 59 60#ifdef HAVE_VALGRIND 61#include <valgrind.h> 62#include <memcheck.h> 63#define VG(x) x 64#else 65#define VG(x) 66#endif 67 68#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s))) 69 70#include "intel_driver.h" 71#include "fd.h" 72 73struct intel_device { 74 int idx; 75 char *master_node; 76 char *render_node; 77 int fd; 78 int device_id; 79 int open_count; 80 int master_count; 81}; 82 83static int intel_device_key = -1; 84 85static int dump_file(ScrnInfoPtr scrn, const char *path) 86{ 87 FILE *file; 88 size_t len = 0; 89 char *line = NULL; 90 91 file = fopen(path, "r"); 92 if (file == NULL) 93 return 0; 94 95 xf86DrvMsg(scrn->scrnIndex, X_INFO, "[drm] Contents of '%s':\n", path); 96 while (getline(&line, &len, file) != -1) 97 xf86DrvMsg(scrn->scrnIndex, X_INFO, "[drm] %s", line); 98 99 free(line); 100 fclose(file); 101 return 1; 102} 103 104static int __find_debugfs(void) 105{ 106 int i; 107 108 for (i = 0; i < DRM_MAX_MINOR; i++) { 109 char path[80]; 110 111 sprintf(path, "/sys/kernel/debug/dri/%d/i915_wedged", i); 112 if (access(path, R_OK) == 0) 113 return i; 114 115 sprintf(path, "/debug/dri/%d/i915_wedged", i); 116 if (access(path, R_OK) == 0) 117 return i; 118 } 119 120 return -1; 121} 122 123static int drm_get_minor(int fd) 124{ 125 struct stat st; 126 127 if (fstat(fd, &st)) 128 return __find_debugfs(); 129 130 if (!S_ISCHR(st.st_mode)) 131 return __find_debugfs(); 132 133 return st.st_rdev & 0x63; 134} 135 136#if __linux__ 137#include <sys/mount.h> 138 139static void dump_debugfs(ScrnInfoPtr scrn, int fd, const char *name) 140{ 141 char path[80]; 142 int minor; 143 144 minor = drm_get_minor(fd); 145 if (minor < 0) 146 return; 147 148 sprintf(path, "/sys/kernel/debug/dri/%d/%s", minor, name); 149 if (dump_file(scrn, path)) 150 return; 151 152 sprintf(path, "/debug/dri/%d/%s", minor, name); 153 if (dump_file(scrn, path)) 154 return; 155 156 if (mount("X-debug", "/sys/kernel/debug", "debugfs", 0, 0) == 0) { 157 sprintf(path, "/sys/kernel/debug/dri/%d/%s", minor, name); 158 dump_file(scrn, path); 159 umount("X-debug"); 160 return; 161 } 162} 163#else 164static void dump_debugfs(ScrnInfoPtr scrn, int fd, const char *name) { } 165#endif 166 167static void dump_clients_info(ScrnInfoPtr scrn, int fd) 168{ 169 dump_debugfs(scrn, fd, "clients"); 170} 171 172static int __intel_get_device_id(int fd) 173{ 174 struct drm_i915_getparam gp; 175 int devid = 0; 176 177 VG_CLEAR(gp); 178 gp.param = I915_PARAM_CHIPSET_ID; 179 gp.value = &devid; 180 181 if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp)) 182 return 0; 183 184 return devid; 185} 186 187int intel_entity_get_devid(int idx) 188{ 189 struct intel_device *dev; 190 191 dev = xf86GetEntityPrivate(idx, intel_device_key)->ptr; 192 if (dev == NULL) 193 return 0; 194 195 return dev->device_id; 196} 197 198static inline struct intel_device *intel_device(ScrnInfoPtr scrn) 199{ 200 if (scrn->entityList == NULL) 201 return NULL; 202 203 return xf86GetEntityPrivate(scrn->entityList[0], intel_device_key)->ptr; 204} 205 206static const char *kernel_module_names[] ={ 207 "i915", 208 NULL, 209}; 210 211static int is_i915_device(int fd) 212{ 213 drm_version_t version; 214 const char **kn; 215 char name[5] = ""; 216 217 memset(&version, 0, sizeof(version)); 218 version.name_len = 4; 219 version.name = name; 220 221 if (drmIoctl(fd, DRM_IOCTL_VERSION, &version)) 222 return 0; 223 224 for (kn = kernel_module_names; *kn; kn++) 225 if (strcmp(*kn, name) == 0) 226 return 1; 227 228 return 0; 229} 230 231static int load_i915_kernel_module(void) 232{ 233 const char **kn; 234 235 for (kn = kernel_module_names; *kn; kn++) 236 if (xf86LoadKernelModule(*kn)) 237 return 0; 238 239 return -1; 240} 241 242static int is_i915_gem(int fd) 243{ 244 int ret = is_i915_device(fd); 245 246 if (ret) { 247 struct drm_i915_getparam gp; 248 249 VG_CLEAR(gp); 250 gp.param = I915_PARAM_HAS_GEM; 251 gp.value = &ret; 252 253 if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp)) 254 ret = 0; 255 } 256 257 return ret; 258} 259 260static int __intel_check_device(int fd) 261{ 262 int ret; 263 264 /* Confirm that this is a i915.ko device with GEM/KMS enabled */ 265 ret = is_i915_gem(fd); 266 if (ret && !hosted()) { 267 struct drm_mode_card_res res; 268 269 memset(&res, 0, sizeof(res)); 270 if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) 271 ret = 0; 272 } 273 274 return ret; 275} 276 277static int open_cloexec(const char *path) 278{ 279 struct stat st; 280 int loop = 1000; 281 int fd; 282 283 /* No file? Assume the driver is loading slowly */ 284 while (stat(path, &st) == -1 && errno == ENOENT && --loop) 285 usleep(50000); 286 287 if (loop != 1000) 288 ErrorF("intel: waited %d ms for '%s' to appear\n", 289 (1000 - loop) * 50, path); 290 291 fd = -1; 292#ifdef O_CLOEXEC 293 fd = open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC); 294#endif 295 if (fd == -1) 296 fd = fd_set_cloexec(open(path, O_RDWR | O_NONBLOCK)); 297 298 return fd; 299} 300 301#ifdef __linux__ 302static int __intel_open_device__major_minor(int _major, int _minor) 303{ 304 char path[256]; 305 DIR *dir; 306 struct dirent *de; 307 int base, fd = -1; 308 309 base = sprintf(path, "/dev/dri/"); 310 311 dir = opendir(path); 312 if (dir == NULL) 313 return -1; 314 315 while ((de = readdir(dir)) != NULL) { 316 struct stat st; 317 318 if (*de->d_name == '.') 319 continue; 320 321 sprintf(path + base, "%s", de->d_name); 322 if (stat(path, &st) == 0 && 323 major(st.st_rdev) == _major && 324 minor(st.st_rdev) == _minor) { 325 fd = open_cloexec(path); 326 break; 327 } 328 } 329 330 closedir(dir); 331 332 return fd; 333} 334 335static int __intel_open_device__pci(const struct pci_device *pci) 336{ 337 struct stat st; 338 char path[256]; 339 DIR *dir; 340 struct dirent *de; 341 int base; 342 int fd; 343 344 /* Look up the major:minor for the drm device through sysfs. 345 * First we need to check that sysfs is available, then 346 * check that we have loaded our driver. When we are happy 347 * that our KMS module is loaded, we can then search for our 348 * device node. We make the assumption that it uses the same 349 * name, but after that we read the major:minor assigned to us 350 * and search for a matching entry in /dev. 351 */ 352 353 base = sprintf(path, 354 "/sys/bus/pci/devices/%04x:%02x:%02x.%d/", 355 pci->domain, pci->bus, pci->dev, pci->func); 356 if (stat(path, &st)) 357 return -1; 358 359 sprintf(path + base, "drm"); 360 dir = opendir(path); 361 if (dir == NULL) { 362 int loop = 0; 363 364 sprintf(path + base, "driver"); 365 if (stat(path, &st)) { 366 if (load_i915_kernel_module()) 367 return -1; 368 (void)xf86LoadKernelModule("fbcon"); 369 } 370 371 sprintf(path + base, "drm"); 372 while ((dir = opendir(path)) == NULL && loop++ < 100) 373 usleep(20000); 374 375 ErrorF("intel: waited %d ms for i915.ko driver to load\n", loop * 20000 / 1000); 376 377 if (dir == NULL) 378 return -1; 379 } 380 381 fd = -1; 382 while ((de = readdir(dir)) != NULL) { 383 if (*de->d_name == '.') 384 continue; 385 386 if (strncmp(de->d_name, "card", 4) == 0) { 387 sprintf(path + base + 4, "/dev/dri/%s", de->d_name); 388 fd = open_cloexec(path + base + 4); 389 if (fd != -1) 390 break; 391 392 sprintf(path + base + 3, "/%s/dev", de->d_name); 393 fd = open(path, O_RDONLY); 394 if (fd == -1) 395 break; 396 397 base = read(fd, path, sizeof(path) - 1); 398 close(fd); 399 400 fd = -1; 401 if (base > 0) { 402 int major, minor; 403 path[base] = '\0'; 404 if (sscanf(path, "%d:%d", &major, &minor) == 2) 405 fd = __intel_open_device__major_minor(major, minor); 406 } 407 break; 408 } 409 } 410 closedir(dir); 411 412 return fd; 413} 414#else 415static int __intel_open_device__pci(const struct pci_device *pci) { return -1; } 416#endif 417 418static int __intel_open_device__legacy(const struct pci_device *pci) 419{ 420 char id[20]; 421 int ret; 422 423 snprintf(id, sizeof(id), 424 "pci:%04x:%02x:%02x.%d", 425 pci->domain, pci->bus, pci->dev, pci->func); 426 427 ret = drmCheckModesettingSupported(id); 428 if (ret) { 429 if (load_i915_kernel_module() == 0) 430 ret = drmCheckModesettingSupported(id); 431 if (ret) 432 return -1; 433 /* Be nice to the user and load fbcon too */ 434 (void)xf86LoadKernelModule("fbcon"); 435 } 436 437 return fd_set_nonblock(drmOpen(NULL, id)); 438} 439 440static int __intel_open_device(const struct pci_device *pci, const char *path) 441{ 442 int fd; 443 444 if (path == NULL) { 445 if (pci == NULL) 446 return -1; 447 448 fd = __intel_open_device__pci(pci); 449 if (fd == -1) 450 fd = __intel_open_device__legacy(pci); 451 } else 452 fd = open_cloexec(path); 453 454 return fd; 455} 456 457static char *find_master_node(int fd) 458{ 459 struct stat st, master; 460 char buf[128]; 461 462 if (fstat(fd, &st)) 463 return NULL; 464 465 if (!S_ISCHR(st.st_mode)) 466 return NULL; 467 468 sprintf(buf, "/dev/dri/card%d", (int)(st.st_rdev & 0x7f)); 469 if (stat(buf, &master) == 0 && 470 S_ISCHR(master.st_mode) && 471 (st.st_rdev & 0x7f) == master.st_rdev) 472 return strdup(buf); 473 474 /* Fallback to iterating over the usual suspects */ 475 return drmGetDeviceNameFromFd(fd); 476} 477 478static int is_render_node(int fd, struct stat *st) 479{ 480 if (fstat(fd, st)) 481 return -1; 482 483 if (!S_ISCHR(st->st_mode)) 484 return -1; 485 486 return st->st_rdev & 0x80; 487} 488 489static char *find_render_node(int fd) 490{ 491 struct stat master, render; 492 char buf[128]; 493 int i; 494 495 /* Are we a render-node ourselves? */ 496 if (is_render_node(fd, &master)) 497 return NULL; 498 499 sprintf(buf, "/dev/dri/renderD%d", (int)((master.st_rdev | 0x80) & 0xbf)); 500 if (stat(buf, &render) == 0 && 501 S_ISCHR(render.st_mode) && 502 render.st_rdev == (master.st_rdev | 0x80)) 503 return strdup(buf); 504 505 /* Misaligned card <-> renderD, do a full search */ 506 for (i = 0; i < 16; i++) { 507 sprintf(buf, "/dev/dri/renderD%d", i + 128); 508 if (stat(buf, &render) == 0 && 509 S_ISCHR(render.st_mode) && 510 render.st_rdev == (master.st_rdev | 0x80)) 511 return strdup(buf); 512 } 513 514 return NULL; 515} 516 517#if defined(ODEV_ATTRIB_PATH) 518static char *get_path(struct xf86_platform_device *dev) 519{ 520 const char *path; 521 522 if (dev == NULL) 523 return NULL; 524 525 path = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH); 526 if (path == NULL) 527 return NULL; 528 529 return strdup(path); 530} 531 532#else 533 534static char *get_path(struct xf86_platform_device *dev) 535{ 536 return NULL; 537} 538#endif 539 540 541#if defined(ODEV_ATTRIB_FD) 542static int get_fd(struct xf86_platform_device *dev) 543{ 544 if (dev == NULL) 545 return -1; 546 547 return xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_FD, -1); 548} 549 550#else 551 552static int get_fd(struct xf86_platform_device *dev) 553{ 554 return -1; 555} 556#endif 557 558static int is_master(int fd) 559{ 560 drmSetVersion sv; 561 562 sv.drm_di_major = 1; 563 sv.drm_di_minor = 1; 564 sv.drm_dd_major = -1; 565 sv.drm_dd_minor = -1; 566 567 return drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv) == 0; 568} 569 570int intel_open_device(int entity_num, 571 const struct pci_device *pci, 572 struct xf86_platform_device *platform) 573{ 574 struct intel_device *dev; 575 char *path; 576 int fd, master_count; 577 578 if (intel_device_key == -1) 579 intel_device_key = xf86AllocateEntityPrivateIndex(); 580 if (intel_device_key == -1) 581 return -1; 582 583 dev = xf86GetEntityPrivate(entity_num, intel_device_key)->ptr; 584 if (dev) 585 return dev->fd; 586 587 path = get_path(platform); 588 589 master_count = 1; /* DRM_MASTER is managed by Xserver */ 590 fd = get_fd(platform); 591 if (fd == -1) { 592 fd = __intel_open_device(pci, path); 593 if (fd == -1) 594 goto err_path; 595 596 master_count = 0; 597 } 598 599 if (path == NULL) { 600 path = find_master_node(fd); 601 if (path == NULL) 602 goto err_close; 603 } 604 605 if (!__intel_check_device(fd)) 606 goto err_close; 607 608 dev = malloc(sizeof(*dev)); 609 if (dev == NULL) 610 goto err_close; 611 612 /* If hosted under a system compositor, just pretend to be master */ 613 if (hosted()) 614 master_count++; 615 616 /* Non-root user holding MASTER, don't let go */ 617 if (geteuid() && is_master(fd)) 618 master_count++; 619 620 if (pci) 621 dev->device_id = pci->device_id; 622 else 623 dev->device_id = __intel_get_device_id(fd); 624 625 dev->idx = entity_num; 626 dev->fd = fd; 627 dev->open_count = master_count; 628 dev->master_count = master_count; 629 dev->master_node = path; 630 dev->render_node = find_render_node(fd); 631 if (dev->render_node == NULL) 632 dev->render_node = dev->master_node; 633 634 xf86GetEntityPrivate(entity_num, intel_device_key)->ptr = dev; 635 636 return fd; 637 638err_close: 639 if (master_count == 0) /* Don't close server-fds */ 640 close(fd); 641err_path: 642 free(path); 643 return -1; 644} 645 646void intel_close_device(int entity_num) 647{ 648 struct intel_device *dev; 649 650 if (intel_device_key == -1) 651 return; 652 653 dev = xf86GetEntityPrivate(entity_num, intel_device_key)->ptr; 654 xf86GetEntityPrivate(entity_num, intel_device_key)->ptr = NULL; 655 if (!dev) 656 return; 657 658 if (dev->master_count == 0) /* Don't close server-fds */ 659 close(dev->fd); 660 661 if (dev->render_node != dev->master_node) 662 free(dev->render_node); 663 free(dev->master_node); 664 free(dev); 665} 666 667int __intel_peek_fd(ScrnInfoPtr scrn) 668{ 669 struct intel_device *dev; 670 671 dev = intel_device(scrn); 672 assert(dev && dev->fd != -1); 673 674 return dev->fd; 675} 676 677int intel_has_render_node(struct intel_device *dev) 678{ 679 struct stat st; 680 681 assert(dev && dev->fd != -1); 682 return is_render_node(dev->fd, &st); 683} 684 685struct intel_device *intel_get_device(ScrnInfoPtr scrn, int *fd) 686{ 687 struct intel_device *dev; 688 int ret; 689 690 dev = intel_device(scrn); 691 if (dev == NULL) 692 return NULL; 693 694 assert(dev->fd != -1); 695 696 if (dev->open_count++ == 0) { 697 drmSetVersion sv; 698 int retry = 2000; 699 700 assert(!hosted()); 701 702 /* Check that what we opened was a master or a 703 * master-capable FD, by setting the version of the 704 * interface we'll use to talk to it. 705 */ 706 do { 707 sv.drm_di_major = 1; 708 sv.drm_di_minor = 1; 709 sv.drm_dd_major = -1; 710 sv.drm_dd_minor = -1; 711 ret = drmIoctl(dev->fd, DRM_IOCTL_SET_VERSION, &sv); 712 if (ret == 0) 713 break; 714 715 usleep(1000); 716 } while (--retry); 717 if (ret != 0) { 718 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 719 "[drm] failed to set drm interface version: %s [%d].\n", 720 strerror(errno), errno); 721 dump_clients_info(scrn, dev->fd); 722 dev->open_count--; 723 return NULL; 724 } 725 } 726 727 *fd = dev->fd; 728 return dev; 729} 730 731const char *intel_get_master_name(struct intel_device *dev) 732{ 733 assert(dev && dev->master_node); 734 return dev->master_node; 735} 736 737const char *intel_get_client_name(struct intel_device *dev) 738{ 739 assert(dev && dev->render_node); 740 return dev->render_node; 741} 742 743static int authorise(struct intel_device *dev, int fd) 744{ 745 struct stat st; 746 drm_magic_t magic; 747 748 if (is_render_node(fd, &st)) /* restricted authority, do not elevate */ 749 return 1; 750 751 return drmGetMagic(fd, &magic) == 0 && drmAuthMagic(dev->fd, magic) == 0; 752} 753 754int intel_get_client_fd(struct intel_device *dev) 755{ 756 int fd = -1; 757 758 assert(dev && dev->fd != -1); 759 assert(dev->render_node); 760 761#ifdef O_CLOEXEC 762 fd = open(dev->render_node, O_RDWR | O_CLOEXEC); 763#endif 764 if (fd < 0) 765 fd = fd_set_cloexec(open(dev->render_node, O_RDWR)); 766 if (fd < 0) 767 return -BadAlloc; 768 769 if (!authorise(dev, fd)) { 770 close(fd); 771 return -BadMatch; 772 } 773 774 assert(is_i915_gem(fd)); 775 776 return fd; 777} 778 779int intel_get_device_id(struct intel_device *dev) 780{ 781 assert(dev && dev->fd != -1); 782 return dev->device_id; 783} 784 785int intel_get_master(struct intel_device *dev) 786{ 787 int ret; 788 789 assert(dev && dev->fd != -1); 790 791 ret = 0; 792 if (dev->master_count++ == 0) { 793 int retry = 2000; 794 795 assert(!hosted()); 796 do { 797 ret = drmSetMaster(dev->fd); 798 if (ret == 0) 799 break; 800 usleep(1000); 801 } while (--retry); 802 } 803 804 return ret; 805} 806 807int intel_put_master(struct intel_device *dev) 808{ 809 int ret; 810 811 assert(dev && dev->fd != -1); 812 813 ret = 0; 814 assert(dev->master_count); 815 if (--dev->master_count == 0) { 816 assert(!hosted()); 817 assert(drmSetMaster(dev->fd) == 0); 818 ret = drmDropMaster(dev->fd); 819 } 820 821 return ret; 822} 823 824void intel_put_device(struct intel_device *dev) 825{ 826 assert(dev && dev->fd != -1); 827 828 assert(dev->open_count); 829 if (--dev->open_count) 830 return; 831 832 assert(!hosted()); 833 xf86GetEntityPrivate(dev->idx, intel_device_key)->ptr = NULL; 834 835 drmClose(dev->fd); 836 if (dev->render_node != dev->master_node) 837 free(dev->render_node); 838 free(dev->master_node); 839 free(dev); 840} 841