[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