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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list