From c97c2f4c26a8d23b7126e92c5b9663ee579e0f5f Mon Sep 17 00:00:00 2001 From: panxi39 Date: Sat, 13 Jun 2026 00:23:51 +0800 Subject: [PATCH] fix(linux): drop implicit DRM master for card fds --- src/platform/linux/cuda.cpp | 4 +++ src/platform/linux/kmsgrab.cpp | 4 +-- src/platform/linux/misc.cpp | 66 ++++++++++++++++++++++++++++++++++ src/platform/linux/misc.h | 6 ++++ 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/platform/linux/cuda.cpp b/src/platform/linux/cuda.cpp index 9fd5e529b42..e775958d922 100644 --- a/src/platform/linux/cuda.cpp +++ b/src/platform/linux/cuda.cpp @@ -264,7 +264,11 @@ namespace cuda { fs::path dri_path {"/dev/dri"sv}; auto device_path = dri_path / file; +#ifdef SUNSHINE_BUILD_DRM + return platf::open_drm_card_fd_non_master(device_path.c_str()); +#else return open(device_path.c_str(), O_RDWR); +#endif } } catch (const std::filesystem::filesystem_error &err) { BOOST_LOG(error) << "Failed to read sysfs: "sv << err.what(); diff --git a/src/platform/linux/kmsgrab.cpp b/src/platform/linux/kmsgrab.cpp index 11571c7c361..903095bd9a7 100644 --- a/src/platform/linux/kmsgrab.cpp +++ b/src/platform/linux/kmsgrab.cpp @@ -320,10 +320,8 @@ namespace platf { int init(const char *path) { cap_sys_admin admin; - fd.el = open(path, O_RDWR); - + fd.el = open_drm_card_fd_non_master(path); if (fd.el < 0) { - BOOST_LOG(error) << "Couldn't open: "sv << path << ": "sv << strerror(errno); return -1; } diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index 5f417810f6f..14e9c59bd75 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -9,6 +9,8 @@ #endif // standard includes +#include +#include #include #include #include @@ -124,6 +126,70 @@ namespace dyn { namespace platf { using ifaddr_t = util::safe_ptr; +#ifdef SUNSHINE_BUILD_DRM + int open_drm_card_fd_non_master(const char *path) { + int fd = open(path, O_RDWR | O_CLOEXEC); + if (fd < 0) { + BOOST_LOG(error) << "Couldn't open: "sv << path << ": "sv << strerror(errno); + return -1; + } + + auto close_and_fail = [&]() { + close(fd); + return -1; + }; + + auto is_master = [&]() -> int { + drm_auth_t auth {}; + auth.magic = 0; + + errno = 0; + if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth) == 0) { + return 1; + } + + auto err = errno; + if (err == EACCES) { + return 0; + } + + if (err == EINVAL || err == ENOENT) { + return 1; + } + + BOOST_LOG(error) << "Couldn't determine DRM master state for "sv << path << ": "sv << strerror(err); + return -1; + }; + + auto master = is_master(); + if (master < 0) { + return close_and_fail(); + } + + if (master) { + if (drmDropMaster(fd)) { + auto err = errno; + BOOST_LOG(error) << "Couldn't drop DRM master for "sv << path << ": "sv << strerror(err); + return close_and_fail(); + } + + BOOST_LOG(info) << "Dropped DRM master for "sv << path; + + master = is_master(); + if (master < 0) { + return close_and_fail(); + } + + if (master) { + BOOST_LOG(error) << "Still DRM master after drop: "sv << path; + return close_and_fail(); + } + } + + return fd; + } +#endif + ifaddr_t get_ifaddrs() { ifaddrs *p {nullptr}; diff --git a/src/platform/linux/misc.h b/src/platform/linux/misc.h index c9f98f44de2..c22254bb68e 100644 --- a/src/platform/linux/misc.h +++ b/src/platform/linux/misc.h @@ -32,3 +32,9 @@ namespace dyn { void *handle(const std::vector &libs); } // namespace dyn + +#ifdef SUNSHINE_BUILD_DRM +namespace platf { + int open_drm_card_fd_non_master(const char *path); +} // namespace platf +#endif