Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/platform/linux/cuda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 1 addition & 3 deletions src/platform/linux/kmsgrab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
66 changes: 66 additions & 0 deletions src/platform/linux/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#endif

// standard includes
#include <cerrno>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <iostream>
Expand Down Expand Up @@ -124,6 +126,70 @@ namespace dyn {
namespace platf {
using ifaddr_t = util::safe_ptr<ifaddrs, freeifaddrs>;

#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};

Expand Down
6 changes: 6 additions & 0 deletions src/platform/linux/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,9 @@ namespace dyn {
void *handle(const std::vector<const char *> &libs);

} // namespace dyn

#ifdef SUNSHINE_BUILD_DRM
namespace platf {
int open_drm_card_fd_non_master(const char *path);
} // namespace platf
#endif