From 3b87709c768480e085556e06bd8d08f62270d42d Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Fri, 21 Apr 2023 16:56:10 +0200 Subject: [PATCH] qemu: Move PCI backend setting into qemuDomainPrepareHostdev() 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 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 drop qemuHostdevPreparePCIDevicesCheckSupport(). Signed-off-by: Michal Privoznik Reviewed-by: Martin Kletzander --- src/qemu/qemu_domain.c | 50 +++++++++++++++++++++++++++++++- src/qemu/qemu_hostdev.c | 64 ++--------------------------------------- src/qemu/qemu_hotplug.c | 2 +- 3 files changed, 53 insertions(+), 63 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index f462476d2a..58cd3dd710 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11292,6 +11292,53 @@ qemuDomainPrepareHostdevSCSI(virDomainHostdevDef *hostdev, } +static int +qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev, + virQEMUCaps *qemuCaps) +{ + bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO(); + virDomainHostdevSubsysPCIBackendType *backend = &hostdev->source.subsys.u.pci.backend; + + /* assign defaults for hostdev passthrough */ + switch (*backend) { + case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT: + if (supportsPassthroughVFIO) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { + *backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO; + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("VFIO PCI device assignment is not supported by this version of QEMU")); + return -1; + } + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("host doesn't support passthrough of host PCI devices")); + return -1; + } + break; + + case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO: + if (!supportsPassthroughVFIO) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("host doesn't support VFIO PCI passthrough")); + return false; + } + break; + + case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("host doesn't support legacy PCI passthrough")); + return false; + + case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN: + case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST: + break; + } + + return true; +} + + int qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev, qemuDomainObjPrivate *priv) @@ -11302,8 +11349,9 @@ qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev, switch ((virDomainHostdevSubsysType)hostdev->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: return qemuDomainPrepareHostdevSCSI(hostdev, priv); - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: + return qemuDomainPrepareHostdevPCI(hostdev, priv->qemuCaps); + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c index 45cd1066f0..49347019ea 100644 --- a/src/qemu/qemu_hostdev.c +++ b/src/qemu/qemu_hostdev.c @@ -153,60 +153,6 @@ qemuHostdevHostSupportsPassthroughVFIO(void) } -static bool -qemuHostdevPreparePCIDevicesCheckSupport(virDomainHostdevDef **hostdevs, - size_t nhostdevs, - virQEMUCaps *qemuCaps) -{ - bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO(); - size_t i; - - /* assign defaults for hostdev passthrough */ - for (i = 0; i < nhostdevs; i++) { - virDomainHostdevDef *hostdev = hostdevs[i]; - virDomainHostdevSubsysPCIBackendType *backend = &hostdev->source.subsys.u.pci.backend; - - if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) - continue; - if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) - continue; - - 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; - } else { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("host doesn't support passthrough of " - "host PCI devices")); - return false; - } - - break; - - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO: - if (!supportsPassthroughVFIO) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("host doesn't support VFIO PCI passthrough")); - return false; - } - break; - - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM: - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("host doesn't support legacy PCI passthrough")); - return false; - - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN: - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST: - break; - } - } - - return true; -} - int qemuHostdevPrepareOneNVMeDisk(virQEMUDriver *driver, const char *name, @@ -235,15 +181,11 @@ qemuHostdevPreparePCIDevices(virQEMUDriver *driver, const unsigned char *uuid, virDomainHostdevDef **hostdevs, int nhostdevs, - virQEMUCaps *qemuCaps, + virQEMUCaps *qemuCaps G_GNUC_UNUSED, unsigned int flags) { - virHostdevManager *hostdev_mgr = driver->hostdevMgr; - - if (!qemuHostdevPreparePCIDevicesCheckSupport(hostdevs, nhostdevs, qemuCaps)) - return -1; - - return virHostdevPreparePCIDevices(hostdev_mgr, QEMU_DRIVER_NAME, + return virHostdevPreparePCIDevices(driver->hostdevMgr, + QEMU_DRIVER_NAME, name, uuid, hostdevs, nhostdevs, flags); } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index d4cded15e7..9cefac9001 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1495,7 +1495,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 qemuDomainPrepareHostdevPCI() */ backend = hostdev->source.subsys.u.pci.backend; switch (backend) {