From 048674a6aeb61149a1b5f6b0bc3762ddf57f38ee Mon Sep 17 00:00:00 2001 From: Adam Jackson 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. Reviewed-by: Alex Deucher Reviewed-by: Simon Farnsworth Signed-off-by: Adam Jackson --- hw/xfree86/os-support/linux/lnx_video.c | 82 +++++++++++++++---------- 1 file 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 3526a21d4..895a79bbd 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__) From d88fb00d791c2b19cf9dd244276838aba3a6b442 Mon Sep 17 00:00:00 2001 From: Adam Jackson 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. Reviewed-by: Alex Deucher Reviewed-by: Simon Farnsworth Signed-off-by: Adam Jackson --- hw/xfree86/os-support/linux/lnx_video.c | 7 ++----- 1 file 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 895a79bbd..d9a5da184 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__) From 245e7e0361b18766583ae391a2ac1231bb1a1f84 Mon Sep 17 00:00:00 2001 From: Adam Jackson 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. v2: Move initial xf86EnableIO() nearer the logic that determines whether to call it, suggested by Simon Farnsworth. Reviewed-by: Alex Deucher Reviewed-by: Simon Farnsworth Signed-off-by: Adam Jackson --- hw/xfree86/common/xf86.h | 1 + hw/xfree86/common/xf86Bus.c | 15 --------------- hw/xfree86/common/xf86Configure.c | 27 +-------------------------- hw/xfree86/common/xf86Init.c | 27 +++++++++++++++------------ hw/xfree86/common/xf86Priv.h | 1 - 5 files changed, 17 insertions(+), 54 deletions(-) diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index bb2903da0..179b87cf5 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 6de8409fc..3c8ae69a3 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c @@ -115,27 +115,12 @@ xf86BusConfig(void) screenLayoutPtr layout; int i, j; - /* Enable full I/O access */ - if (xorgHWAccess) - xorgHWAccess = xf86EnableIO(); - /* * Now call each of the Probe functions. Each successful probe will * result in an extra entry added to the xf86Screens[] list for each * 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 6f69117d3..6c5e35919 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 e4a6b8613..1695dbf74 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -402,6 +402,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) Bool pix24Fail = FALSE; Bool autoconfig = FALSE; Bool sigio_blocked = FALSE; + Bool want_hw_access = FALSE; GDevPtr configured_device; xf86Initialising = TRUE; @@ -530,23 +531,21 @@ 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; + if (NEED_IO_ENABLED(flags)) + want_hw_access = TRUE; - if (NEED_IO_ENABLED(flags)) - xorgHWAccess = TRUE; - if (!(flags & HW_SKIP_CONSOLE)) - xorgHWOpenConsole = TRUE; - } + if (!(flags & HW_SKIP_CONSOLE)) + xorgHWOpenConsole = TRUE; } if (xorgHWOpenConsole) @@ -554,6 +553,10 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) else xf86Info.dontVTSwitch = TRUE; + /* Enable full I/O access */ + if (want_hw_access) + xorgHWAccess = xf86EnableIO(); + if (xf86BusConfig() == FALSE) return; diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index c9f2e7eb8..58cfe0a1a 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;