From 66d1c4c19faff83e36075c7b61053d060a8ffc50 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Wed, 14 Dec 2016 17:30:35 +0100 Subject: [PATCH] virtio-pci: Fix cross-version migration with older machines This patch fixes a cross-version migration regression introduced by commit d1b4259f ("virtio-bus: Plug devices after features are negotiated"). The problem is encountered when host's vhost backend does not support VIRTIO_F_VERSION_1, and migration is initiated from a v2.7 or prior machine with virtio-pci modern capabilities enabled to a v2.8 machine. In this case, modern capabilities get exposed to the guest by the source, whereas the target will detect version 1 is not supported so will only expose legacy capabilities. The problem is fixed by introducing a new "x-ignore-backend-features" property, which is set in v2.7 and prior compatibility modes. Doing this, v2.7 machine keeps its broken behaviour (enabling modern while version is not supported), and newer machines will behave correctly. Reported-by: Michael Roth Reviewed-by: Marcel Apfelbaum Reviewed-by: Stefan Hajnoczi Reviewed-by: Michael S. Tsirkin Tested-by: Michael Roth Signed-off-by: Maxime Coquelin Message-id: 20161214163035.3297-1-maxime.coquelin@redhat.com Suggested-by: Stefan Hajnoczi Cc: Michael S. Tsirkin Cc: Cornelia Huck Cc: Dr. David Alan Gilbert Reviewed-by: Marcel Apfelbaum Reviewed-by: Stefan Hajnoczi Tested-by: Michael Roth Signed-off-by: Maxime Coquelin Signed-off-by: Stefan Hajnoczi --- hw/virtio/virtio-pci.c | 5 ++++- hw/virtio/virtio-pci.h | 1 + include/hw/compat.h | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 521ba0b41567..21c2b9dbfc97 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1580,7 +1580,8 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp) * Virtio capabilities present without * VIRTIO_F_VERSION_1 confuses guests */ - if (!virtio_has_feature(vdev->host_features, VIRTIO_F_VERSION_1)) { + if (!proxy->ignore_backend_features && + !virtio_has_feature(vdev->host_features, VIRTIO_F_VERSION_1)) { virtio_pci_disable_modern(proxy); if (!legacy) { @@ -1852,6 +1853,8 @@ static Property virtio_pci_properties[] = { VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT, false), DEFINE_PROP_BIT("page-per-vq", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT, false), + DEFINE_PROP_BOOL("x-ignore-backend-features", VirtIOPCIProxy, + ignore_backend_features, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index b2a996fa8338..5e078866c426 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -153,6 +153,7 @@ struct VirtIOPCIProxy { int config_cap; uint32_t flags; bool disable_modern; + bool ignore_backend_features; OnOffAuto disable_legacy; uint32_t class_code; uint32_t nvectors; diff --git a/include/hw/compat.h b/include/hw/compat.h index 0f06e113bee2..8dfc7a38c0f2 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -18,6 +18,10 @@ .driver = "intel-iommu",\ .property = "x-buggy-eim",\ .value = "true",\ + },{\ + .driver = "virtio-pci",\ + .property = "x-ignore-backend-features",\ + .value = "on",\ }, #define HW_COMPAT_2_6 \