render / rpms / libvirt

Forked from rpms/libvirt 7 months ago
Clone
c313de
From 050eb598af9291f385998cb1127d5bdf83305501 Mon Sep 17 00:00:00 2001
c313de
Message-Id: <050eb598af9291f385998cb1127d5bdf83305501@dist-git>
c313de
From: Yi Min Zhao <zyimin@linux.ibm.com>
c313de
Date: Mon, 8 Apr 2019 10:57:21 +0200
c313de
Subject: [PATCH] conf: Introduce extension flag and zPCI member for PCI
c313de
 address
c313de
MIME-Version: 1.0
c313de
Content-Type: text/plain; charset=UTF-8
c313de
Content-Transfer-Encoding: 8bit
c313de
c313de
This patch introduces PCI address extension flag for virDomainDeviceInfo
c313de
and virPCIDeviceAddress. The extension flag in virDomainDeviceInfo is
c313de
used internally during calculating PCI extension flag. The one in
c313de
virPCIDeviceAddress is the duplicate to indicate extension address is
c313de
being used. Currently only zPCI extension address is introduced to deal
c313de
with 'uid' and 'fid' on the S390 platform.
c313de
c313de
Signed-off-by: Yi Min Zhao <zyimin@linux.ibm.com>
c313de
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
c313de
Reviewed-by: Ján Tomko <jtomko@redhat.com>
c313de
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
c313de
c313de
(cherry picked from commit 478e5f90fd4c0c0a8c1b3a8e19b9cae93ed78a4e)
c313de
c313de
https://bugzilla.redhat.com/show_bug.cgi?id=1508149
c313de
c313de
Conflicts:
c313de
c313de
  * src/qemu/qemu_domain_address.c
c313de
    + context
c313de
      - missing db98a426a640
c313de
c313de
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
c313de
Message-Id: <20190408085732.28684-5-abologna@redhat.com>
c313de
Reviewed-by: Laine Stump <laine@redhat.com>
c313de
Reviewed-by: Ján Tomko <jtomko@redhat.com>
c313de
---
c313de
 src/conf/device_conf.h         |   4 +
c313de
 src/conf/domain_addr.h         |   5 ++
c313de
 src/qemu/qemu_domain_address.c | 140 ++++++++++++++++++++++++++++++++-
c313de
 src/util/virpci.h              |   2 +
c313de
 4 files changed, 149 insertions(+), 2 deletions(-)
c313de
c313de
diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
c313de
index a31ce9c376..c79066ec02 100644
c313de
--- a/src/conf/device_conf.h
c313de
+++ b/src/conf/device_conf.h
c313de
@@ -164,6 +164,10 @@ struct _virDomainDeviceInfo {
c313de
      * assignment, never saved and never reported.
c313de
      */
c313de
     int pciConnectFlags; /* enum virDomainPCIConnectFlags */
c313de
+    /* pciAddrExtFlags is only used internally to calculate PCI
c313de
+     * address extension flags during address assignment.
c313de
+     */
c313de
+    int pciAddrExtFlags; /* enum virDomainPCIAddressExtensionFlags */
c313de
     char *loadparm;
c313de
 
c313de
     /* PCI devices will only be automatically placed on a PCI bus
c313de
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
c313de
index 3236b7d6de..fd06008e26 100644
c313de
--- a/src/conf/domain_addr.h
c313de
+++ b/src/conf/domain_addr.h
c313de
@@ -29,6 +29,11 @@
c313de
 # define VIR_PCI_ADDRESS_SLOT_LAST 31
c313de
 # define VIR_PCI_ADDRESS_FUNCTION_LAST 7
c313de
 
c313de
+typedef enum {
c313de
+    VIR_PCI_ADDRESS_EXTENSION_NONE = 0, /* no extension */
c313de
+    VIR_PCI_ADDRESS_EXTENSION_ZPCI = 1 << 0, /* zPCI support */
c313de
+} virPCIDeviceAddressExtensionFlags;
c313de
+
c313de
 typedef enum {
c313de
    VIR_PCI_CONNECT_HOTPLUGGABLE = 1 << 0, /* is hotplug needed/supported */
c313de
 
c313de
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
c313de
index 79d2b9f9c4..3d01d14b46 100644
c313de
--- a/src/qemu/qemu_domain_address.c
c313de
+++ b/src/qemu/qemu_domain_address.c
c313de
@@ -511,6 +511,64 @@ qemuDomainAssignARMVirtioMMIOAddresses(virDomainDefPtr def,
c313de
 }
c313de
 
c313de
 
c313de
+static bool
c313de
+qemuDomainDeviceSupportZPCI(virDomainDeviceDefPtr device)
c313de
+{
c313de
+    switch ((virDomainDeviceType)device->type) {
c313de
+    case VIR_DOMAIN_DEVICE_CHR:
c313de
+        return false;
c313de
+
c313de
+    case VIR_DOMAIN_DEVICE_CONTROLLER:
c313de
+    case VIR_DOMAIN_DEVICE_DISK:
c313de
+    case VIR_DOMAIN_DEVICE_LEASE:
c313de
+    case VIR_DOMAIN_DEVICE_FS:
c313de
+    case VIR_DOMAIN_DEVICE_NET:
c313de
+    case VIR_DOMAIN_DEVICE_INPUT:
c313de
+    case VIR_DOMAIN_DEVICE_SOUND:
c313de
+    case VIR_DOMAIN_DEVICE_VIDEO:
c313de
+    case VIR_DOMAIN_DEVICE_HOSTDEV:
c313de
+    case VIR_DOMAIN_DEVICE_WATCHDOG:
c313de
+    case VIR_DOMAIN_DEVICE_GRAPHICS:
c313de
+    case VIR_DOMAIN_DEVICE_HUB:
c313de
+    case VIR_DOMAIN_DEVICE_REDIRDEV:
c313de
+    case VIR_DOMAIN_DEVICE_SMARTCARD:
c313de
+    case VIR_DOMAIN_DEVICE_MEMBALLOON:
c313de
+    case VIR_DOMAIN_DEVICE_NVRAM:
c313de
+    case VIR_DOMAIN_DEVICE_RNG:
c313de
+    case VIR_DOMAIN_DEVICE_SHMEM:
c313de
+    case VIR_DOMAIN_DEVICE_TPM:
c313de
+    case VIR_DOMAIN_DEVICE_PANIC:
c313de
+    case VIR_DOMAIN_DEVICE_MEMORY:
c313de
+    case VIR_DOMAIN_DEVICE_IOMMU:
c313de
+    case VIR_DOMAIN_DEVICE_VSOCK:
c313de
+        break;
c313de
+
c313de
+    case VIR_DOMAIN_DEVICE_NONE:
c313de
+    case VIR_DOMAIN_DEVICE_LAST:
c313de
+    default:
c313de
+        virReportEnumRangeError(virDomainDeviceType, device->type);
c313de
+        return false;
c313de
+    }
c313de
+
c313de
+    return true;
c313de
+}
c313de
+
c313de
+
c313de
+static virPCIDeviceAddressExtensionFlags
c313de
+qemuDomainDeviceCalculatePCIAddressExtensionFlags(virQEMUCapsPtr qemuCaps,
c313de
+                                                  virDomainDeviceDefPtr dev)
c313de
+{
c313de
+    virPCIDeviceAddressExtensionFlags extFlags = 0;
c313de
+
c313de
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_ZPCI) &&
c313de
+        qemuDomainDeviceSupportZPCI(dev)) {
c313de
+        extFlags |= VIR_PCI_ADDRESS_EXTENSION_ZPCI;
c313de
+    }
c313de
+
c313de
+    return extFlags;
c313de
+}
c313de
+
c313de
+
c313de
 /**
c313de
  * qemuDomainDeviceCalculatePCIConnectFlags:
c313de
  *
c313de
@@ -993,6 +1051,56 @@ qemuDomainFillAllPCIConnectFlags(virDomainDefPtr def,
c313de
 }
c313de
 
c313de
 
c313de
+/**
c313de
+ * qemuDomainFillDevicePCIExtensionFlagsIter:
c313de
+ *
c313de
+ * @def: the entire DomainDef
c313de
+ * @dev: The device to be checked
c313de
+ * @info: virDomainDeviceInfo within the device
c313de
+ * @opaque: qemu capabilities
c313de
+ *
c313de
+ * Sets the pciAddressExtFlags for a single device's info. Has properly
c313de
+ * formatted arguments to be called by virDomainDeviceInfoIterate().
c313de
+ *
c313de
+ * Always returns 0 - there is no failure.
c313de
+ */
c313de
+static int
c313de
+qemuDomainFillDevicePCIExtensionFlagsIter(virDomainDefPtr def ATTRIBUTE_UNUSED,
c313de
+                                          virDomainDeviceDefPtr dev,
c313de
+                                          virDomainDeviceInfoPtr info,
c313de
+                                          void *opaque)
c313de
+{
c313de
+    virQEMUCapsPtr qemuCaps = opaque;
c313de
+
c313de
+    info->pciAddrExtFlags =
c313de
+        qemuDomainDeviceCalculatePCIAddressExtensionFlags(qemuCaps, dev);
c313de
+
c313de
+    return 0;
c313de
+}
c313de
+
c313de
+
c313de
+/**
c313de
+ * qemuDomainFillAllPCIExtensionFlags:
c313de
+ *
c313de
+ * @def: the entire DomainDef
c313de
+ * @qemuCaps: as you'd expect
c313de
+ *
c313de
+ * Set the info->pciAddressExtFlags for all devices in the domain.
c313de
+ *
c313de
+ * Returns 0 on success or -1 on failure (the only possibility of
c313de
+ * failure would be some internal problem with
c313de
+ * virDomainDeviceInfoIterate())
c313de
+ */
c313de
+static int
c313de
+qemuDomainFillAllPCIExtensionFlags(virDomainDefPtr def,
c313de
+                                   virQEMUCapsPtr qemuCaps)
c313de
+{
c313de
+    return virDomainDeviceInfoIterate(def,
c313de
+                                      qemuDomainFillDevicePCIExtensionFlagsIter,
c313de
+                                      qemuCaps);
c313de
+}
c313de
+
c313de
+
c313de
 /**
c313de
  * qemuDomainFindUnusedIsolationGroupIter:
c313de
  * @def: domain definition
c313de
@@ -1267,6 +1375,27 @@ qemuDomainFillDevicePCIConnectFlags(virDomainDefPtr def,
c313de
 }
c313de
 
c313de
 
c313de
+/**
c313de
+ * qemuDomainFillDevicePCIExtensionFlags:
c313de
+ *
c313de
+ * @dev: The device to be checked
c313de
+ * @info: virDomainDeviceInfo within the device
c313de
+ * @qemuCaps: as you'd expect
c313de
+ *
c313de
+ * Set the info->pciAddressExtFlags for a single device.
c313de
+ *
c313de
+ * No return value.
c313de
+ */
c313de
+static void
c313de
+qemuDomainFillDevicePCIExtensionFlags(virDomainDeviceDefPtr dev,
c313de
+                                      virDomainDeviceInfoPtr info,
c313de
+                                      virQEMUCapsPtr qemuCaps)
c313de
+{
c313de
+    info->pciAddrExtFlags =
c313de
+        qemuDomainDeviceCalculatePCIAddressExtensionFlags(qemuCaps, dev);
c313de
+}
c313de
+
c313de
+
c313de
 static int
c313de
 qemuDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs,
c313de
                                     virDomainDeviceInfoPtr dev)
c313de
@@ -2400,6 +2529,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
c313de
     if (qemuDomainFillAllPCIConnectFlags(def, qemuCaps, driver) < 0)
c313de
         goto cleanup;
c313de
 
c313de
+    if (qemuDomainFillAllPCIExtensionFlags(def, qemuCaps) < 0)
c313de
+        goto cleanup;
c313de
+
c313de
     if (qemuDomainSetupIsolationGroups(def) < 0)
c313de
         goto cleanup;
c313de
 
c313de
@@ -2435,7 +2567,8 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
c313de
              */
c313de
             virDomainDeviceInfo info = {
c313de
                 .pciConnectFlags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
c313de
-                                    VIR_PCI_CONNECT_TYPE_PCI_DEVICE)
c313de
+                                    VIR_PCI_CONNECT_TYPE_PCI_DEVICE),
c313de
+                .pciAddrExtFlags = VIR_PCI_ADDRESS_EXTENSION_NONE
c313de
             };
c313de
             bool buses_reserved = true;
c313de
 
c313de
@@ -2472,7 +2605,8 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
c313de
             qemuDomainHasPCIeRoot(def)) {
c313de
             virDomainDeviceInfo info = {
c313de
                 .pciConnectFlags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
c313de
-                                    VIR_PCI_CONNECT_TYPE_PCIE_DEVICE)
c313de
+                                    VIR_PCI_CONNECT_TYPE_PCIE_DEVICE),
c313de
+                .pciAddrExtFlags = VIR_PCI_ADDRESS_EXTENSION_NONE
c313de
             };
c313de
 
c313de
             /* if there isn't an empty pcie-root-port, this will
c313de
@@ -2989,6 +3123,8 @@ qemuDomainEnsurePCIAddress(virDomainObjPtr obj,
c313de
 
c313de
     qemuDomainFillDevicePCIConnectFlags(obj->def, dev, priv->qemuCaps, driver);
c313de
 
c313de
+    qemuDomainFillDevicePCIExtensionFlags(dev, info, priv->qemuCaps);
c313de
+
c313de
     return virDomainPCIAddressEnsureAddr(priv->pciaddrs, info,
c313de
                                          info->pciConnectFlags);
c313de
 }
c313de
diff --git a/src/util/virpci.h b/src/util/virpci.h
c313de
index 01df652b86..b366d7d9c3 100644
c313de
--- a/src/util/virpci.h
c313de
+++ b/src/util/virpci.h
c313de
@@ -49,6 +49,8 @@ struct _virPCIDeviceAddress {
c313de
     unsigned int slot;
c313de
     unsigned int function;
c313de
     int multi; /* virTristateSwitch */
c313de
+    int extFlags; /* enum virPCIDeviceAddressExtensionFlags */
c313de
+    virZPCIDeviceAddress zpci;
c313de
 };
c313de
 
c313de
 typedef enum {
c313de
-- 
c313de
2.22.0
c313de