The device option for vfio-pci is nearly identical to that for
pci-assign - only the configfd parameter isn't supported (or needed).
Checking for presence of the bootindex parameter is done separately
from constructing the commandline, similar to how it is done for
pci-assign.
---
src/qemu/qemu_command.c | 48 ++++++++++++++++++++++++++++++++++++++----------
src/qemu/qemu_hotplug.c | 13 ++++++++++++-
2 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 4f14dff..761291c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4345,14 +4345,19 @@ qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char
*configfd,
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
- virBufferAddLit(&buf, "pci-assign");
+ if (dev->source.subsys.u.pci.backend
+ == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) {
+ virBufferAddLit(&buf, "vfio-pci");
+ } else {
+ virBufferAddLit(&buf, "pci-assign");
+ if (configfd && *configfd)
+ virBufferAsprintf(&buf, ",configfd=%s", configfd);
+ }
virBufferAsprintf(&buf, ",host=%.2x:%.2x.%.1x",
dev->source.subsys.u.pci.addr.bus,
dev->source.subsys.u.pci.addr.slot,
dev->source.subsys.u.pci.addr.function);
virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
- if (configfd && *configfd)
- virBufferAsprintf(&buf, ",configfd=%s", configfd);
if (dev->info->bootIndex)
virBufferAsprintf(&buf, ",bootindex=%d",
dev->info->bootIndex);
if (qemuBuildDeviceAddressStr(&buf, dev->info, qemuCaps) < 0)
@@ -7850,12 +7855,23 @@ qemuBuildCommandLine(virConnectPtr conn,
" supported for PCI and USB devices"));
goto error;
} else {
- if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI
&&
- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_BOOTINDEX)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("booting from assigned PCI devices is
not"
- " supported with this version of qemu"));
- goto error;
+ if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
{
+ if (hostdev->source.subsys.u.pci.backend
+ == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_BOOTINDEX)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("booting from PCI devices assigned with
VFIO "
+ "is not supported with this version of
qemu"));
+ goto error;
+ }
+ } else {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_BOOTINDEX)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("booting from assigned PCI devices is
not"
+ " supported with this version of
qemu"));
+ goto error;
+ }
+ }
}
if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB
&&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HOST_BOOTINDEX)) {
@@ -7889,9 +7905,21 @@ qemuBuildCommandLine(virConnectPtr conn,
/* PCI */
if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+
+ if ((hostdev->source.subsys.u.pci.backend
+ == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("VFIO PCI device assignment is not supported by
"
+ "this version of qemu"));
+ goto error;
+ }
+
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
char *configfd_name = NULL;
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
+ if ((hostdev->source.subsys.u.pci.backend
+ != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
int configfd = qemuOpenPCIConfig(hostdev);
if (configfd >= 0) {
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f6b2fc8..30c8bda 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -999,13 +999,24 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
&hostdev, 1) < 0)
return -1;
+ if ((hostdev->source.subsys.u.pci.backend
+ == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
+ !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("VFIO PCI device assignment is not supported by "
+ "this version of qemu"));
+ goto error;
+ }
+
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
goto error;
if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0)
goto error;
releaseaddr = true;
- if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
+ if ((hostdev->source.subsys.u.pci.backend
+ != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
+ virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
configfd = qemuOpenPCIConfig(hostdev);
if (configfd >= 0) {
if (virAsprintf(&configfd_name, "fd-%s",
--
1.7.11.7