summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2018-09-18 14:37:51 -0400
committerMatt Turner <mattst88@gmail.com>2020-08-18 17:20:09 +0000
commit74b7427c41b4e4104af7abf70a996c086d3d7628 (patch)
tree7d63225044c7a120e209601aa742b0781f6df38f
parent4979ac8f0be6fa2c4a1edd8a527f7d2134d8586a (diff)
linux: Make platform device probe less fragile
At the point where xf86BusProbe runs we haven't yet taken our own VT, which means we can't perform drm "master" operations on the device. This is tragic, because we need master to fish the bus id string out of the kernel, which we can only do after drmSetInterfaceVersion, which for some reason stores that string on the device not the file handle and thus needs master access. Fortunately we know the format of the busid string, and it happens to almost be the same as the ID_PATH variable from udev. Use that instead and stop calling drmSetInterfaceVersion. (backported from commit 0816e8fca6194dfb4cc94c3a7fcb2c7f2a921386) Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Huacai Chen <chenhc@lemote.com>
-rw-r--r--config/udev.c17
-rw-r--r--hw/xfree86/os-support/linux/lnx_platform.c20
2 files changed, 14 insertions, 23 deletions
diff --git a/config/udev.c b/config/udev.c
index 3a73189e2..8c6c4b666 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -56,7 +56,7 @@ static struct udev_monitor *udev_monitor;
#ifdef CONFIG_UDEV_KMS
static void
-config_udev_odev_setup_attribs(const char *path, const char *syspath,
+config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path, const char *syspath,
int major, int minor,
config_odev_probe_proc_ptr probe_callback);
#endif
@@ -128,7 +128,7 @@ device_added(struct udev_device *udev_device)
LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);
- config_udev_odev_setup_attribs(path, syspath, major(devnum),
+ config_udev_odev_setup_attribs(udev_device, path, syspath, major(devnum),
minor(devnum), NewGPUDeviceRequest);
return;
}
@@ -322,7 +322,7 @@ device_removed(struct udev_device *device)
LogMessage(X_INFO, "config/udev: removing GPU device %s %s\n",
syspath, path);
- config_udev_odev_setup_attribs(path, syspath, major(devnum),
+ config_udev_odev_setup_attribs(device, path, syspath, major(devnum),
minor(devnum), DeleteGPUDeviceRequest);
/* Retry vtenter after a drm node removal */
systemd_logind_vtenter();
@@ -465,17 +465,24 @@ config_udev_fini(void)
#ifdef CONFIG_UDEV_KMS
static void
-config_udev_odev_setup_attribs(const char *path, const char *syspath,
+config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path, const char *syspath,
int major, int minor,
config_odev_probe_proc_ptr probe_callback)
{
struct OdevAttributes *attribs = config_odev_allocate_attributes();
+ const char *value;
attribs->path = XNFstrdup(path);
attribs->syspath = XNFstrdup(syspath);
attribs->major = major;
attribs->minor = minor;
+ value = udev_device_get_property_value(udev_device, "ID_PATH");
+ if (value && !strncmp(value, "pci-", 4)) {
+ attribs->busid = XNFstrdup(value);
+ attribs->busid[3] = ':';
+ }
+
/* ownership of attribs is passed to probe layer */
probe_callback(attribs);
}
@@ -516,7 +523,7 @@ config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback)
else if (!check_seat(udev_device))
goto no_probe;
- config_udev_odev_setup_attribs(path, syspath, major(devnum),
+ config_udev_odev_setup_attribs(udev_device, path, syspath, major(devnum),
minor(devnum), probe_callback);
no_probe:
udev_device_unref(udev_device);
diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c
index 70374ace8..e62306219 100644
--- a/hw/xfree86/os-support/linux/lnx_platform.c
+++ b/hw/xfree86/os-support/linux/lnx_platform.c
@@ -23,13 +23,13 @@
static Bool
get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
{
- drmSetVersion sv;
drmVersionPtr v;
- char *buf;
int fd;
int err = 0;
Bool paused, server_fd = FALSE;
+ LogMessage(X_INFO, "Platform probe for %s\n", attribs->syspath);
+
fd = systemd_logind_take_fd(attribs->major, attribs->minor, path, &paused);
if (fd != -1) {
if (paused) {
@@ -48,18 +48,6 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
if (fd == -1)
return FALSE;
- sv.drm_di_major = 1;
- sv.drm_di_minor = 4;
- sv.drm_dd_major = -1; /* Don't care */
- sv.drm_dd_minor = -1; /* Don't care */
-
- err = drmSetInterfaceVersion(fd, &sv);
- if (err) {
- xf86Msg(X_ERROR, "%s: failed to set DRM interface version 1.4: %s\n",
- path, strerror(-err));
- goto out;
- }
-
/* for a delayed probe we've already added the device */
if (delayed_index == -1) {
xf86_add_platform_device(attribs, FALSE);
@@ -69,10 +57,6 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
if (server_fd)
xf86_platform_devices[delayed_index].flags |= XF86_PDEV_SERVER_FD;
- buf = drmGetBusid(fd);
- xf86_platform_odev_attributes(delayed_index)->busid = XNFstrdup(buf);
- drmFreeBusid(buf);
-
v = drmGetVersion(fd);
if (!v) {
xf86Msg(X_ERROR, "%s: failed to query DRM version\n", path);