Hi, On 30-09-16 10:28, Hans de Goede wrote:
Hi,
<snip>
Xorg when running without a Xorg.conf searches for what it considers a "primary" gpu / video-card, basically it attempts to bring up the right card in setups where there are multiple cards and if it does not find one exits with an error. The xserver has a 2 step process for finding the primary card: 1) It searches for is a card which has a vga-bios mapped, as we've already determined in the mentioned Red Hat bug that works for the classic qemu emulated video-cards, but not for qemu's virtio-vga. 2) If that does not work Xorg will fallback to any video class device on pci-bus 1. This fallback actually has been broken in the Xorg xserver for quite a while now and only 2 days ago a patch from Laszlo was merged to fix this. Only for things to break again due to this kernel patch. Since the whole step 2) thingie is very much tied to x86 machines where pci-bus 0 used to be the main bus and pci-bus 1 the agp, which is sorta an obsolete assumption now a days and since relying on bus numbers / enumeration order is a bad idea in general I'm not entirely sure if this counts as a regression. I've discussed the problem of the xserver exiting with an error when no primary device can be found with some people (ajax) at XDC last week since there are other use-cases where the pci-bus 1 fallback does not work. As such I've been working on a xserver patch-set to make the xserver try harder (pick the first available device) when both steps described above fail to find one, which should make things work even with the newest (broken / regressed) kernels. Given this mail thread, I guess I'm working after all today (I had planned a day off) and I'll try to wrap up this patch-set and reply to this mail with the server patches attached for Joachim and/or Laszlo to test.
Attached are 2 patches against the xserver which should fix this, please give them a try. Regards, Hans
>From 8499d06529c3f95cf94a6d4429e18d48052c2689 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@xxxxxxxxxx> Date: Fri, 30 Sep 2016 11:59:04 +0200 Subject: [PATCH 1/2] xfree86: Make adding unclaimed devices as GPU devices a separate step This is primarily a preparation patch for fixing the xserver exiting with a "no screens found" error even though there are supported video cards, due to the server not recognizing any card as the primary card. This also fixes the (mostly theoretical) case of a platformBus capable driver adding a device as GPUscreen before a driver which only supports the old PCI probe method gets a chance to claim it as a normal screen. Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> --- hw/xfree86/common/xf86Bus.c | 4 ++++ hw/xfree86/common/xf86platformBus.c | 15 +++++++++++++++ hw/xfree86/common/xf86platformBus.h | 6 ++++++ 3 files changed, 25 insertions(+) diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c index 27c6b1b..a3a9898 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c @@ -125,6 +125,10 @@ xf86BusConfig(void) xf86CallDriverProbe(xf86DriverList[i], FALSE); } + for (i = 0; i < xf86NumDrivers; i++) { + xf86platformAddGPUDevices(xf86DriverList[i]); + } + /* If nothing was detected, return now */ if (xf86NumScreens == 0) { xf86Msg(X_ERROR, "No devices detected.\n"); diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c index 3e2264f..ec2a1dd 100644 --- a/hw/xfree86/common/xf86platformBus.c +++ b/hw/xfree86/common/xf86platformBus.c @@ -476,6 +476,21 @@ xf86platformProbeDev(DriverPtr drvp) isGPUDevice(devList[i]) ? PLATFORM_PROBE_GPU_SCREEN : 0); } + return foundScreen; +} + +int +xf86platformAddGPUDevices(DriverPtr drvp) +{ + Bool foundScreen = FALSE; + GDevPtr *devList; + int j; + + if (!drvp->platformProbe) + return FALSE; + + xf86MatchDevice(drvp->driverName, &devList); + /* if autoaddgpu devices is enabled then go find any unclaimed platform * devices and add them as GPU screens */ if (xf86Info.autoAddGPU) { diff --git a/hw/xfree86/common/xf86platformBus.h b/hw/xfree86/common/xf86platformBus.h index a7335b9..0f5c0ef 100644 --- a/hw/xfree86/common/xf86platformBus.h +++ b/hw/xfree86/common/xf86platformBus.h @@ -41,6 +41,7 @@ struct xf86_platform_device { #ifdef XSERVER_PLATFORM_BUS int xf86platformProbe(void); int xf86platformProbeDev(DriverPtr drvp); +int xf86platformAddGPUDevices(DriverPtr drvp); extern int xf86_num_platform_devices; extern struct xf86_platform_device *xf86_platform_devices; @@ -156,6 +157,11 @@ xf86PlatformMatchDriver(char *matches[], int nmatches); extern void xf86platformVTProbe(void); extern void xf86platformPrimary(void); + +#else + +static inline int xf86platformAddGPUDevices(DriverPtr drvp) { return FALSE; } + #endif #endif -- 2.9.3
>From 3241fcf1636e1b1cb8e0fdd698a2d2e00d1bbcc0 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@xxxxxxxxxx> Date: Fri, 30 Sep 2016 12:29:09 +0200 Subject: [PATCH 2/2] xfree86: Try harder to find atleast 1 non GPU Screen If we did not find any non GPU Screens, try again ignoring the notion of any video devices being the primary device. This fixes Xorg exiting with a "no screens found" error when using virtio-vga in a virtual-machine and when using a device driven by simpledrm. This is a somewhat ugly solution, but it is the best I can come up with without major surgery to the bus and probe code. Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> --- hw/xfree86/common/xf86.h | 1 + hw/xfree86/common/xf86Bus.c | 26 +++++++++++++++++++++++--- hw/xfree86/common/xf86Globals.c | 1 + hw/xfree86/common/xf86pciBus.c | 4 ++++ hw/xfree86/common/xf86platformBus.c | 4 ++++ 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index e54c811..f724688 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 xf86ProbeIgnorePrimary; 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 a3a9898..9836803 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c @@ -117,14 +117,34 @@ xf86BusConfig(void) int i, j; /* - * 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. + * 3 step probe to (hopefully) ensure that we always find at least 1 + * (non GPU) screen: + * + * 1. Call each drivers probe function normally, + * 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++) { xf86CallDriverProbe(xf86DriverList[i], FALSE); } + /* + * 2. If no Screens were found, call each drivers probe function with + * ignorePrimary = TRUE, to ensure that we do actually get a + * Screen if there is atleast one supported video card. + */ + if (xf86NumScreens == 0) { + xf86ProbeIgnorePrimary = TRUE; + for (i = 0; i < xf86NumDrivers && xf86NumScreens == 0; i++) { + xf86CallDriverProbe(xf86DriverList[i], FALSE); + } + xf86ProbeIgnorePrimary = FALSE; + } + + /* + * 3. Call xf86platformAddGPUDevices() to add any additional video cards as + * GPUScreens (GPUScreens are only supported by platformBus drivers). + */ for (i = 0; i < xf86NumDrivers; i++) { xf86platformAddGPUDevices(xf86DriverList[i]); } diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c index 072c3fc..0d1e31b 100644 --- a/hw/xfree86/common/xf86Globals.c +++ b/hw/xfree86/common/xf86Globals.c @@ -153,6 +153,7 @@ XF86ConfigPtr xf86configptr = NULL; Bool xf86Resetting = FALSE; Bool xf86Initialising = FALSE; Bool xf86DoConfigure = FALSE; +Bool xf86ProbeIgnorePrimary = FALSE; Bool xf86DoShowOptions = FALSE; DriverPtr *xf86DriverList = NULL; int xf86NumDrivers = 0; diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index 8158c2b..9adfee5 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -352,6 +352,10 @@ xf86ComparePciBusString(const char *busID, int bus, int device, int func) Bool xf86IsPrimaryPci(struct pci_device *pPci) { + /* Add max. 1 screen for the IgnorePrimary fallback path */ + if (xf86ProbeIgnorePrimary && xf86NumScreens == 0) + return TRUE; + if (primaryBus.type == BUS_PCI) return pPci == primaryBus.id.pci; #ifdef XSERVER_PLATFORM_BUS diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c index ec2a1dd..fde6796 100644 --- a/hw/xfree86/common/xf86platformBus.c +++ b/hw/xfree86/common/xf86platformBus.c @@ -115,6 +115,10 @@ xf86_find_platform_device_by_devnum(int major, int minor) static Bool xf86IsPrimaryPlatform(struct xf86_platform_device *plat) { + /* Add max. 1 screen for the IgnorePrimary fallback path */ + if (xf86ProbeIgnorePrimary && xf86NumScreens == 0) + return TRUE; + if (primaryBus.type == BUS_PLATFORM) return plat == primaryBus.id.plat; #ifdef XSERVER_LIBPCIACCESS -- 2.9.3
_______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel