Blame SOURCES/0001-linux-Make-platform-device-probe-less-fragile.patch

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