From 2dd7402227e77d748a7375233ac9e7feab244bda Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Fri, 5 May 2017 19:06:14 +0200 Subject: usb-xhci: Fix PCI capability order RH-Author: Dr. David Alan Gilbert Message-id: <20170505190614.15987-2-dgilbert@redhat.com> Patchwork-id: 75038 O-Subject: [RHEL-7.4 qemu-kvm-rhev PATCH 1/1] usb-xhci: Fix PCI capability order Bugzilla: 1447874 RH-Acked-by: Laszlo Ersek RH-Acked-by: Michael S. Tsirkin RH-Acked-by: Gerd Hoffmann RH-Acked-by: Juan Quintela From: "Dr. David Alan Gilbert" Upstream commit 1108b2f8a9 in 2.7.0 changed the order of the PCI capability chain in the XHCI pci device in the case where the device has the PCIe endpoint capability (i.e. only older machine types, pc-i440fx-2.0 upstream, pc-i440fx-rhel7.0.0 apparently for us). Changing the order breaks migration compatibility; fixing this upstream would mean breaking the same case going from 2.7.0->current that currently works 2.7.0->2.9.0 - so upstream it's a choice of two breakages. Since we never released 2.7.0/2.8.0 we can fix this downstream. This reverts the order so that we create the capabilities in the order: PCIe MSI MSI-X The symptom is: qemu-kvm: get_pci_config_device: Bad config data: i=0x71 read: a0 device: 0 cmask: ff wmask: 0 w1cmask:0 qemu-kvm: Failed to load PCIDevice:config qemu-kvm: Failed to load xhci:parent_obj qemu-kvm: error while loading state for instance 0x0 of device '0000:00:0d.0/xhci' qemu-kvm: load of migration failed: Invalid argument Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Miroslav Rezanina -- Rebase notes (2.9.0): - Change in assert condition (upstream) (cherry picked from commit aad727a5ecde1ad4935eb8427604d4df5a1f1f35) --- hw/usb/hcd-xhci.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 10848db..53de805 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -3368,6 +3368,12 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp) xhci->max_pstreams_mask = 0; } + if (pci_bus_is_express(dev->bus) || + xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) { + ret = pcie_endpoint_cap_init(dev, 0xa0); + assert(ret > 0); + } + if (xhci->msi != ON_OFF_AUTO_OFF) { ret = msi_init(dev, 0x70, xhci->numintrs, true, false, &err); /* Any error other than -ENOTSUP(board's MSI support is broken) @@ -3416,12 +3422,6 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp) PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64, &xhci->mem); - if (pci_bus_is_express(dev->bus) || - xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) { - ret = pcie_endpoint_cap_init(dev, 0xa0); - assert(ret > 0); - } - if (xhci->msix != ON_OFF_AUTO_OFF) { /* TODO check for errors, and should fail when msix=on */ msix_init(dev, xhci->numintrs, -- 1.8.3.1