]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: propagate virQEMUDriver object to qemuDomainDeviceCalculatePCIConnectFlags
authorLaine Stump <laine@laine.org>
Thu, 3 Nov 2016 20:33:32 +0000 (16:33 -0400)
committerLaine Stump <laine@laine.org>
Wed, 30 Nov 2016 20:28:07 +0000 (15:28 -0500)
If libvirtd is running unprivileged, it can open a device's PCI config
data in sysfs, but can only read the first 64 bytes. But as part of
determining whether a device is Express or legacy PCI,
qemuDomainDeviceCalculatePCIConnectFlags() will be updated in a future
patch to call virPCIDeviceIsPCIExpress(), which tries to read beyond
the first 64 bytes of the PCI config data and fails with an error log
if the read is unsuccessful.

In order to avoid creating a parallel "quiet" version of
virPCIDeviceIsPCIExpress(), this patch passes a virQEMUDriverPtr down
through all the call chains that initialize the
qemuDomainFillDevicePCIConnectFlagsIterData, and saves the driver
pointer with the rest of the iterdata so that it can be used by
qemuDomainDeviceCalculatePCIConnectFlags(). This pointer isn't used
yet, but will be used in an upcoming patch (that detects Express vs
legacy PCI for VFIO assigned devices) to examine driver->privileged.

src/qemu/qemu_domain.c
src/qemu/qemu_domain_address.c
src/qemu/qemu_domain_address.h
src/qemu/qemu_hotplug.c
src/qemu/qemu_process.c
tests/qemuhotplugtest.c

index 47332a82c5db5e4d9d15aaaa144df4041a7dbfa8..4aae14d9d10365d49c29faa1d22e73e71ab76ace 100644 (file)
@@ -3120,7 +3120,7 @@ qemuDomainDefAssignAddresses(virDomainDef *def,
             goto cleanup;
     }
 
-    if (qemuDomainAssignAddresses(def, qemuCaps, NULL, newDomain) < 0)
+    if (qemuDomainAssignAddresses(def, qemuCaps, driver, NULL, newDomain) < 0)
         goto cleanup;
 
     ret = 0;
index 13f6702b5f2ac5b31c364182a07250ae8e4f4dfb..84b8601a318a60d9b3e142bf6e01f83d3223485a 100644 (file)
@@ -436,6 +436,7 @@ qemuDomainAssignARMVirtioMMIOAddresses(virDomainDefPtr def,
  */
 static virDomainPCIConnectFlags
 qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
+                                         virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
                                          virDomainPCIConnectFlags pcieFlags,
                                          virDomainPCIConnectFlags virtioFlags)
 {
@@ -674,6 +675,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
 typedef struct {
     virDomainPCIConnectFlags virtioFlags;
     virDomainPCIConnectFlags pcieFlags;
+    virQEMUDriverPtr driver;
 } qemuDomainFillDevicePCIConnectFlagsIterData;
 
 
@@ -686,8 +688,12 @@ typedef struct {
 static void
 qemuDomainFillDevicePCIConnectFlagsIterInit(virDomainDefPtr def,
                                             virQEMUCapsPtr qemuCaps,
+                                            virQEMUDriverPtr driver,
                                             qemuDomainFillDevicePCIConnectFlagsIterData *data)
 {
+
+    data->driver = driver;
+
     if (qemuDomainMachineHasPCIeRoot(def)) {
         data->pcieFlags = (VIR_PCI_CONNECT_TYPE_PCIE_DEVICE |
                            VIR_PCI_CONNECT_HOTPLUGGABLE);
@@ -727,7 +733,8 @@ qemuDomainFillDevicePCIConnectFlagsIter(virDomainDefPtr def ATTRIBUTE_UNUSED,
     qemuDomainFillDevicePCIConnectFlagsIterData *data = opaque;
 
     info->pciConnectFlags
-        = qemuDomainDeviceCalculatePCIConnectFlags(dev, data->pcieFlags,
+        = qemuDomainDeviceCalculatePCIConnectFlags(dev, data->driver,
+                                                   data->pcieFlags,
                                                    data->virtioFlags);
     return 0;
 }
@@ -747,11 +754,12 @@ qemuDomainFillDevicePCIConnectFlagsIter(virDomainDefPtr def ATTRIBUTE_UNUSED,
  */
 static int
 qemuDomainFillAllPCIConnectFlags(virDomainDefPtr def,
-                                 virQEMUCapsPtr qemuCaps)
+                                 virQEMUCapsPtr qemuCaps,
+                                 virQEMUDriverPtr driver)
 {
     qemuDomainFillDevicePCIConnectFlagsIterData data;
 
-    qemuDomainFillDevicePCIConnectFlagsIterInit(def, qemuCaps, &data);
+    qemuDomainFillDevicePCIConnectFlagsIterInit(def, qemuCaps, driver, &data);
 
     return virDomainDeviceInfoIterate(def,
                                       qemuDomainFillDevicePCIConnectFlagsIter,
@@ -773,7 +781,8 @@ qemuDomainFillAllPCIConnectFlags(virDomainDefPtr def,
 static void
 qemuDomainFillDevicePCIConnectFlags(virDomainDefPtr def,
                                     virDomainDeviceDefPtr dev,
-                                    virQEMUCapsPtr qemuCaps)
+                                    virQEMUCapsPtr qemuCaps,
+                                    virQEMUDriverPtr driver)
 {
     virDomainDeviceInfoPtr info = virDomainDeviceGetInfo(dev);
 
@@ -789,10 +798,11 @@ qemuDomainFillDevicePCIConnectFlags(virDomainDefPtr def,
          */
         qemuDomainFillDevicePCIConnectFlagsIterData data;
 
-        qemuDomainFillDevicePCIConnectFlagsIterInit(def, qemuCaps, &data);
+        qemuDomainFillDevicePCIConnectFlagsIterInit(def, qemuCaps, driver, &data);
 
         info->pciConnectFlags
-            = qemuDomainDeviceCalculatePCIConnectFlags(dev, data.pcieFlags,
+            = qemuDomainDeviceCalculatePCIConnectFlags(dev, data.driver,
+                                                       data.pcieFlags,
                                                        data.virtioFlags);
     }
 }
@@ -1829,6 +1839,7 @@ qemuDomainAddressFindNewBusNr(virDomainDefPtr def)
 static int
 qemuDomainAssignPCIAddresses(virDomainDefPtr def,
                              virQEMUCapsPtr qemuCaps,
+                             virQEMUDriverPtr driver,
                              virDomainObjPtr obj)
 {
     int ret = -1;
@@ -1854,7 +1865,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
      * of all devices. This will be used to pick an appropriate
      * bus when assigning addresses.
      */
-    if (qemuDomainFillAllPCIConnectFlags(def, qemuCaps) < 0)
+    if (qemuDomainFillAllPCIConnectFlags(def, qemuCaps, driver) < 0)
         goto cleanup;
 
     if (nbuses > 0 &&
@@ -1973,7 +1984,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
             dev.type = VIR_DOMAIN_DEVICE_CONTROLLER;
             dev.data.controller = def->controllers[contIndex];
             /* set connect flags so it will be properly addressed */
-            qemuDomainFillDevicePCIConnectFlags(def, &dev, qemuCaps);
+            qemuDomainFillDevicePCIConnectFlags(def, &dev, qemuCaps, driver);
             if (qemuDomainPCIAddressReserveNextSlot(addrs,
                                                     &dev.data.controller->info) < 0)
                 goto cleanup;
@@ -2343,6 +2354,7 @@ qemuDomainAssignUSBAddresses(virDomainDefPtr def,
 int
 qemuDomainAssignAddresses(virDomainDefPtr def,
                           virQEMUCapsPtr qemuCaps,
+                          virQEMUDriverPtr driver,
                           virDomainObjPtr obj,
                           bool newDomain)
 {
@@ -2357,7 +2369,7 @@ qemuDomainAssignAddresses(virDomainDefPtr def,
 
     qemuDomainAssignARMVirtioMMIOAddresses(def, qemuCaps);
 
-    if (qemuDomainAssignPCIAddresses(def, qemuCaps, obj) < 0)
+    if (qemuDomainAssignPCIAddresses(def, qemuCaps, driver, obj) < 0)
         return -1;
 
     if (qemuDomainAssignUSBAddresses(def, obj, newDomain) < 0)
@@ -2386,7 +2398,8 @@ qemuDomainAssignAddresses(virDomainDefPtr def,
  */
 int
 qemuDomainEnsurePCIAddress(virDomainObjPtr obj,
-                           virDomainDeviceDefPtr dev)
+                           virDomainDeviceDefPtr dev,
+                           virQEMUDriverPtr driver)
 {
     qemuDomainObjPrivatePtr priv = obj->privateData;
     virDomainDeviceInfoPtr info = virDomainDeviceGetInfo(dev);
@@ -2394,7 +2407,7 @@ qemuDomainEnsurePCIAddress(virDomainObjPtr obj,
     if (!info)
         return 0;
 
-    qemuDomainFillDevicePCIConnectFlags(obj->def, dev, priv->qemuCaps);
+    qemuDomainFillDevicePCIConnectFlags(obj->def, dev, priv->qemuCaps, driver);
 
     return virDomainPCIAddressEnsureAddr(priv->pciaddrs, info,
                                          info->pciConnectFlags);
index e532bd85227f411cadf2a9e59c117d269665d88a..067f4e799703e9a06eed9bce73c526ebf0b8f736 100644 (file)
@@ -25,6 +25,7 @@
 
 # include "domain_addr.h"
 # include "domain_conf.h"
+# include "qemu_conf.h"
 # include "qemu_capabilities.h"
 
 int qemuDomainSetSCSIControllerModel(const virDomainDef *def,
@@ -33,13 +34,15 @@ int qemuDomainSetSCSIControllerModel(const virDomainDef *def,
 
 int qemuDomainAssignAddresses(virDomainDefPtr def,
                               virQEMUCapsPtr qemuCaps,
+                              virQEMUDriverPtr driver,
                               virDomainObjPtr obj,
                               bool newDomain)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 
 int qemuDomainEnsurePCIAddress(virDomainObjPtr obj,
-                               virDomainDeviceDefPtr dev)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+                               virDomainDeviceDefPtr dev,
+                               virQEMUDriverPtr driver)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 
 void qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
                                     virDomainDeviceInfoPtr info,
index b03e618837ec8e3bdb1364a56935bac420198fc9..9d74dfb15d17e0daeaa0b0952eddd1b55816d846 100644 (file)
@@ -345,7 +345,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
             goto error;
     } else if (!disk->info.type ||
                 disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-        if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
+        if (qemuDomainEnsurePCIAddress(vm, &dev, driver) < 0)
             goto error;
     }
     releaseaddr = true;
@@ -504,7 +504,7 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
 
     if (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
         controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-        if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
+        if (qemuDomainEnsurePCIAddress(vm, &dev, driver) < 0)
             goto cleanup;
     } else if (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
         if (!(ccwaddrs = qemuDomainCCWAddrSetCreateFromDomain(vm->def)))
@@ -1137,7 +1137,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("virtio-s390 net device cannot be hotplugged."));
         goto cleanup;
-    } else if (qemuDomainEnsurePCIAddress(vm, &dev) < 0) {
+    } else if (qemuDomainEnsurePCIAddress(vm, &dev, driver) < 0) {
         goto cleanup;
     }
 
@@ -1441,7 +1441,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 
     if (qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1) < 0)
         goto error;
-    if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
+    if (qemuDomainEnsurePCIAddress(vm, &dev, driver) < 0)
         goto error;
     releaseaddr = true;
     if (backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
@@ -1773,7 +1773,8 @@ qemuDomainChrRemove(virDomainDefPtr vmdef,
  */
 static int
 qemuDomainAttachChrDeviceAssignAddr(virDomainObjPtr vm,
-                                    virDomainChrDefPtr chr)
+                                    virDomainChrDefPtr chr,
+                                    virQEMUDriverPtr driver)
 {
     virDomainDefPtr def = vm->def;
     qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -1787,7 +1788,7 @@ qemuDomainAttachChrDeviceAssignAddr(virDomainObjPtr vm,
 
     } else if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
                chr->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI) {
-        if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
+        if (qemuDomainEnsurePCIAddress(vm, &dev, driver) < 0)
             return -1;
         return 1;
 
@@ -1847,7 +1848,7 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
     if (qemuAssignDeviceChrAlias(vmdef, chr, -1) < 0)
         goto cleanup;
 
-    if ((rc = qemuDomainAttachChrDeviceAssignAddr(vm, chr)) < 0)
+    if ((rc = qemuDomainAttachChrDeviceAssignAddr(vm, chr, driver)) < 0)
         goto cleanup;
     if (rc == 1)
         need_release = true;
@@ -1996,7 +1997,7 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
 
     if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
         rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-        if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
+        if (qemuDomainEnsurePCIAddress(vm, &dev, driver) < 0)
             goto cleanup;
     } else if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
         if (!(ccwaddrs = qemuDomainCCWAddrSetCreateFromDomain(vm->def)))
@@ -2516,7 +2517,7 @@ qemuDomainAttachSCSIVHostDevice(virQEMUDriverPtr driver,
 
     if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
         hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-        if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
+        if (qemuDomainEnsurePCIAddress(vm, &dev, driver) < 0)
             goto cleanup;
     } else if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
         if (!(ccwaddrs = qemuDomainCCWAddrSetCreateFromDomain(vm->def)))
@@ -2665,7 +2666,7 @@ qemuDomainAttachShmemDevice(virQEMUDriverPtr driver,
 
     if ((shmem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
          shmem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
-        (qemuDomainEnsurePCIAddress(vm, &dev) < 0))
+        (qemuDomainEnsurePCIAddress(vm, &dev, driver) < 0))
         return -1;
 
     if (!(shmstr = qemuBuildShmemDevStr(vm->def, shmem, priv->qemuCaps)))
index ecd7ded670ea2a9045ba102c143101713f6552e4..7f19c691e62980d197741ace3b0d0f431126f779 100644 (file)
@@ -3368,8 +3368,10 @@ qemuProcessReconnect(void *opaque)
         goto cleanup;
     }
 
-    if ((qemuDomainAssignAddresses(obj->def, priv->qemuCaps, obj, false)) < 0)
+    if ((qemuDomainAssignAddresses(obj->def, priv->qemuCaps,
+                                   driver, obj, false)) < 0) {
         goto error;
+    }
 
     /* if domain requests security driver we haven't loaded, report error, but
      * do not kill the domain
@@ -5156,9 +5158,10 @@ qemuProcessPrepareDomain(virConnectPtr conn,
      * use in hotplug
      */
     VIR_DEBUG("Assigning domain PCI addresses");
-    if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm,
-                                   !!(flags & VIR_QEMU_PROCESS_START_NEW))) < 0)
+    if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, driver, vm,
+                                   !!(flags & VIR_QEMU_PROCESS_START_NEW))) < 0) {
         goto cleanup;
+    }
 
     if (qemuAssignDeviceAliases(vm->def, priv->qemuCaps) < 0)
         goto cleanup;
@@ -6355,8 +6358,10 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
      * use in hotplug
      */
     VIR_DEBUG("Assigning domain PCI addresses");
-    if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm, false)) < 0)
+    if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps,
+                                   driver, vm, false)) < 0) {
         goto error;
+    }
 
     if ((timestamp = virTimeStringNow()) == NULL)
         goto error;
index 89e870c0aa89ac08a01787c0d847a7acff80145b..f0a84539471a003cf82fbe87ae98996665f3b847 100644 (file)
@@ -90,8 +90,10 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt,
                                                VIR_DOMAIN_DEF_PARSE_INACTIVE)))
         goto cleanup;
 
-    if (qemuDomainAssignAddresses((*vm)->def, priv->qemuCaps, *vm, true) < 0)
+    if (qemuDomainAssignAddresses((*vm)->def, priv->qemuCaps,
+                                  &driver, *vm, true) < 0) {
         goto cleanup;
+    }
 
     if (qemuAssignDeviceAliases((*vm)->def, priv->qemuCaps) < 0)
         goto cleanup;