[xorg-x11-server] Make failure to iopl non-fatal

Adam Jackson ajax at fedoraproject.org
Fri Aug 3 18:27:16 UTC 2012


commit a33d4439160653e147caeccacc9276cc4de3bf6c
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Aug 3 14:26:52 2012 -0400

    Make failure to iopl non-fatal

 0001-linux-Refactor-xf86-En-Dis-ableIO.patch       |  136 ++++++++++++++++
 0002-linux-Make-failure-to-iopl-non-fatal.patch    |   40 +++++
 ...nge-the-semantics-of-driverFunc-GET_REQUI.patch |  163 ++++++++++++++++++++
 xorg-x11-server.spec                               |    9 +-
 4 files changed, 347 insertions(+), 1 deletions(-)
---
diff --git a/0001-linux-Refactor-xf86-En-Dis-ableIO.patch b/0001-linux-Refactor-xf86-En-Dis-ableIO.patch
new file mode 100644
index 0000000..5523fad
--- /dev/null
+++ b/0001-linux-Refactor-xf86-En-Dis-ableIO.patch
@@ -0,0 +1,136 @@
+From c02d0e62ca9d073ddd13b4b7493ade16fbc15ade Mon Sep 17 00:00:00 2001
+From: Adam Jackson <ajax at redhat.com>
+Date: Tue, 26 Jun 2012 13:12:45 -0400
+Subject: [PATCH 1/3] linux: Refactor xf86{En,Dis}ableIO
+
+Pull platform methods into their own sections for legibility, and
+rewrite the ifdefs to be more concise.
+
+Signed-off-by: Adam Jackson <ajax at redhat.com>
+---
+ hw/xfree86/os-support/linux/lnx_video.c |   82 ++++++++++++++++++-------------
+ 1 files changed, 48 insertions(+), 34 deletions(-)
+
+diff --git a/hw/xfree86/os-support/linux/lnx_video.c b/hw/xfree86/os-support/linux/lnx_video.c
+index 3526a21..895a79b 100644
+--- a/hw/xfree86/os-support/linux/lnx_video.c
++++ b/hw/xfree86/os-support/linux/lnx_video.c
+@@ -479,39 +479,36 @@ volatile unsigned char *ioBase = NULL;
+ #define __NR_pciconfig_iobase	200
+ #endif
+ 
+-#endif
+-
+-Bool
+-xf86EnableIO(void)
++static Bool
++hwEnableIO(void)
+ {
+-#if defined(__powerpc__)
+     int fd;
+-    unsigned int ioBase_phys;
+-#endif
+-
+-    if (ExtendedEnabled)
+-        return TRUE;
+-
+-#if defined(__powerpc__)
+-    ioBase_phys = syscall(__NR_pciconfig_iobase, 2, 0, 0);
++    unsigned int ioBase_phys = syscall(__NR_pciconfig_iobase, 2, 0, 0);
+ 
+     fd = open("/dev/mem", O_RDWR);
+     if (ioBase == NULL) {
+         ioBase = (volatile unsigned char *) mmap(0, 0x20000,
+                                                  PROT_READ | PROT_WRITE,
+                                                  MAP_SHARED, fd, ioBase_phys);
+-/* Should this be fatal or just a warning? */
+-#if 0
+-        if (ioBase == MAP_FAILED) {
+-            xf86Msg(X_WARNING,
+-                    "xf86EnableIOPorts: Failed to map iobase (%s)\n",
+-                    strerror(errno));
+-            return FALSE;
+-        }
+-#endif
+     }
+     close(fd);
+-#elif !defined(__mc68000__) && !defined(__sparc__) && !defined(__mips__) && !defined(__sh__) && !defined(__hppa__) && !defined(__s390__) && !defined(__arm__) && !defined(__m32r__) && !defined(__nds32__)
++
++    return ioBase != MAP_FAILED;
++}
++
++static void
++hwDisableIO(void)
++{
++    munmap(ioBase, 0x20000);
++    ioBase = NULL;
++}
++
++#elif defined(__i386__) || defined(__x86_64__) || defined(__ia64__) || \
++      defined(__alpha__)
++
++static Bool
++hwEnableIO(void)
++{
+     if (ioperm(0, 1024, 1) || iopl(3)) {
+         if (errno == ENODEV)
+             ErrorF("xf86EnableIOPorts: no I/O ports found\n");
+@@ -526,27 +523,44 @@ xf86EnableIO(void)
+     ioperm(0x40, 4, 0);         /* trap access to the timer chip */
+     ioperm(0x60, 4, 0);         /* trap access to the keyboard controller */
+ #endif
+-#endif
+-    ExtendedEnabled = TRUE;
+ 
+     return TRUE;
+ }
+ 
++static void
++hwDisableIO(void)
++{
++    iopl(0);
++    ioperm(0, 1024, 0);
++}
++
++#else /* non-IO architectures */
++
++#define hwEnableIO() TRUE
++#define hwDisableIO() do {} while (0)
++
++#endif
++
++Bool
++xf86EnableIO(void)
++{
++    if (ExtendedEnabled)
++        return TRUE;
++
++    ExtendedEnabled = hwEnableIO();
++
++    return ExtendedEnabled;
++}
++
+ void
+ xf86DisableIO(void)
+ {
+     if (!ExtendedEnabled)
+         return;
+-#if defined(__powerpc__)
+-    munmap(ioBase, 0x20000);
+-    ioBase = NULL;
+-#elif !defined(__mc68000__) && !defined(__sparc__) && !defined(__mips__) && !defined(__sh__) && !defined(__hppa__) && !defined(__arm__) && !defined(__s390__) && !defined(__m32r__) && !defined(__nds32__)
+-    iopl(0);
+-    ioperm(0, 1024, 0);
+-#endif
+-    ExtendedEnabled = FALSE;
+ 
+-    return;
++    hwDisableIO();
++
++    ExtendedEnabled = FALSE;
+ }
+ 
+ #if defined (__alpha__)
+-- 
+1.7.7.6
+
diff --git a/0002-linux-Make-failure-to-iopl-non-fatal.patch b/0002-linux-Make-failure-to-iopl-non-fatal.patch
new file mode 100644
index 0000000..f0fd50f
--- /dev/null
+++ b/0002-linux-Make-failure-to-iopl-non-fatal.patch
@@ -0,0 +1,40 @@
+From e47530e266b8e7f84004978e9fd247b5e6df0fb7 Mon Sep 17 00:00:00 2001
+From: Adam Jackson <ajax at redhat.com>
+Date: Tue, 26 Jun 2012 13:15:45 -0400
+Subject: [PATCH 2/3] linux: Make failure to iopl non-fatal
+
+We load the driver list, then enable I/O, then call driver probe based
+on whether I/O enable succeeded.  That's bad, because the loaded
+security policy might forbid port access.  We happen to treat that as
+fatal for some reason, which means even drivers that don't need I/O
+access (like kms and fbdev) don't get the chance to run.  Facepalm.
+
+How about we just make that non-fatal instead, that sounds like a much
+better plan.
+
+Signed-off-by: Adam Jackson <ajax at redhat.com>
+---
+ hw/xfree86/os-support/linux/lnx_video.c |    7 ++-----
+ 1 files changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/hw/xfree86/os-support/linux/lnx_video.c b/hw/xfree86/os-support/linux/lnx_video.c
+index 895a79b..d9a5da1 100644
+--- a/hw/xfree86/os-support/linux/lnx_video.c
++++ b/hw/xfree86/os-support/linux/lnx_video.c
+@@ -510,11 +510,8 @@ static Bool
+ hwEnableIO(void)
+ {
+     if (ioperm(0, 1024, 1) || iopl(3)) {
+-        if (errno == ENODEV)
+-            ErrorF("xf86EnableIOPorts: no I/O ports found\n");
+-        else
+-            FatalError("xf86EnableIOPorts: failed to set IOPL"
+-                       " for I/O (%s)\n", strerror(errno));
++        ErrorF("xf86EnableIOPorts: failed to set IOPL for I/O (%s)\n",
++               strerror(errno));
+         return FALSE;
+     }
+ #if !defined(__alpha__)
+-- 
+1.7.7.6
+
diff --git a/0003-xfree86-Change-the-semantics-of-driverFunc-GET_REQUI.patch b/0003-xfree86-Change-the-semantics-of-driverFunc-GET_REQUI.patch
new file mode 100644
index 0000000..8f3b92f
--- /dev/null
+++ b/0003-xfree86-Change-the-semantics-of-driverFunc-GET_REQUI.patch
@@ -0,0 +1,163 @@
+From d9ea0f90f87c3cf2d8382a1e8a6ae30e58a419b3 Mon Sep 17 00:00:00 2001
+From: Adam Jackson <ajax at redhat.com>
+Date: Tue, 26 Jun 2012 14:32:31 -0400
+Subject: [PATCH 3/3] xfree86: Change the semantics of
+ driverFunc(GET_REQUIRED_HW_INTERFACES)
+
+This is a really awkward interface, since we're calling it well before
+the driver knows what device it's going to drive.  Drivers with both KMS
+and UMS support therefore don't know whether to say they need I/O port
+access or not, and have to assume they do.
+
+With this change we now call it only to query whether port access might
+be needed; we don't use that to determine whether to call a driver's
+probe function or not, instead we call them unconditionally.  If the
+driver doesn't check whether port access was enabled, they might crash
+ungracefully.  To accomodate this, we move xorgHWAccess to be explicitly
+intentionally exported (sigh xf86Priv.h) so that drivers can check that
+before they attempt port access.
+
+Signed-off-by: Adam Jackson <ajax at redhat.com>
+---
+ hw/xfree86/common/xf86.h          |    1 +
+ hw/xfree86/common/xf86Bus.c       |   11 -----------
+ hw/xfree86/common/xf86Configure.c |   27 +--------------------------
+ hw/xfree86/common/xf86Init.c      |   23 +++++++++++------------
+ hw/xfree86/common/xf86Priv.h      |    1 -
+ 5 files changed, 13 insertions(+), 50 deletions(-)
+
+diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
+index 129660d..913f206 100644
+--- a/hw/xfree86/common/xf86.h
++++ b/hw/xfree86/common/xf86.h
+@@ -55,6 +55,7 @@
+ extern _X_EXPORT int xf86DoConfigure;
+ extern _X_EXPORT int xf86DoShowOptions;
+ extern _X_EXPORT Bool xf86DoConfigurePass1;
++extern _X_EXPORT Bool xorgHWAccess;
+ 
+ extern _X_EXPORT DevPrivateKeyRec xf86ScreenKeyRec;
+ 
+diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
+index 6c86f5e..4ea88aa 100644
+--- a/hw/xfree86/common/xf86Bus.c
++++ b/hw/xfree86/common/xf86Bus.c
+@@ -119,17 +119,6 @@ xf86BusConfig(void)
+      * instance of the hardware found.
+      */
+     for (i = 0; i < xf86NumDrivers; i++) {
+-        xorgHWFlags flags;
+-
+-        if (!xorgHWAccess) {
+-            if (!xf86DriverList[i]->driverFunc
+-                || !xf86DriverList[i]->driverFunc(NULL,
+-                                                  GET_REQUIRED_HW_INTERFACES,
+-                                                  &flags)
+-                || NEED_IO_ENABLED(flags))
+-                continue;
+-        }
+-
+         xf86CallDriverProbe(xf86DriverList[i], FALSE);
+     }
+ 
+diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c
+index 6f69117..6c5e359 100644
+--- a/hw/xfree86/common/xf86Configure.c
++++ b/hw/xfree86/common/xf86Configure.c
+@@ -545,41 +545,16 @@ DoConfigure(void)
+ 
+     free(vlist);
+ 
+-    for (i = 0; i < xf86NumDrivers; i++) {
+-        xorgHWFlags flags;
+-
+-        if (!xf86DriverList[i]->driverFunc
+-            || !xf86DriverList[i]->driverFunc(NULL,
+-                                              GET_REQUIRED_HW_INTERFACES,
+-                                              &flags)
+-            || NEED_IO_ENABLED(flags)) {
+-            xorgHWAccess = TRUE;
+-            break;
+-        }
+-    }
+-    /* Enable full I/O access */
+-    if (xorgHWAccess) {
+-        if (!xf86EnableIO())
+-            /* oops, we have failed */
+-            xorgHWAccess = FALSE;
+-    }
++    xorgHWAccess = xf86EnableIO();
+ 
+     /* Create XF86Config file structure */
+     xf86config = calloc(1, sizeof(XF86ConfigRec));
+ 
+     /* Call all of the probe functions, reporting the results. */
+     for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) {
+-        xorgHWFlags flags;
+         Bool found_screen;
+         DriverRec *const drv = xf86DriverList[CurrentDriver];
+ 
+-        if (!xorgHWAccess) {
+-            if (!drv->driverFunc
+-                || !drv->driverFunc(NULL, GET_REQUIRED_HW_INTERFACES, &flags)
+-                || NEED_IO_ENABLED(flags))
+-                continue;
+-        }
+-
+         found_screen = xf86CallDriverProbe(drv, TRUE);
+         if (found_screen && drv->Identify) {
+             (*drv->Identify) (0);
+diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
+index ca6efd4..581579e 100644
+--- a/hw/xfree86/common/xf86Init.c
++++ b/hw/xfree86/common/xf86Init.c
+@@ -527,23 +527,22 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
+          */
+ 
+         for (i = 0; i < xf86NumDrivers; i++) {
++            xorgHWFlags flags = HW_IO;
++
+             if (xf86DriverList[i]->Identify != NULL)
+                 xf86DriverList[i]->Identify(0);
+ 
+-            if (!xorgHWAccess || !xorgHWOpenConsole) {
+-                xorgHWFlags flags;
++            if (xf86DriverList[i]->driverFunc)
++                xf86DriverList[i]->driverFunc(NULL,
++                                              GET_REQUIRED_HW_INTERFACES,
++                                              &flags);
+ 
+-                if (!xf86DriverList[i]->driverFunc
+-                    || !xf86DriverList[i]->driverFunc(NULL,
+-                                                      GET_REQUIRED_HW_INTERFACES,
+-                                                      &flags))
+-                    flags = HW_IO;
++            /* this is "do we want it" at this point */
++            if (NEED_IO_ENABLED(flags))
++                xorgHWAccess = TRUE;
+ 
+-                if (NEED_IO_ENABLED(flags))
+-                    xorgHWAccess = TRUE;
+-                if (!(flags & HW_SKIP_CONSOLE))
+-                    xorgHWOpenConsole = TRUE;
+-            }
++            if (!(flags & HW_SKIP_CONSOLE))
++                xorgHWOpenConsole = TRUE;
+         }
+ 
+         if (xorgHWOpenConsole)
+diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
+index 42a3b30..aeca2a9 100644
+--- a/hw/xfree86/common/xf86Priv.h
++++ b/hw/xfree86/common/xf86Priv.h
+@@ -91,7 +91,6 @@ extern _X_EXPORT int xf86NumScreens;
+ extern _X_EXPORT const char *xf86VisualNames[];
+ extern _X_EXPORT int xf86Verbose;       /* verbosity level */
+ extern _X_EXPORT int xf86LogVerbose;    /* log file verbosity level */
+-extern _X_EXPORT Bool xorgHWAccess;
+ 
+ extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable;
+ 
+-- 
+1.7.7.6
+
diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec
index 320ee22..35ae2ff 100644
--- a/xorg-x11-server.spec
+++ b/xorg-x11-server.spec
@@ -43,7 +43,7 @@
 Summary:   X.Org X11 X server
 Name:      xorg-x11-server
 Version:   1.12.99.903
-Release:   5%{?gitdate:.%{gitdate}}%{dist}
+Release:   6%{?gitdate:.%{gitdate}}%{dist}
 URL:       http://www.x.org
 License:   MIT
 Group:     User Interface/X
@@ -97,6 +97,10 @@ Patch7020: xserver-1.12-xkb-fill-in-keycode-and-event-type-for-slow-keys-ena.pat
 
 Patch7021: xserver-1.12.99-glx-fix.patch
 
+Patch7022: 0001-linux-Refactor-xf86-En-Dis-ableIO.patch
+Patch7023: 0002-linux-Make-failure-to-iopl-non-fatal.patch
+Patch7024: 0003-xfree86-Change-the-semantics-of-driverFunc-GET_REQUI.patch
+
 %define moduledir	%{_libdir}/xorg/modules
 %define drimoduledir	%{_libdir}/dri
 %define sdkdir		%{_includedir}/xorg
@@ -569,6 +573,9 @@ rm -rf $RPM_BUILD_ROOT
 %{xserver_source_dir}
 
 %changelog
+* Fri Aug 03 2012 Adam Jackson <ajax at redhat.com> 1.12.99.903-6
+- Make failure to iopl non-fatal
+
 * Mon Jul 30 2012 Adam Jackson <ajax at redhat.com> 1.12.99.903-5
 - No need to --disable-xaa explicitly anymore.
 


More information about the scm-commits mailing list