]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
pcie: fix link active status bit migration
authorMichael S. Tsirkin <mst@redhat.com>
Tue, 19 Jul 2016 20:16:19 +0000 (23:16 +0300)
committerMichael Roth <mdroth@linux.vnet.ibm.com>
Fri, 5 Aug 2016 21:45:19 +0000 (16:45 -0500)
We changed link status register in pci express endpoint capability
over time. Specifically,

commit b2101eae63ea57b571cee4a9075a4287d24ba4a4 ("pcie: Set the "link
active" in the link status register") set data link layer link active
bit in this register without adding compatibility to old machine types.

When migrating from qemu 2.3 and older this affects xhci devices which
under machine type 2.0 and older have a pci express endpoint capability
even if they are on a pci bus.

Add compatibility flags to make this bit value match what it was under
2.3.

Additionally, to avoid breaking migration from qemu 2.3 and up,
suppress checking link status during migration: this seems sane
since hardware can change link status at any time.

https://bugzilla.redhat.com/show_bug.cgi?id=1352860

Reported-by: Gerd Hoffmann <kraxel@redhat.com>
Fixes: b2101eae63ea57b571cee4a9075a4287d24ba4a4
    ("pcie: Set the "link active" in the link status register")
Cc: qemu-stable@nongnu.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 6b4495401bdf442457b713b7e3994b465c55af35)
Conflicts:
hw/pci/pcie.c

* removed functional dependency on 6383292

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
hw/pci/pci.c
hw/pci/pcie.c
include/hw/compat.h
include/hw/pci/pci.h

index bb605efae0236b506e0dc044879deca87147cdf6..616f04c1f226cd3286627273fde0ef4c0867bfde 100644 (file)
@@ -62,6 +62,8 @@ static Property pci_props[] = {
                     QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false),
     DEFINE_PROP_BIT("command_serr_enable", PCIDevice, cap_present,
                     QEMU_PCI_CAP_SERR_BITNR, true),
+    DEFINE_PROP_BIT("x-pcie-lnksta-dllla", PCIDevice, cap_present,
+                    QEMU_PCIE_LNKSTA_DLLLA_BITNR, true),
     DEFINE_PROP_END_OF_LIST()
 };
 
index 728386ada71392bc25403ecbc152fd7ee6737df7..c85b4f7ae5a993cdfd88761cc66bf6466bc32aaa 100644 (file)
@@ -47,6 +47,7 @@ int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port)
 {
     int pos;
     uint8_t *exp_cap;
+    uint8_t *cmask;
 
     assert(pci_is_express(dev));
 
@@ -57,6 +58,7 @@ int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port)
     }
     dev->exp.exp_cap = pos;
     exp_cap = dev->config + pos;
+    cmask = dev->cmask + pos;
 
     /* capability register
        interrupt message number defaults to 0 */
@@ -80,7 +82,18 @@ int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port)
                  PCI_EXP_LNK_LS_25);
 
     pci_set_word(exp_cap + PCI_EXP_LNKSTA,
-                 PCI_EXP_LNK_MLW_1 | PCI_EXP_LNK_LS_25 |PCI_EXP_LNKSTA_DLLLA);
+                 PCI_EXP_LNK_MLW_1 | PCI_EXP_LNK_LS_25);
+
+    if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) {
+        pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
+                                   PCI_EXP_LNKSTA_DLLLA);
+    }
+
+    /* We changed link status bits over time, and changing them across
+     * migrations is generally fine as hardware changes them too.
+     * Let's not bother checking.
+     */
+    pci_set_word(cmask + PCI_EXP_LNKSTA, 0);
 
     pci_set_long(exp_cap + PCI_EXP_DEVCAP2,
                  PCI_EXP_DEVCAP2_EFF | PCI_EXP_DEVCAP2_EETLPP);
index a5dbbf8984b1dd1ecf184e286f45ddd9d9e592d5..81fc19b96a4cd250871b9833e7f7fcd95623a0f2 100644 (file)
         .driver   = "virtio-rng-pci",\
         .property = "any_layout",\
         .value    = "off",\
+    },{\
+        .driver   = TYPE_PCI_DEVICE,\
+        .property = "x-pcie-lnksta-dllla",\
+        .value    = "off",\
     },
 
 #define HW_COMPAT_2_2 \
index ef6ba51f6c6850df5c6dafa0fff3faa98e684fde..e7f2df5b7ab9058ec865af8bf194dc97f13fafe3 100644 (file)
@@ -173,6 +173,9 @@ enum {
     /* PCI Express capability - Power Controller Present */
 #define QEMU_PCIE_SLTCAP_PCP_BITNR 7
     QEMU_PCIE_SLTCAP_PCP = (1 << QEMU_PCIE_SLTCAP_PCP_BITNR),
+    /* Link active status in endpoint capability is always set */
+#define QEMU_PCIE_LNKSTA_DLLLA_BITNR 8
+    QEMU_PCIE_LNKSTA_DLLLA = (1 << QEMU_PCIE_LNKSTA_DLLLA_BITNR),
 };
 
 #define TYPE_PCI_DEVICE "pci-device"