[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 22/22] qemu: implement backend of <driver group='auto'/>

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

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)
             = backend;
+        switch (netdef->forward.driverGroupMgmt)
+        {
+            break;
+            break;
+            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)
                 return NULL;
+            if (hostdev->source.subsys.u.pci.groupMgmt
+                virPCIDeviceSetAttachGroup(dev, true);
+            }
         } else {
             if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0) {
@@ -167,6 +171,10 @@ int qemuUpdateActivePciHostdevs(virQEMUDriverPtr driver,
             if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0)
                 goto cleanup;
+            if (hostdev->source.subsys.u.pci.groupMgmt
+                virPCIDeviceSetAttachGroup(dev, true);
+            }
         } else {
             if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0)
                 goto cleanup;

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]