[libvirt] [PATCHv2 11/11] qemu_driver: BaselineHypervisorCPU supports S390 using QEMU/QMP

Chris Venteicher cventeic at redhat.com
Tue Jul 10 03:56:55 UTC 2018


Transient S390 configurations require using QEMU to compute CPU Model
Baseline and to do CPU Feature Expansion.

Start and use a single QEMU instance to do both the baseline and
expansion transactions required by BaselineHypervisorCPU.

CPU Feature Expansion uses true / false to indicate if property is/isn't
included in model. Baseline only returns property list where all
enumerated properties are included.
---
 src/qemu/qemu_driver.c | 74 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 65 insertions(+), 9 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9a35e04a85..6c6107f077 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13400,10 +13400,13 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
     virArch arch;
     virDomainVirtType virttype;
     virDomainCapsCPUModelsPtr cpuModels;
-    bool migratable;
+    bool migratable_only;
     virCPUDefPtr cpu = NULL;
     char *cpustr = NULL;
     char **features = NULL;
+    virQEMUCapsInitQMPCommandPtr cmd = NULL;
+    bool forceTCG = false;
+    qemuMonitorCPUModelInfoPtr modelInfo = NULL;
 
     virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
                   VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL);
@@ -13411,8 +13414,6 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
     if (virConnectBaselineHypervisorCPUEnsureACL(conn) < 0)
         goto cleanup;
 
-    migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
-
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_AUTO)))
         goto cleanup;
 
@@ -13425,6 +13426,19 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
     if (!qemuCaps)
         goto cleanup;
 
+    /* QEMU can enumerate non-migratable cpu model features for some archs like x86
+     * migratable_only == true:  ask for and include only migratable features
+     * migratable_only == false: ask for and include all features
+     */
+    migratable_only = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
+
+    if (ARCH_IS_S390(arch)) {
+       /* QEMU for S390 arch only enumerates migratable features
+        * No reason to explicitly ask QEMU for or include non-migratable features
+        */
+       migratable_only = true;
+    }
+
     if (!(cpuModels = virQEMUCapsGetCPUDefinitions(qemuCaps, virttype)) ||
         cpuModels->nmodels == 0) {
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
@@ -13437,18 +13451,31 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 
     if (ARCH_IS_X86(arch)) {
         int rc = virQEMUCapsGetCPUFeatures(qemuCaps, virttype,
-                                           migratable, &features);
+                                           migratable_only, &features);
         if (rc < 0)
             goto cleanup;
         if (features && rc == 0) {
             /* We got only migratable features from QEMU if we asked for them,
              * no further filtering in virCPUBaseline is desired. */
-            migratable = false;
+            migratable_only = false;
         }
 
         if (!(cpu = virCPUBaseline(arch, cpus, ncpus, cpuModels,
-                                   (const char **)features, migratable)))
+                                   (const char **)features, migratable_only)))
             goto cleanup;
+    } else if (ARCH_IS_S390(arch)) {
+
+       const char *binary = virQEMUCapsGetBinary(qemuCaps);
+       virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
+       if (!(cmd = virQEMUCapsNewQMPCommandConnection(binary, cfg->libDir,
+                                                      cfg->user, cfg->group,
+                                                      forceTCG)))
+          goto cleanup;
+
+       if ((virQEMUCapsQMPBaselineCPUModel(cmd, cpus, &cpu) < 0) || !cpu)
+          goto cleanup; /* Content Error */
+
     } else {
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("computing baseline hypervisor CPU is not supported "
@@ -13458,9 +13485,36 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 
     cpu->fallback = VIR_CPU_FALLBACK_FORBID;
 
-    if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
-        virCPUExpandFeatures(arch, cpu) < 0)
-        goto cleanup;
+    if (flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) {
+       if (ARCH_IS_X86(arch)) {
+          if (virCPUExpandFeatures(arch, cpu) < 0)
+             goto cleanup;
+       } else if (ARCH_IS_S390(arch)) {
+
+          if (!(modelInfo = virQEMUCapsCPUModelInfoFromCPUDef(cpu)))
+             goto cleanup;
+
+          virCPUDefFree(cpu); /* Null on failure, repopulated on success */
+
+          if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) {
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                            _("Feature Expansion not supported with this QEMU binary"));
+             goto cleanup;
+          }
+
+          if (qemuMonitorGetCPUModelExpansion(cmd->mon,
+                                              QEMU_MONITOR_CPU_MODEL_EXPANSION_FULL,
+                                              migratable_only, modelInfo) < 0)
+             goto cleanup;
+
+          /* Expansion enumerates all features
+           * Baseline reply enumerates only in-model (true) features */
+          qemuMonitorCPUModelInfoRemovePropByBoolValue(modelInfo, false);
+
+          if (!(cpu = virQEMUCapsCPUModelInfoToCPUDef(migratable_only, modelInfo)))
+             goto cleanup;
+       }
+    }
 
     cpustr = virCPUDefFormat(cpu, NULL);
 
@@ -13469,6 +13523,8 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
     virCPUDefFree(cpu);
     virObjectUnref(qemuCaps);
     virStringListFree(features);
+    virQEMUCapsInitQMPCommandFree(cmd);
+    qemuMonitorCPUModelInfoFree(modelInfo);
 
     return cpustr;
 }
-- 
2.17.1




More information about the libvir-list mailing list