From 17ab5dbea69e690cbf78c25040db518471e0887f Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Fri, 16 Apr 2010 10:19:19 -0700 Subject: Refuse to bind to a device which has kernel modesetting active. Touching directly the hardware while kernel modesetting is active breaks console output. Patch almost entrirely based on VESA patch by Christopher James Halse Rogers Signed-off-by: Marcin Slusarz Tested-by: Aaron Plattner Reviewed-by: Aaron Plattner --- configure.ac | 11 +++++++++++ src/Makefile.am | 2 +- src/nv_driver.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d717805..c51ab4a 100644 --- a/configure.ac +++ b/configure.ac @@ -134,6 +134,17 @@ AC_SUBST([modes_dir]) AC_SUBST([XORG_CFLAGS]) AC_SUBST([moduledir]) +if test "x$XSERVER_LIBPCIACCESS" = xyes; then + PKG_CHECK_MODULES(LIBDRM, [libdrm > 2.4.3 xf86driproto], HAVE_KMS="yes", HAVE_KMS="no") + if test "x$HAVE_KMS" = xyes; then + AC_DEFINE(HAVE_KMS, 1, [Have kernel modesetting]) + else + AC_MSG_WARN(Support for detecting kernel modesetting drivers is not available.) + AC_MSG_WARN(This driver can cause display problems in the presence of kernel modesetting.) + AC_MSG_WARN(Please install libdrm > 2.4.3 and xf86driproto to enable KMS detection.) + fi +fi + DRIVER_NAME=nv AC_SUBST([DRIVER_NAME]) diff --git a/src/Makefile.am b/src/Makefile.am index 2677d9c..5d57010 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,7 +23,7 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @XMODES_CFLAGS@ @XORG_CFLAGS@ +AM_CFLAGS = @XMODES_CFLAGS@ @XORG_CFLAGS@ $(LIBDRM_CFLAGS) nv_drv_la_LTLIBRARIES = nv_drv.la nv_drv_la_LDFLAGS = -module -avoid-version nv_drv_ladir = @moduledir@/drivers diff --git a/src/nv_driver.c b/src/nv_driver.c index 0d017f9..e10ae0c 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -33,6 +33,11 @@ #include "xf86int10.h" #include "vbeModes.h" +#ifdef HAVE_KMS +#include +#include +#endif + const OptionInfoRec * RivaAvailableOptions(int chipid, int busid); Bool RivaGetScrnInfoRec(PciChipsets *chips, int chip); Bool G80GetScrnInfoRec(PciChipsets *chips, int chip); @@ -830,6 +835,26 @@ NVIsSupported(CARD32 id) return FALSE; } +#ifdef HAVE_KMS +static Bool NVKernelModesettingEnabled(struct pci_device *device) +{ + char *busIdString; + int ret; + + if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) + return FALSE; + + busIdString = DRICreatePCIBusID(device); + + ret = drmCheckModesettingSupported(busIdString); + xfree(busIdString); + + return (ret == 0); +} +#else +static inline Bool NVKernelModesettingEnabled(struct pci_device *device) { return FALSE; } +#endif //HAVE_KMS + /* Mandatory */ #if XSERVER_LIBPCIACCESS static Bool @@ -864,6 +889,14 @@ NVPciProbe(DriverPtr drv, int entity, struct pci_device *dev, intptr_t data) NV_NAME ": Found NVIDIA %s at %2.2x@%2.2x:%2.2x:%1.1x\n", name, dev->bus, dev->domain, dev->dev, dev->func); + /* Trying to bring up a NV mode while kernel modesetting is enabled + results in badness */ + if (NVKernelModesettingEnabled(dev)) { + xf86Msg(X_ERROR, + NV_NAME ": Kernel modesetting driver in use, refusing to load\n"); + return FALSE; + } + if(NVIsG80(id)) return G80GetScrnInfoRec(NULL, entity); else if(dev->vendor_id == PCI_VENDOR_NVIDIA_SGS) -- cgit v1.2.3