From e85ee5f0196b85ad6f9faa02571325831b612c37 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Thu, 7 Jan 2021 14:12:25 -0500 Subject: usb/hcd-xhci-pci: Fixup capabilities ordering (again) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Dr. David Alan Gilbert Message-id: <20210107141225.19709-2-dgilbert@redhat.com> Patchwork-id: 100518 O-Subject: [RHEL-AV-8.4.0 qemu-kvm PATCH 1/1] usb/hcd-xhci-pci: Fixup capabilities ordering (again) Bugzilla: 1912846 RH-Acked-by: Philippe Mathieu-Daudé RH-Acked-by: Laszlo Ersek RH-Acked-by: Gerd Hoffmann From: "Dr. David Alan Gilbert" Allow the reordering of the PCIe capabilities for MSI around the PCIe capability. This changed incompatibly way back in QEMU 2.7 and in RHEL we fixed it up in bz 1447874 unconditionally putting it back. The xhci code got reorganised between 5.0 and 5.2; and we lost this fixup on rebase. This time, add it as a property, and enable the property for old machine types; this will allow us to drop this patch once the old machine types go. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Danilo C. L. de Paula --- hw/core/machine.c | 4 ++- hw/usb/hcd-xhci-pci.c | 59 +++++++++++++++++++++++++++++++++---------- hw/usb/hcd-xhci-pci.h | 1 + 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index aba05ad676..68495b9411 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -29,7 +29,7 @@ #include "migration/vmstate.h" /* - * The same as hw_compat_5_1 + * Mostly the same as hw_compat_5_1 */ GlobalProperty hw_compat_rhel_8_3[] = { /* hw_compat_rhel_8_3 from hw_compat_5_1 */ @@ -46,6 +46,8 @@ GlobalProperty hw_compat_rhel_8_3[] = { { "nvme", "use-intel-id", "on"}, /* hw_compat_rhel_8_3 from hw_compat_5_1 */ { "pvpanic", "events", "1"}, /* PVPANIC_PANICKED */ + /* hw_compat_rhel_8_3 bz 1912846 */ + { "pci-xhci", "x-rh-late-msi-cap", "off" }, }; const size_t hw_compat_rhel_8_3_len = G_N_ELEMENTS(hw_compat_rhel_8_3); diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c index bba628d3d2..d045a2a8be 100644 --- a/hw/usb/hcd-xhci-pci.c +++ b/hw/usb/hcd-xhci-pci.c @@ -101,6 +101,33 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id) return 0; } +/* RH bz 1912846 */ +static bool usb_xhci_pci_add_msi(struct PCIDevice *dev, Error **errp) +{ + int ret; + Error *err = NULL; + XHCIPciState *s = XHCI_PCI(dev); + + ret = msi_init(dev, 0x70, s->xhci.numintrs, true, false, &err); + /* + * Any error other than -ENOTSUP(board's MSI support is broken) + * is a programming error + */ + assert(!ret || ret == -ENOTSUP); + if (ret && s->msi == ON_OFF_AUTO_ON) { + /* Can't satisfy user's explicit msi=on request, fail */ + error_append_hint(&err, "You have to use msi=auto (default) or " + "msi=off with this machine type.\n"); + error_propagate(errp, err); + return true; + } + assert(!err || s->msi == ON_OFF_AUTO_AUTO); + /* With msi=auto, we fall back to MSI off silently */ + error_free(err); + + return false; +} + static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp) { int ret; @@ -124,23 +151,12 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp) s->xhci.nec_quirks = true; } - if (s->msi != ON_OFF_AUTO_OFF) { - ret = msi_init(dev, 0x70, s->xhci.numintrs, true, false, &err); - /* - * Any error other than -ENOTSUP(board's MSI support is broken) - * is a programming error - */ - assert(!ret || ret == -ENOTSUP); - if (ret && s->msi == ON_OFF_AUTO_ON) { - /* Can't satisfy user's explicit msi=on request, fail */ - error_append_hint(&err, "You have to use msi=auto (default) or " - "msi=off with this machine type.\n"); + if (s->msi != ON_OFF_AUTO_OFF && s->rh_late_msi_cap) { + /* This gives the behaviour from 5.2.0 onwards, lspci shows 90,a0,70 */ + if (usb_xhci_pci_add_msi(dev, &err)) { error_propagate(errp, err); return; } - assert(!err || s->msi == ON_OFF_AUTO_AUTO); - /* With msi=auto, we fall back to MSI off silently */ - error_free(err); } pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY | @@ -153,6 +169,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp) assert(ret > 0); } + /* RH bz 1912846 */ + if (s->msi != ON_OFF_AUTO_OFF && !s->rh_late_msi_cap) { + /* This gives the older RH machine behaviour, lspci shows 90,70,a0 */ + if (usb_xhci_pci_add_msi(dev, &err)) { + error_propagate(errp, err); + return; + } + } if (s->msix != ON_OFF_AUTO_OFF) { /* TODO check for errors, and should fail when msix=on */ msix_init(dev, s->xhci.numintrs, @@ -197,11 +221,18 @@ static void xhci_instance_init(Object *obj) qdev_alias_all_properties(DEVICE(&s->xhci), obj); } +static Property xhci_pci_properties[] = { + /* RH bz 1912846 */ + DEFINE_PROP_BOOL("x-rh-late-msi-cap", XHCIPciState, rh_late_msi_cap, true), + DEFINE_PROP_END_OF_LIST() +}; + static void xhci_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); + device_class_set_props(dc, xhci_pci_properties); dc->reset = xhci_pci_reset; dc->vmsd = &vmstate_xhci_pci; set_bit(DEVICE_CATEGORY_USB, dc->categories); diff --git a/hw/usb/hcd-xhci-pci.h b/hw/usb/hcd-xhci-pci.h index c193f79443..086a1feb1e 100644 --- a/hw/usb/hcd-xhci-pci.h +++ b/hw/usb/hcd-xhci-pci.h @@ -39,6 +39,7 @@ typedef struct XHCIPciState { XHCIState xhci; OnOffAuto msi; OnOffAuto msix; + bool rh_late_msi_cap; /* bz 1912846 */ } XHCIPciState; #endif -- 2.18.4