DRI2 backend of Mesa started relying more on libdrm to open DRM devices nodes and opening multiple fds on a single node. This change keeps track of up to 10 fds so that stub works again.
Signed-off-by: Lionel Landwerlin <lionel.g.landwer...@intel.com> --- intel_stub.c | 98 +++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/intel_stub.c b/intel_stub.c index 8b8db64..9ac8ad3 100644 --- a/intel_stub.c +++ b/intel_stub.c @@ -23,9 +23,11 @@ #define _GNU_SOURCE /* for RTLD_NEXT */ +#include <assert.h> #include <string.h> #include <stdlib.h> #include <stdio.h> +#include <stdbool.h> #include <stdint.h> #include <stdarg.h> #include <errno.h> @@ -37,6 +39,8 @@ #include <dlfcn.h> #include <i915_drm.h> +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + static void *(*libc_mmap)(void *addr, size_t len, int prot, int flags, int fildes, off_t off); static void *(*libc_mmap64)(void *addr, size_t len, int prot, int flags, @@ -52,7 +56,39 @@ static int (*libc__fxstat64)(int ver, int fd, struct stat64 *buf); static int (*libc_fcntl)(int fd, int cmd, int param); static ssize_t (*libc_readlink)(const char *pathname, char *buf, size_t bufsiz); -static int drm_fd = 0x0000BEEF; +int open64(const char*, int, ...) __attribute__((alias("open"))); +int fcntl64(int fd, int cmd, ...) __attribute__((alias("fcntl"))); +void* mmap64(void*, size_t, int, int, int, off_t) __attribute__((alias("mmap"))); + +static int drm_fds[10]; +static int n_drm_fds = 0; + +static int create_drm_fd(int flags, mode_t mode) +{ + assert(n_drm_fds < ARRAY_SIZE(drm_fds)); + drm_fds[n_drm_fds++] = libc_open("/dev/null", flags, mode); + return drm_fds[n_drm_fds - 1]; +} + +static void remove_drm_fd(int fd) +{ + for (int i = 0; i < n_drm_fds; i++) { + if (fd == drm_fds[i]) { + for (int j = i + 1; j < n_drm_fds; j++) + drm_fds[j - 1] = drm_fds[j]; + n_drm_fds--; + return; + } + } +} + +static bool is_drm_fd(int fd) +{ + for (int i = 0; i < n_drm_fds; i++) + if (fd == drm_fds[i]) + return true; + return false; +} #define DRM_MAJOR 226 @@ -89,45 +125,27 @@ open(const char *path, int flags, ...) va_list args; mode_t mode; - if (strcmp(path, "/dev/dri/renderD128") == 0) - return drm_fd; - va_start(args, flags); mode = va_arg(args, int); va_end(args); - return libc_open(path, flags, mode); -} - -__attribute__ ((visibility ("default"))) int -open64(const char *path, int flags, ...) -{ - va_list args; - mode_t mode; - if (strcmp(path, "/dev/dri/renderD128") == 0) - return drm_fd; - - va_start(args, flags); - mode = va_arg(args, int); - va_end(args); + return create_drm_fd(flags, mode); - return libc_open64(path, flags, mode); + return libc_open(path, flags, mode); } __attribute__ ((visibility ("default"))) int close(int fd) { - if (fd == drm_fd) - return 0; - + remove_drm_fd(fd); return libc_close(fd); } __attribute__ ((visibility ("default"))) int fstat(int fd, struct stat *buf) { - if (fd == drm_fd) { + if (is_drm_fd(fd)) { buf->st_mode = S_IFCHR | (S_IRWXG | S_IRGRP | S_IRWXU | S_IRUSR); buf->st_uid = 0; @@ -141,7 +159,7 @@ fstat(int fd, struct stat *buf) __attribute__ ((visibility ("default"))) int fstat64(int fd, struct stat64 *buf) { - if (fd == drm_fd) { + if (is_drm_fd(fd)) { buf->st_mode = S_IFCHR | (S_IRWXG | S_IRGRP | S_IRWXU | S_IRUSR); buf->st_uid = 0; @@ -155,7 +173,7 @@ fstat64(int fd, struct stat64 *buf) __attribute__ ((visibility ("default"))) int __fxstat(int ver, int fd, struct stat *buf) { - if (fd == drm_fd) { + if (is_drm_fd(fd)) { buf->st_mode = S_IFCHR | (S_IRWXG | S_IRGRP | S_IRWXU | S_IRUSR); buf->st_rdev = makedev(DRM_MAJOR, 0); @@ -170,7 +188,7 @@ __fxstat(int ver, int fd, struct stat *buf) __attribute__ ((visibility ("default"))) int __fxstat64(int ver, int fd, struct stat64 *buf) { - if (fd == drm_fd) { + if (is_drm_fd(fd)) { buf->st_mode = S_IFCHR | (S_IRWXG | S_IRGRP | S_IRWXU | S_IRUSR); buf->st_rdev = makedev(DRM_MAJOR, 0); @@ -188,8 +206,8 @@ fcntl(int fd, int cmd, ...) va_list args; int param; - if (fd == drm_fd && cmd == F_DUPFD_CLOEXEC) - return drm_fd; + if (is_drm_fd(fd) && cmd == F_DUPFD_CLOEXEC) + return create_drm_fd(O_RDWR, O_CLOEXEC); va_start(args, cmd); param = va_arg(args, int); @@ -202,7 +220,7 @@ __attribute__ ((visibility ("default"))) void * mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { - if (fildes == drm_fd) { + if (is_drm_fd(fildes)) { return libc_mmap(NULL, len, prot, flags | MAP_ANONYMOUS, -1, 0); } else { @@ -210,19 +228,6 @@ mmap(void *addr, size_t len, int prot, int flags, } } -__attribute__ ((visibility ("default"))) void * -mmap64(void *addr, size_t len, int prot, int flags, - int fildes, off_t off) -{ - if (fildes == drm_fd) { - return libc_mmap64(NULL, len, prot, flags | MAP_ANONYMOUS, - -1, 0); - } else { - return libc_mmap64(addr, len, prot, flags, fildes, off); - } -} - - __attribute__ ((visibility ("default"))) ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) { @@ -237,20 +242,13 @@ ioctl(int fd, unsigned long request, ...) { va_list args; void *argp; - struct stat buf; char *pci_id; va_start(args, request); argp = va_arg(args, void *); va_end(args); - if (_IOC_TYPE(request) == DRM_IOCTL_BASE && - drm_fd != fd && libc_fstat(fd, &buf) == 0 && - (buf.st_mode & S_IFMT) == S_IFCHR && major(buf.st_rdev) == DRM_MAJOR) { - drm_fd = fd; - } - - if (fd == drm_fd) { + if (is_drm_fd(fd)) { switch (request) { case DRM_IOCTL_VERSION: return dispatch_version(fd, request, argp); -- 2.20.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev