提交 a87cef82 编写于 作者: M Michael S. Tsirkin 提交者: Michael Roth

pcie: fix link active status bit migration

We changed link status register in pci express endpoint capability
over time. Specifically,

commit b2101eae ("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=1352860Reported-by: NGerd Hoffmann <kraxel@redhat.com>
Fixes: b2101eae
    ("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: NMichael S. Tsirkin <mst@redhat.com>

(cherry picked from commit 6b449540)
Conflicts:
	hw/pci/pcie.c

* removed functional dependency on 6383292aSigned-off-by: NMichael Roth <mdroth@linux.vnet.ibm.com>
上级 97b5a97f
......@@ -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()
};
......
......@@ -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);
......
......@@ -73,6 +73,10 @@
.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 \
......
......@@ -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"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册