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) {