drm: Branch 'master'

[email protected] (GitLab Mirror) Fri, 22 Feb 2019 21:03:16 +0000 (UTC)
Newsgroups gmane.comp.video.dri.patches
Message-ID <[email protected]>
 xf86drm.c |   23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

New commits:
commit 56c21f877bda7b8c62c3d7925b070b5113d807f2
Author: Emily Deng <[email protected]>
Date:   Thu Feb 14 15:53:38 2019 +0800

    libdrm: Fix issue about differrent domainID but same BDF
    
    For multiple GPUs which has the same BDF, but has different domain ID,
    the drmOpenByBusid will return the wrong fd when startx.
    
    The reproduce sequence as below:
    1. Call drmOpenByBusid to open Card0, then will return the right fd0, and the
    fd0 is master privilege;
    2. Call drmOpenByBusid to open Card1. In function drmOpenByBusid, it will
    open Card0 first, this time, the fd1 for opening Card0 is not master
    privilege, and will call drmSetInterfaceVersion to identify the
    domain ID feature, as the fd1 is not master privilege, then drmSetInterfaceVersion
    will fail, and then won't compare domain ID, then return the wrong fd for Card1.
    
    Solution:
    First loop search the best match fd about drm 1.4.
    
    Reviewed-by: Alex Deucher <[email protected]>
    Signed-off-by: Emily Deng <[email protected]>
    Signed-off-by: Alex Deucher <[email protected]>

diff --git a/xf86drm.c b/xf86drm.c
index d006bb38..cbae3e28 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -586,11 +586,34 @@ static int drmOpenByBusid(const char *busid, int type)
     if (base < 0)
         return -1;
 
+    /* We need to try for 1.4 first for proper PCI domain support */
     drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
     for (i = base; i < base + DRM_MAX_MINOR; i++) {
         fd = drmOpenMinor(i, 1, type);
         drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
         if (fd >= 0) {
+            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 */
+            if (!drmSetInterfaceVersion(fd, &sv)) {
+                buf = drmGetBusid(fd);
+                drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);
+                if (buf && drmMatchBusID(buf, busid, 1)) {
+                    drmFreeBusid(buf);
+                    return fd;
+                }
+                if (buf)
+                    drmFreeBusid(buf);
+            }
+            close(fd);
+        }
+    }
+
+   for (i = base; i < base + DRM_MAX_MINOR; i++) {
+        fd = drmOpenMinor(i, 1, type);
+        drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
+        if (fd >= 0) {
             /* We need to try for 1.4 first for proper PCI domain support
              * and if that fails, we know the kernel is busted
              */


--