[PATCH v2 20/21] qemu_hotplug: do not hotplug/hotunplug 'unassigned' hostdevs

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

 



The new address type 'unassigned' allows for a hostdev to be
managed by Libvirt, but not be assigned for guest usage. This
can allow us to execute PCI multifunction hotplug, with managed
mode, leaving non-zero functions unassigned.

For hotplug and unplug , we'll skip unassigned devices when
setting or evaluating aggregateSlotIdx and when we're about
to execute device_add/device_del in QEMU. For hotplug we'll
also skip adress assignment. For unplug we won't mark
the device for removal since we won't be executing device_del
on it.

Signed-off-by: Daniel Henrique Barboza <danielhb413@xxxxxxxxx>
---
 src/qemu/qemu_domain_address.c                |  6 ++
 src/qemu/qemu_hotplug.c                       | 16 ++++
 tests/qemuhotplugtest.c                       |  9 ++
 ...plug-multifunction-hostdev-pci-partial.xml | 27 ++++++
 ...live+multifunction-hostdev-pci-partial.xml | 82 +++++++++++++++++++
 5 files changed, 140 insertions(+)
 create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-multifunction-hostdev-pci-partial.xml
 create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-live+multifunction-hostdev-pci-partial.xml

diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 395f054b8d..c8fe6bbd64 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -3511,6 +3511,9 @@ qemuDomainPCIMultifunctionHostdevEnsurePCIAddresses(virDomainObjPtr vm,
     for (i = 0; i < devlist->count; i++) {
         virDomainHostdevDefPtr hostdev = devlist->devs[i]->data.hostdev;
 
+        if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED)
+            continue;
+
         if (qemuDomainIsPSeries(vm->def)) {
             /* Isolation groups are only relevant for pSeries guests */
             if (qemuDomainFillDeviceIsolationGroup(vm->def, devlist->devs[i]) < 0)
@@ -3544,6 +3547,9 @@ qemuDomainPCIMultifunctionHostdevEnsurePCIAddresses(virDomainObjPtr vm,
         virDomainHostdevDefPtr hostdev = devlist->devs[i]->data.hostdev;
         virPCIDeviceAddress addr = hostdev->source.subsys.u.pci.addr;
 
+        if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED)
+            continue;
+
         devinfos->infos[addr.function] = hostdev->info;
     }
 
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index fe823bb910..00bd5499fe 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1629,6 +1629,13 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
         goto error;
     }
 
+    /* For an unassigned hostdev, add it to the domain definition
+     * and return without hotplugging it to QEMU.  */
+    if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED) {
+        vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
+        return 0;
+    }
+
     if (!(devstr = qemuBuildPCIHostdevDevStr(vm->def, hostdev, 0, priv->qemuCaps)))
         goto error;
 
@@ -6058,6 +6065,9 @@ qemuDomainDetachMultifunctionDevice(virDomainObjPtr vm,
 
     /* Check if the devices belong to same guest slot.*/
     FOR_EACH_DEV_IN_DEVLIST()
+        if (detach->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED)
+            continue;
+
         /* Pick one aggregateSlotIdx and compare against rest of them */
         slotaggridx = slotaggridx ? slotaggridx : detach->info->aggregateSlotIdx;
         if (slotaggridx != detach->info->aggregateSlotIdx) {
@@ -6090,6 +6100,9 @@ qemuDomainDetachMultifunctionDevice(virDomainObjPtr vm,
         if (qemuAssignDeviceHostdevAlias(vm->def, &detach->info->alias, -1) < 0)
             goto reset;
 
+        if (detach->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED)
+            continue;
+
         qemuDomainMarkDeviceAliasForRemoval(vm, detach->info->alias, false);
     }
 
@@ -6102,6 +6115,9 @@ qemuDomainDetachMultifunctionDevice(virDomainObjPtr vm,
         pcisrc = &subsys->u.pci;
         virDomainHostdevFind(vm->def, hostdev, &detach);
 
+        if (detach->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED)
+            continue;
+
         if (qemuMonitorDelDevice(priv->mon, detach->info->alias) < 0) {
             ignore_value(qemuDomainObjExitMonitor(driver, vm));
             if (virDomainObjIsActive(vm))
diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c
index ffd91b5250..50e4bd535b 100644
--- a/tests/qemuhotplugtest.c
+++ b/tests/qemuhotplugtest.c
@@ -843,6 +843,15 @@ mymain(void)
                                  QMP_DEVICE_DELETED("hostdev1")
                                  QMP_DEVICE_DELETED("hostdev0") QMP_OK);
 
+    DO_TEST_ATTACH("base-live", "multifunction-hostdev-pci-partial", false, true,
+                   "device_add", QMP_OK,
+                   "device_add", QMP_OK,
+                   "device_add", QMP_OK);
+    DO_TEST_DETACH("base-live", "multifunction-hostdev-pci-partial", false, false,
+                   "device_del", QMP_DEVICE_DELETED("hostdev3")
+                                 QMP_DEVICE_DELETED("hostdev2")
+                                 QMP_DEVICE_DELETED("hostdev0") QMP_OK);
+
     qemuTestSetHostArch(&driver, VIR_ARCH_PPC64);
     DO_TEST_ATTACH("pseries-base-live", "multifunction-hostdev-pci-2", false, true,
                    "device_add", QMP_OK,
diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-multifunction-hostdev-pci-partial.xml b/tests/qemuhotplugtestdevices/qemuhotplug-multifunction-hostdev-pci-partial.xml
new file mode 100644
index 0000000000..5e01564d2b
--- /dev/null
+++ b/tests/qemuhotplugtestdevices/qemuhotplug-multifunction-hostdev-pci-partial.xml
@@ -0,0 +1,27 @@
+<devices>
+    <hostdev mode='subsystem' type='pci' managed='yes'>
+      <driver name='vfio'/>
+      <source>
+        <address domain='0x0005' bus='0x90' slot='0x01' function='0x1'/>
+      </source>
+    </hostdev>
+    <hostdev mode='subsystem' type='pci' managed='yes'>
+      <driver name='vfio'/>
+      <source>
+        <address domain='0x0005' bus='0x90' slot='0x01' function='0x2'/>
+      </source>
+      <address type='unassigned'/>
+    </hostdev>
+    <hostdev mode='subsystem' type='pci' managed='yes'>
+      <driver name='vfio'/>
+      <source>
+        <address domain='0x0005' bus='0x90' slot='0x01' function='0x3'/>
+      </source>
+    </hostdev>
+    <hostdev mode='subsystem' type='pci' managed='yes'>
+      <driver name='vfio'/>
+      <source>
+        <address domain='0x0005' bus='0x90' slot='0x01' function='0x0'/>
+      </source>
+    </hostdev>
+</devices>
diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+multifunction-hostdev-pci-partial.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+multifunction-hostdev-pci-partial.xml
new file mode 100644
index 0000000000..1808a0071e
--- /dev/null
+++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+multifunction-hostdev-pci-partial.xml
@@ -0,0 +1,82 @@
+<domain type='kvm' id='7'>
+  <name>hotplug</name>
+  <uuid>d091ea82-29e6-2e34-3005-f02617b36e87</uuid>
+  <memory unit='KiB'>4194304</memory>
+  <currentMemory unit='KiB'>4194304</currentMemory>
+  <vcpu placement='static'>4</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+    <apic/>
+    <pae/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <controller type='usb' index='0'>
+      <alias name='usb'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <alias name='ide'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='scsi' index='0' model='virtio-scsi'>
+      <alias name='scsi0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'>
+      <alias name='pci'/>
+    </controller>
+    <controller type='virtio-serial' index='0'>
+      <alias name='virtio-serial0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+    </controller>
+    <input type='mouse' bus='ps2'>
+      <alias name='input0'/>
+    </input>
+    <input type='keyboard' bus='ps2'>
+      <alias name='input1'/>
+    </input>
+    <hostdev mode='subsystem' type='pci' managed='yes'>
+      <driver name='vfio'/>
+      <source>
+        <address domain='0x0005' bus='0x90' slot='0x01' function='0x3'/>
+      </source>
+      <alias name='hostdev0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x3'/>
+    </hostdev>
+    <hostdev mode='subsystem' type='pci' managed='yes'>
+      <driver name='vfio'/>
+      <source>
+        <address domain='0x0005' bus='0x90' slot='0x01' function='0x2'/>
+      </source>
+      <alias name='hostdev1'/>
+      <address type='unassigned'/>
+    </hostdev>
+    <hostdev mode='subsystem' type='pci' managed='yes'>
+      <driver name='vfio'/>
+      <source>
+        <address domain='0x0005' bus='0x90' slot='0x01' function='0x1'/>
+      </source>
+      <alias name='hostdev2'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/>
+    </hostdev>
+    <hostdev mode='subsystem' type='pci' managed='yes'>
+      <driver name='vfio'/>
+      <source>
+        <address domain='0x0005' bus='0x90' slot='0x01' function='0x0'/>
+      </source>
+      <alias name='hostdev3'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/>
+    </hostdev>
+    <memballoon model='none'/>
+  </devices>
+  <seclabel type='none' model='none'/>
+</domain>
-- 
2.24.1






[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux