From: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx> virsh command domxml-to-native failed with below error but start command succeed for same domain xml. "internal error: invalid PCI passthrough type 'default'" If a <hostdev> PCI backend is not set in the XML, the supported one is then chosen in qemuHostdevPreparePCIDevicesCheckSupport(). But this function is not called anywhere from qemuConnectDomainXMLToNative(). But qemuDomainPrepareHostdev() is. And it is also called from domain startup/hotplug code. Therefore, move the backend setting to the common path. And since qemuDomainPrepareHostdev() is called transitively from our qemuxml2argvtest, we can just drop the code in testCompareXMLToArgvCreateArgs() that preselects the backend (if a mock for qemuHostdevHostSupportsPassthroughVFIO() is provided. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx> Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/qemu/qemu_domain.c | 12 ++++++++++++ src/qemu/qemu_hostdev.c | 16 +++++++--------- src/qemu/qemu_hotplug.c | 2 +- tests/qemuxml2argvmock.c | 7 +++++++ tests/qemuxml2argvtest.c | 6 ------ 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 63b13b6875..6de846f158 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11275,6 +11275,18 @@ qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev, } } + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { + bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO(); + virDomainHostdevSubsysPCIBackendType *backend = &hostdev->source.subsys.u.pci.backend; + + if (*backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT && + supportsPassthroughVFIO && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { + *backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO; + } + } + return 0; } diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c index 45cd1066f0..8408928c00 100644 --- a/src/qemu/qemu_hostdev.c +++ b/src/qemu/qemu_hostdev.c @@ -156,7 +156,7 @@ qemuHostdevHostSupportsPassthroughVFIO(void) static bool qemuHostdevPreparePCIDevicesCheckSupport(virDomainHostdevDef **hostdevs, size_t nhostdevs, - virQEMUCaps *qemuCaps) + virQEMUCaps *qemuCaps G_GNUC_UNUSED) { bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO(); size_t i; @@ -173,17 +173,15 @@ qemuHostdevPreparePCIDevicesCheckSupport(virDomainHostdevDef **hostdevs, switch (*backend) { case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT: - if (supportsPassthroughVFIO && - virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { - *backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO; + /* qemuDomainPrepareHostdev() should have set different value */ + if (supportsPassthroughVFIO) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("QEMU doesn't support VFIO PCI passthrough")); } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("host doesn't support passthrough of " - "host PCI devices")); - return false; + _("host doesn't support passthrough of host PCI devices")); } - - break; + return false; case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO: if (!supportsPassthroughVFIO) { diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 8902b40815..95ac0fd754 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1478,7 +1478,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver, &hostdev, 1, priv->qemuCaps, flags) < 0) return -1; - /* this could have been changed by qemuHostdevPreparePCIDevices */ + /* this could have been changed by qemuDomainPrepareHostdev */ backend = hostdev->source.subsys.u.pci.backend; switch (backend) { diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c index f566ec539a..863fdf0351 100644 --- a/tests/qemuxml2argvmock.c +++ b/tests/qemuxml2argvmock.c @@ -33,6 +33,7 @@ #include "virscsivhost.h" #include "virtpm.h" #include "virutil.h" +#include "qemu/qemu_hostdev.h" #include "qemu/qemu_interface.h" #include "qemu/qemu_command.h" #include <unistd.h> @@ -82,6 +83,12 @@ virSCSIVHostOpenVhostSCSI(int *vhostfd) return 0; } +bool +qemuHostdevHostSupportsPassthroughVFIO(void) +{ + return true; +} + int virNetDevTapCreate(char **ifname, const char *tunpath G_GNUC_UNUSED, diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 1808d9fc02..8333749eea 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -407,12 +407,6 @@ testCompareXMLToArgvCreateArgs(virQEMUDriver *drv, for (i = 0; i < vm->def->nhostdevs; i++) { virDomainHostdevDef *hostdev = vm->def->hostdevs[i]; - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && - hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && - hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) { - hostdev->source.subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO; - } - if (virHostdevIsSCSIDevice(hostdev)) { virDomainHostdevSubsysSCSI *scsisrc = &hostdev->source.subsys.u.scsi; -- 2.39.2