virtio-pci: compat page aligned ATS
Commit4c70875372
("pci: advertise a page aligned ATS") advertises the page aligned via ATS capability (RO) to unbrek recent Linux IOMMU drivers since 5.2. But it forgot the compat the capability which breaks the migration from old machine type: (qemu) qemu-kvm: get_pci_config_device: Bad config data: i=0x104 read: 0 device: 20 cmask: ff wmask: 0 w1cmask:0 This patch introduces a new parameter "x-ats-page-aligned" for virtio-pci device and turns it on for machine type which is newer than 5.1. Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Peter Xu <peterx@redhat.com> Cc: Dr. David Alan Gilbert <dgilbert@redhat.com> Cc: qemu-stable@nongnu.org Fixes:4c70875372
("pci: advertise a page aligned ATS") Signed-off-by: Jason Wang <jasowang@redhat.com> Message-Id: <20210406040330.11306-1-jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
90a66f4847
commit
d83f46d189
@ -53,6 +53,7 @@ GlobalProperty hw_compat_5_1[] = {
|
||||
{ "nvme", "use-intel-id", "on"},
|
||||
{ "pvpanic", "events", "1"}, /* PVPANIC_PANICKED */
|
||||
{ "pl011", "migrate-clk", "off" },
|
||||
{ "virtio-pci", "x-ats-page-aligned", "off"},
|
||||
};
|
||||
const size_t hw_compat_5_1_len = G_N_ELEMENTS(hw_compat_5_1);
|
||||
|
||||
|
@ -963,16 +963,18 @@ void pcie_dev_ser_num_init(PCIDevice *dev, uint16_t offset, uint64_t ser_num)
|
||||
pci_set_quad(dev->config + offset + pci_dsn_cap, ser_num);
|
||||
}
|
||||
|
||||
void pcie_ats_init(PCIDevice *dev, uint16_t offset)
|
||||
void pcie_ats_init(PCIDevice *dev, uint16_t offset, bool aligned)
|
||||
{
|
||||
pcie_add_capability(dev, PCI_EXT_CAP_ID_ATS, 0x1,
|
||||
offset, PCI_EXT_CAP_ATS_SIZEOF);
|
||||
|
||||
dev->exp.ats_cap = offset;
|
||||
|
||||
/* Invalidate Queue Depth 0, Page Aligned Request 1 */
|
||||
pci_set_word(dev->config + offset + PCI_ATS_CAP,
|
||||
PCI_ATS_CAP_PAGE_ALIGNED);
|
||||
/* Invalidate Queue Depth 0 */
|
||||
if (aligned) {
|
||||
pci_set_word(dev->config + offset + PCI_ATS_CAP,
|
||||
PCI_ATS_CAP_PAGE_ALIGNED);
|
||||
}
|
||||
/* STU 0, Disabled by default */
|
||||
pci_set_word(dev->config + offset + PCI_ATS_CTRL, 0);
|
||||
|
||||
|
@ -1856,7 +1856,8 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
|
||||
}
|
||||
|
||||
if (proxy->flags & VIRTIO_PCI_FLAG_ATS) {
|
||||
pcie_ats_init(pci_dev, last_pcie_cap_offset);
|
||||
pcie_ats_init(pci_dev, last_pcie_cap_offset,
|
||||
proxy->flags & VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED);
|
||||
last_pcie_cap_offset += PCI_EXT_CAP_ATS_SIZEOF;
|
||||
}
|
||||
|
||||
@ -1933,6 +1934,8 @@ static Property virtio_pci_properties[] = {
|
||||
ignore_backend_features, false),
|
||||
DEFINE_PROP_BIT("ats", VirtIOPCIProxy, flags,
|
||||
VIRTIO_PCI_FLAG_ATS_BIT, false),
|
||||
DEFINE_PROP_BIT("x-ats-page-aligned", VirtIOPCIProxy, flags,
|
||||
VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT, true),
|
||||
DEFINE_PROP_BIT("x-pcie-deverr-init", VirtIOPCIProxy, flags,
|
||||
VIRTIO_PCI_FLAG_INIT_DEVERR_BIT, true),
|
||||
DEFINE_PROP_BIT("x-pcie-lnkctl-init", VirtIOPCIProxy, flags,
|
||||
|
@ -42,6 +42,7 @@ enum {
|
||||
VIRTIO_PCI_FLAG_INIT_PM_BIT,
|
||||
VIRTIO_PCI_FLAG_INIT_FLR_BIT,
|
||||
VIRTIO_PCI_FLAG_AER_BIT,
|
||||
VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT,
|
||||
};
|
||||
|
||||
/* Need to activate work-arounds for buggy guests at vmstate load. */
|
||||
@ -84,6 +85,10 @@ enum {
|
||||
/* Advanced Error Reporting capability */
|
||||
#define VIRTIO_PCI_FLAG_AER (1 << VIRTIO_PCI_FLAG_AER_BIT)
|
||||
|
||||
/* Page Aligned Address space Translation Service */
|
||||
#define VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED \
|
||||
(1 << VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT)
|
||||
|
||||
typedef struct {
|
||||
MSIMessage msg;
|
||||
int virq;
|
||||
|
@ -137,7 +137,7 @@ void pcie_acs_reset(PCIDevice *dev);
|
||||
|
||||
void pcie_ari_init(PCIDevice *dev, uint16_t offset, uint16_t nextfn);
|
||||
void pcie_dev_ser_num_init(PCIDevice *dev, uint16_t offset, uint64_t ser_num);
|
||||
void pcie_ats_init(PCIDevice *dev, uint16_t offset);
|
||||
void pcie_ats_init(PCIDevice *dev, uint16_t offset, bool aligned);
|
||||
|
||||
void pcie_cap_slot_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
Error **errp);
|
||||
|
Loading…
Reference in New Issue
Block a user