[PATCH v1 4/9] qemu: capabilities: query and cache host-recommended CPU model

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

 



Query the host-recommended CPU model from QEMU, if it is supported. This
model will be stored in the QEMU capabilities file underneath the
closing </hostCPU> tag, labeled <hostRecCPU>. An example follows,
(shortened as to not overwhelm the commit message):

  <hostRecCPU type='kvm' model='gen16a-base' migratability='no'>
    <property name='aen' type='boolean' value='true'/>
    <property name='cmmnt' type='boolean' value='true'/>
    <property name='aefsi' type='boolean' value='true'/>
    <property name='diag318' type='boolean' value='true'/>
    <property name='csske' type='boolean' value='false'/>
    <property name='mepoch' type='boolean' value='true'/>
    <property name='msa8' type='boolean' value='true'/>
    ...
    <property name='te' type='boolean' value='false'/>
    <property name='cmm' type='boolean' value='true'/>
  </hostRecCPU>

Signed-off-by: Collin Walling <walling@xxxxxxxxxxxxx>
Reviewed-by: Boris Fiuczynski <fiuczy@xxxxxxxxxxxxx>
---
 src/conf/schemas/cputypes.rng                 |   1 +
 src/qemu/qemu_capabilities.c                  | 108 +++++++++++++++---
 src/qemu/qemu_capabilities.h                  |   3 +
 src/qemu/qemu_capspriv.h                      |   6 +-
 tests/cputest.c                               |   4 +-
 .../caps_8.1.0_s390x.replies                  |  74 ++++++++++++
 .../qemucapabilitiesdata/caps_8.1.0_s390x.xml |  54 +++++++++
 7 files changed, 231 insertions(+), 19 deletions(-)

diff --git a/src/conf/schemas/cputypes.rng b/src/conf/schemas/cputypes.rng
index db1aa57158..5e89d67c8e 100644
--- a/src/conf/schemas/cputypes.rng
+++ b/src/conf/schemas/cputypes.rng
@@ -10,6 +10,7 @@
         <value>host-model</value>
         <value>host-passthrough</value>
         <value>maximum</value>
+        <value>host-recommended</value>
       </choice>
     </attribute>
   </define>
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 40cdcffbfe..59403808ee 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -724,6 +724,11 @@ struct _virQEMUCapsHostCPUData {
     qemuMonitorCPUModelInfo *info;
     /* Physical address size of the host CPU or 0 if unknown or not applicable. */
     unsigned int physAddrSize;
+    /* Host CPU model with delta changes reported by the hypervisor to ensure
+     * migration compatibility with newer machines that may exclude certain
+     * features available on older machines.
+     */
+    qemuMonitorCPUModelInfo *hostRec;
     /* Host CPU definition reported in domain capabilities. */
     virCPUDef *reported;
     /* Migratable host CPU definition used for updating guest CPU. */
@@ -732,6 +737,8 @@ struct _virQEMUCapsHostCPUData {
      * combined with features reported by QEMU. This is used for backward
      * compatible comparison between a guest CPU and a host CPU. */
     virCPUDef *full;
+    /* CPU definition converted from hostRec model info */
+    virCPUDef *recommended;
 };
 
 typedef struct _virQEMUCapsAccel virQEMUCapsAccel;
@@ -1834,6 +1841,12 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUData *dst,
 
     if (src->full)
         dst->full = virCPUDefCopy(src->full);
+
+    if (src->hostRec)
+        dst->hostRec = qemuMonitorCPUModelInfoCopy(src->hostRec);
+
+    if (src->recommended)
+        dst->recommended = virCPUDefCopy(src->recommended);
 }
 
 
@@ -1841,9 +1854,11 @@ static void
 virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUData *cpuData)
 {
     qemuMonitorCPUModelInfoFree(cpuData->info);
+    qemuMonitorCPUModelInfoFree(cpuData->hostRec);
     virCPUDefFree(cpuData->reported);
     virCPUDefFree(cpuData->migratable);
     virCPUDefFree(cpuData->full);
+    virCPUDefFree(cpuData->recommended);
 
     memset(cpuData, 0, sizeof(*cpuData));
 }
@@ -2190,6 +2205,9 @@ virQEMUCapsGetHostModel(virQEMUCaps *qemuCaps,
         /* 'full' is non-NULL only if we have data from both QEMU and
          * virCPUGetHost */
         return cpuData->full ? cpuData->full : cpuData->reported;
+
+    case VIR_QEMU_CAPS_HOST_CPU_RECOMMENDED:
+        return cpuData->recommended;
     }
 
     return NULL;
@@ -2202,7 +2220,8 @@ virQEMUCapsSetHostModel(virQEMUCaps *qemuCaps,
                         unsigned int physAddrSize,
                         virCPUDef *reported,
                         virCPUDef *migratable,
-                        virCPUDef *full)
+                        virCPUDef *full,
+                        virCPUDef *recommended)
 {
     virQEMUCapsHostCPUData *cpuData;
 
@@ -2211,6 +2230,7 @@ virQEMUCapsSetHostModel(virQEMUCaps *qemuCaps,
     cpuData->reported = reported;
     cpuData->migratable = migratable;
     cpuData->full = full;
+    cpuData->recommended = recommended;
 }
 
 
@@ -3048,6 +3068,7 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCaps *qemuCaps,
 {
     const char *model = virQEMUCapsTypeIsAccelerated(virtType) ? "host" : "max";
     g_autoptr(qemuMonitorCPUModelInfo) modelInfo = NULL;
+    g_autoptr(qemuMonitorCPUModelInfo) hostRecInfo = NULL;
     g_autoptr(qemuMonitorCPUModelInfo) nonMigratable = NULL;
     g_autoptr(virCPUDef) cpu = NULL;
     qemuMonitorCPUModelExpansionType type;
@@ -3133,6 +3154,19 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCaps *qemuCaps,
             return -1;
     }
 
+    /* Retrieve the hypervisor recommended host CPU */
+    if (virQEMUCapsTypeIsAccelerated(virtType) &&
+        ARCH_IS_S390(qemuCaps->arch) &&
+        virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_STATIC_RECOMMENDED)) {
+        type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC_REC;
+
+        if (qemuMonitorGetCPUModelExpansion(mon, type, cpu, true, false, fail_no_props,
+                                            &hostRecInfo) < 0)
+            return -1;
+
+        accel->hostCPU.hostRec = g_steal_pointer(&hostRecInfo);
+    }
+
     accel->hostCPU.info = g_steal_pointer(&modelInfo);
     return 0;
 }
@@ -3157,7 +3191,7 @@ virQEMUCapsGetCPUFeatures(virQEMUCaps *qemuCaps,
     size_t n;
 
     *features = NULL;
-    modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, virtType);
+    modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, virtType, false);
 
     if (!modelInfo)
         return 0;
@@ -3725,14 +3759,19 @@ int
 virQEMUCapsInitCPUModel(virQEMUCaps *qemuCaps,
                         virDomainVirtType type,
                         virCPUDef *cpu,
-                        bool migratable)
+                        bool migratable,
+                        bool recommended)
 {
-    qemuMonitorCPUModelInfo *modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, type);
+    qemuMonitorCPUModelInfo *modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, type,
+                                                                    recommended);
     int ret = 1;
 
     if (migratable && modelInfo && !modelInfo->migratability)
         return 1;
 
+    if (recommended && !modelInfo)
+        return 2;
+
     if (ARCH_IS_S390(qemuCaps->arch)) {
         ret = virQEMUCapsInitCPUModelS390(qemuCaps, type, modelInfo,
                                           cpu, migratable);
@@ -3775,6 +3814,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
     virCPUDef *hostCPU = NULL;
     virCPUDef *fullCPU = NULL;
     unsigned int physAddrSize = 0;
+    virCPUDef *recCPU = NULL;
     size_t i;
     int rc;
 
@@ -3784,7 +3824,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
     if (!(cpu = virQEMUCapsNewHostCPUModel()))
         goto error;
 
-    if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
+    if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false, false)) < 0) {
         goto error;
     } else if (rc == 1) {
         g_autoptr(virDomainCapsCPUModels) cpuModels = NULL;
@@ -3823,7 +3863,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
     if (!(migCPU = virQEMUCapsNewHostCPUModel()))
         goto error;
 
-    if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0) {
+    if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true, false)) < 0) {
         goto error;
     } else if (rc == 1) {
         VIR_DEBUG("CPU migratability not provided by QEMU");
@@ -3833,6 +3873,17 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
             goto error;
     }
 
+    if (!(recCPU = virQEMUCapsNewHostCPUModel()))
+        goto error;
+
+    if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, recCPU, false, true)) < 0) {
+        goto error;
+    } else if (rc == 2) {
+        VIR_DEBUG("CPU reccomendation not provided by QEMU");
+        virCPUDefFree(recCPU);
+        recCPU = NULL;
+    }
+
     if (ARCH_IS_X86(qemuCaps->arch) &&
         !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_UNAVAILABLE_FEATURES)) {
         if (cpu &&
@@ -3851,7 +3902,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
     if (virQEMUCapsTypeIsAccelerated(type))
         virHostCPUGetPhysAddrSize(hostArch, &physAddrSize);
 
-    virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize, cpu, migCPU, fullCPU);
+    virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize, cpu, migCPU, fullCPU, recCPU);
 
  cleanup:
     virCPUDefFree(cpuExpanded);
@@ -3862,6 +3913,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
     virCPUDefFree(cpu);
     virCPUDefFree(migCPU);
     virCPUDefFree(fullCPU);
+    virCPUDefFree(recCPU);
     virResetLastError();
     goto cleanup;
 }
@@ -3878,8 +3930,12 @@ virQEMUCapsUpdateHostCPUModel(virQEMUCaps *qemuCaps,
 
 qemuMonitorCPUModelInfo *
 virQEMUCapsGetCPUModelInfo(virQEMUCaps *qemuCaps,
-                           virDomainVirtType type)
+                           virDomainVirtType type,
+                           bool recommended)
 {
+    if (recommended)
+        return virQEMUCapsGetAccel(qemuCaps, type)->hostCPU.hostRec;
+
     return virQEMUCapsGetAccel(qemuCaps, type)->hostCPU.info;
 }
 
@@ -4006,6 +4062,17 @@ virQEMUCapsLoadHostCPUModelInfo(virQEMUCapsAccel *caps,
 }
 
 
+static int
+virQEMUCapsLoadHostRecCPUModelInfo(virQEMUCapsAccel *caps,
+                                   xmlXPathContextPtr ctxt,
+                                   const char *typeStr)
+{
+    g_autofree char *xpath = g_strdup_printf("./hostRecCPU[@type='%s']", typeStr);
+
+    return virQEMUCapsLoadCPUModelInfo(&caps->hostCPU.hostRec, ctxt, xpath);
+}
+
+
 static int
 virQEMUCapsLoadCPUModels(virArch arch,
                          virQEMUCapsAccel *caps,
@@ -4169,6 +4236,10 @@ virQEMUCapsLoadAccel(virQEMUCaps *qemuCaps,
     if (virQEMUCapsLoadHostCPUModelInfo(caps, ctxt, typeStr) < 0)
         return -1;
 
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_STATIC_RECOMMENDED) &&
+        virQEMUCapsLoadHostRecCPUModelInfo(caps, ctxt, typeStr) < 0)
+        return -1;
+
     if (virQEMUCapsLoadCPUModels(qemuCaps->arch, caps, ctxt, typeStr) < 0)
         return -1;
 
@@ -4705,18 +4776,24 @@ virQEMUCapsLoadCache(virArch hostArch,
 static void
 virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsAccel *caps,
                                   virBuffer *buf,
-                                  const char *typeStr)
+                                  const char *typeStr,
+                                  bool recommended)
 {
-    qemuMonitorCPUModelInfo *model = caps->hostCPU.info;
+    qemuMonitorCPUModelInfo *model;
     size_t i;
 
+    if (recommended)
+        model = caps->hostCPU.hostRec;
+    else
+        model = caps->hostCPU.info;
+
     if (!model)
         return;
 
     virBufferAsprintf(buf,
-                      "<hostCPU type='%s' model='%s' migratability='%s'>\n",
-                      typeStr, model->name,
-                      model->migratability ? "yes" : "no");
+                      "<%s type='%s' model='%s' migratability='%s'>\n",
+                      recommended ? "hostRecCPU" : "hostCPU", typeStr,
+                      model->name, model->migratability ? "yes" : "no");
     virBufferAdjustIndent(buf, 2);
 
     for (i = 0; i < model->nprops; i++) {
@@ -4752,7 +4829,7 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsAccel *caps,
     }
 
     virBufferAdjustIndent(buf, -2);
-    virBufferAddLit(buf, "</hostCPU>\n");
+    virBufferAsprintf(buf, "</%s>\n", recommended ? "hostRecCPU" : "hostCPU");
 }
 
 
@@ -4846,7 +4923,8 @@ virQEMUCapsFormatAccel(virQEMUCaps *qemuCaps,
     virQEMUCapsAccel *caps = virQEMUCapsGetAccel(qemuCaps, type);
     const char *typeStr = virQEMUCapsAccelStr(type);
 
-    virQEMUCapsFormatHostCPUModelInfo(caps, buf, typeStr);
+    virQEMUCapsFormatHostCPUModelInfo(caps, buf, typeStr, false);
+    virQEMUCapsFormatHostCPUModelInfo(caps, buf, typeStr, true);
     virQEMUCapsFormatCPUModels(qemuCaps->arch, caps, buf, typeStr);
     virQEMUCapsFormatMachines(caps, buf, typeStr);
 
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 4fa64b6435..bb68b74328 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -726,6 +726,9 @@ typedef enum {
      * combined with features reported by QEMU. This is used for backward
      * compatible comparison between a guest CPU and a host CPU. */
     VIR_QEMU_CAPS_HOST_CPU_FULL,
+    /* Host CPU definition with a modified feature set based on dropped
+     * features on newer CPU models. */
+    VIR_QEMU_CAPS_HOST_CPU_RECOMMENDED,
 } virQEMUCapsHostCPUType;
 
 virCPUDef *virQEMUCapsGetHostModel(virQEMUCaps *qemuCaps,
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
index 06b36d2eb8..a97710eecf 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -64,11 +64,13 @@ int
 virQEMUCapsInitCPUModel(virQEMUCaps *qemuCaps,
                         virDomainVirtType type,
                         virCPUDef *cpu,
-                        bool migratable);
+                        bool migratable,
+                        bool recommended);
 
 qemuMonitorCPUModelInfo *
 virQEMUCapsGetCPUModelInfo(virQEMUCaps *qemuCaps,
-                           virDomainVirtType type);
+                           virDomainVirtType type,
+                           bool recommended);
 
 void
 virQEMUCapsSetCPUModelInfo(virQEMUCaps *qemuCaps,
diff --git a/tests/cputest.c b/tests/cputest.c
index b3253e3116..8d3a0dd4d9 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -857,7 +857,7 @@ cpuTestJSONCPUID(const void *arg)
     cpu->match = VIR_CPU_MATCH_EXACT;
     cpu->fallback = VIR_CPU_FALLBACK_FORBID;
 
-    if (virQEMUCapsInitCPUModel(qemuCaps, VIR_DOMAIN_VIRT_KVM, cpu, false) != 0)
+    if (virQEMUCapsInitCPUModel(qemuCaps, VIR_DOMAIN_VIRT_KVM, cpu, false, false) != 0)
         return -1;
 
     return cpuTestCompareXML(data->arch, cpu, result);
@@ -875,7 +875,7 @@ cpuTestJSONSignature(const void *arg)
     if (!(qemuCaps = cpuTestMakeQEMUCaps(data)))
         return -1;
 
-    modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, VIR_DOMAIN_VIRT_KVM);
+    modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, VIR_DOMAIN_VIRT_KVM, false);
     if (!(hostData = virQEMUCapsGetCPUModelX86Data(qemuCaps, modelInfo, false)))
         return -1;
 
diff --git a/tests/qemucapabilitiesdata/caps_8.1.0_s390x.replies b/tests/qemucapabilitiesdata/caps_8.1.0_s390x.replies
index 8cd7312bea..2720408726 100644
--- a/tests/qemucapabilitiesdata/caps_8.1.0_s390x.replies
+++ b/tests/qemucapabilitiesdata/caps_8.1.0_s390x.replies
@@ -29649,6 +29649,80 @@
   "id": "libvirt-37"
 }
 
+{
+  "execute": "query-cpu-model-expansion",
+  "arguments": {
+    "type": "static-recommended",
+    "model": {
+      "name": "host"
+    }
+  },
+  "id": "libvirt-38"
+}
+
+{
+  "return": {
+    "model": {
+      "name": "gen16a-base",
+      "props": {
+        "nnpa": true,
+        "aen": true,
+        "cmmnt": true,
+        "vxpdeh": true,
+        "aefsi": true,
+        "diag318": true,
+        "csske": false,
+        "mepoch": true,
+        "msa9": true,
+        "msa8": true,
+        "msa7": true,
+        "msa6": true,
+        "msa5": true,
+        "msa4": true,
+        "msa3": true,
+        "msa2": true,
+        "msa1": true,
+        "sthyi": true,
+        "edat": true,
+        "ri": true,
+        "deflate": true,
+        "edat2": true,
+        "etoken": true,
+        "vx": true,
+        "ipter": true,
+        "pai": true,
+        "paie": true,
+        "mepochptff": true,
+        "ap": true,
+        "vxeh": true,
+        "vxpd": true,
+        "esop": true,
+        "msa9_pckmo": true,
+        "vxeh2": true,
+        "esort": true,
+        "apqi": true,
+        "apft": true,
+        "els": true,
+        "iep": true,
+        "apqci": true,
+        "cte": false,
+        "ais": true,
+        "bpb": false,
+        "gs": true,
+        "ppa15": true,
+        "zpci": true,
+        "rdp": true,
+        "sea_esop2": true,
+        "beareh": true,
+        "te": false,
+        "cmm": true,
+        "vxpdeh2": true
+      }
+    }
+  },
+  "id": "libvirt-38"
+}
+
 {
   "execute": "qmp_capabilities",
   "id": "libvirt-1"
diff --git a/tests/qemucapabilitiesdata/caps_8.1.0_s390x.xml b/tests/qemucapabilitiesdata/caps_8.1.0_s390x.xml
index 0bb4233383..c580cbb5b0 100644
--- a/tests/qemucapabilitiesdata/caps_8.1.0_s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_8.1.0_s390x.xml
@@ -171,6 +171,60 @@
     <property name='cmm' type='boolean' value='true'/>
     <property name='vxpdeh2' type='boolean' value='true'/>
   </hostCPU>
+  <hostRecCPU type='kvm' model='gen16a-base' migratability='no'>
+    <property name='nnpa' type='boolean' value='true'/>
+    <property name='aen' type='boolean' value='true'/>
+    <property name='cmmnt' type='boolean' value='true'/>
+    <property name='vxpdeh' type='boolean' value='true'/>
+    <property name='aefsi' type='boolean' value='true'/>
+    <property name='diag318' type='boolean' value='true'/>
+    <property name='csske' type='boolean' value='false'/>
+    <property name='mepoch' type='boolean' value='true'/>
+    <property name='msa9' type='boolean' value='true'/>
+    <property name='msa8' type='boolean' value='true'/>
+    <property name='msa7' type='boolean' value='true'/>
+    <property name='msa6' type='boolean' value='true'/>
+    <property name='msa5' type='boolean' value='true'/>
+    <property name='msa4' type='boolean' value='true'/>
+    <property name='msa3' type='boolean' value='true'/>
+    <property name='msa2' type='boolean' value='true'/>
+    <property name='msa1' type='boolean' value='true'/>
+    <property name='sthyi' type='boolean' value='true'/>
+    <property name='edat' type='boolean' value='true'/>
+    <property name='ri' type='boolean' value='true'/>
+    <property name='deflate' type='boolean' value='true'/>
+    <property name='edat2' type='boolean' value='true'/>
+    <property name='etoken' type='boolean' value='true'/>
+    <property name='vx' type='boolean' value='true'/>
+    <property name='ipter' type='boolean' value='true'/>
+    <property name='pai' type='boolean' value='true'/>
+    <property name='paie' type='boolean' value='true'/>
+    <property name='mepochptff' type='boolean' value='true'/>
+    <property name='ap' type='boolean' value='true'/>
+    <property name='vxeh' type='boolean' value='true'/>
+    <property name='vxpd' type='boolean' value='true'/>
+    <property name='esop' type='boolean' value='true'/>
+    <property name='msa9_pckmo' type='boolean' value='true'/>
+    <property name='vxeh2' type='boolean' value='true'/>
+    <property name='esort' type='boolean' value='true'/>
+    <property name='apqi' type='boolean' value='true'/>
+    <property name='apft' type='boolean' value='true'/>
+    <property name='els' type='boolean' value='true'/>
+    <property name='iep' type='boolean' value='true'/>
+    <property name='apqci' type='boolean' value='true'/>
+    <property name='cte' type='boolean' value='false'/>
+    <property name='ais' type='boolean' value='true'/>
+    <property name='bpb' type='boolean' value='false'/>
+    <property name='gs' type='boolean' value='true'/>
+    <property name='ppa15' type='boolean' value='true'/>
+    <property name='zpci' type='boolean' value='true'/>
+    <property name='rdp' type='boolean' value='true'/>
+    <property name='sea_esop2' type='boolean' value='true'/>
+    <property name='beareh' type='boolean' value='true'/>
+    <property name='te' type='boolean' value='false'/>
+    <property name='cmm' type='boolean' value='true'/>
+    <property name='vxpdeh2' type='boolean' value='true'/>
+  </hostRecCPU>
   <cpu type='kvm' name='gen16a-base' typename='gen16a-base-s390x-cpu' usable='yes'/>
   <cpu type='kvm' name='gen16a' typename='gen16a-s390x-cpu' usable='yes'/>
   <cpu type='kvm' name='z800-base' typename='z800-base-s390x-cpu' usable='yes'/>
-- 
2.41.0




[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