This connects the new <driver> group attribute into qemu in two places:
1) when a hostdev is allocated from a libvirt network, the setting of
groupMgmt is transferred from the network definition into the new
HostdevDef.
2) When the virPCIDeviceList of all hostdevs for the domain is
created, each device's attach_group bool is set according to the value
of groupMgmt in the HostdevDef. This is where virPCIDeviceDetach (and
later virPCIDeviceReAttach) will find it.
The effect of setting group='auto':
If there are multiple devices in the same iommu group as the device
you wish to assign to a guest using VFIO, you have two choices:
a) Manually (with "virsh nodedev-detach --driver vfio" or by other
means) detach each device in the group from the host and bind them
all to either the vfio-pci driver or the pci-stub driver. Then
define the <hostdev> (or <interface type='hostdev'>) in the guest
config *without* "managed='yes'" - libvirt will expect that the
device (and any other devices in the same group) will already be
detached from the host and attached to a different driver
appropriate for assigning to the guest.
b) If you wish to use <hostdev managed='yes'>, then add
"group='auto'"
to the device's <driver> element:
<driver name='vfio' group='auto'/>
When it is time to assign the device to the guest, libvirt will
check through the group list, and any device in the group not
already bound to vfio-pci, pci-stub, or pcieport, will be detached
from the host and bound to vfio-pci.
Option (1) provides finer grained control over what driver is used for
each device in a group, while option (2) is simpler.
Note that if you actually want to assign all the devices in the group
to a single guest, you can specify "group='auto'" for all of them, and
libvirt will pay attention to which devices were already detached (and
not attempt to re-detach them, which is just a waste of time), and
also will not attempt to re-attach any of the devices in the group to
the host until *all* of them have been detached from the guest and are
free (and at that time all of them will be re-attached to the host at
the same time).
---
src/network/bridge_driver.c | 22 ++++++++++++++++++++++
src/qemu/qemu_hostdev.c | 8 ++++++++
2 files changed, 30 insertions(+)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index f7c2470..fbe0098 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -3945,6 +3945,7 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
} else if (netdef->forward.type == VIR_NETWORK_FORWARD_HOSTDEV) {
virDomainHostdevSubsysPciBackendType backend;
+ virDomainHostdevSubsysPciGroupMgmtType groupMgmt;
if (!iface->data.network.actual
&& (VIR_ALLOC(iface->data.network.actual) < 0)) {
@@ -4001,6 +4002,27 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.backend
= backend;
+ switch (netdef->forward.driverGroupMgmt)
+ {
+ case VIR_NETWORK_FORWARD_DRIVER_GROUP_MGMT_DEFAULT:
+ groupMgmt = VIR_DOMAIN_HOSTDEV_PCI_GROUP_MGMT_DEFAULT;
+ break;
+ case VIR_NETWORK_FORWARD_DRIVER_GROUP_MGMT_MANUAL:
+ groupMgmt = VIR_DOMAIN_HOSTDEV_PCI_GROUP_MGMT_MANUAL;
+ break;
+ case VIR_NETWORK_FORWARD_DRIVER_GROUP_MGMT_AUTO:
+ groupMgmt = VIR_DOMAIN_HOSTDEV_PCI_GROUP_MGMT_AUTO;
+ break;
+ default:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unrecognized driver group management value %d "
+ " in network '%s'"),
+ netdef->forward.driverGroupMgmt, netdef->name);
+ goto error;
+ }
+ iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.groupMgmt
+ = groupMgmt;
+
/* merge virtualports from interface, network, and portgroup to
* arrive at actual virtualport to use
*/
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 1abad59..2b0221d 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -74,6 +74,10 @@ qemuGetPciHostDeviceList(virDomainHostdevDefPtr *hostdevs, int
nhostdevs)
virObjectUnref(list);
return NULL;
}
+ if (hostdev->source.subsys.u.pci.groupMgmt
+ == VIR_DOMAIN_HOSTDEV_PCI_GROUP_MGMT_AUTO) {
+ virPCIDeviceSetAttachGroup(dev, true);
+ }
} else {
if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0) {
virObjectUnref(list);
@@ -167,6 +171,10 @@ int qemuUpdateActivePciHostdevs(virQEMUDriverPtr driver,
== VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0)
goto cleanup;
+ if (hostdev->source.subsys.u.pci.groupMgmt
+ == VIR_DOMAIN_HOSTDEV_PCI_GROUP_MGMT_AUTO) {
+ virPCIDeviceSetAttachGroup(dev, true);
+ }
} else {
if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0)
goto cleanup;
--
1.7.11.7