[libvirt] [PATCH v2 02/45] domcaps: Add support for listing supported CPU models

Jiri Denemark jdenemar at redhat.com
Mon Sep 19 13:30:11 UTC 2016


The patch adds <cpu> element to domain capabilities XML:

    <cpu>
        <mode name='host-passthrough' supported='yes'/>
        <mode name='host-model' supported='yes'/>
        <mode name='custom' supported='yes'>
            <model>Broadwell</model>
            <model>Broadwell-noTSX</model>
            ...
        </mode>
    </cpu>

Applications can use it to inspect what CPU configuration modes are
supported for a specific combination of domain type, emulator binary,
guest architecture and machine type.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---

Notes:
    Version 2:
    - switched to VIR_STEAL_PTR
    - s/alloc/nmodels_max/ and s/count/nmodels/
    - added cross reference to formatdomain.html#elementsCPU

 docs/formatdomaincaps.html.in                      |  44 ++++++
 docs/schemas/domaincaps.rng                        |  43 ++++++
 src/conf/domain_capabilities.c                     | 149 +++++++++++++++++++++
 src/conf/domain_capabilities.h                     |  33 +++++
 src/libvirt_private.syms                           |   4 +
 tests/domaincapsschemadata/basic.xml               |   5 +
 tests/domaincapsschemadata/full.xml                |   9 ++
 tests/domaincapsschemadata/libxl-xenfv-usb.xml     |   5 +
 tests/domaincapsschemadata/libxl-xenfv.xml         |   5 +
 tests/domaincapsschemadata/libxl-xenpv-usb.xml     |   5 +
 tests/domaincapsschemadata/libxl-xenpv.xml         |   5 +
 tests/domaincapsschemadata/qemu_1.7.0.x86_64.xml   |   5 +
 .../qemu_2.6.0-gicv2-virt.aarch64.xml              |   5 +
 .../qemu_2.6.0-gicv3-virt.aarch64.xml              |   5 +
 tests/domaincapsschemadata/qemu_2.6.0.aarch64.xml  |   5 +
 tests/domaincapsschemadata/qemu_2.6.0.ppc64le.xml  |   5 +
 tests/domaincapsschemadata/qemu_2.6.0.x86_64.xml   |   5 +
 tests/domaincapstest.c                             |   9 ++
 18 files changed, 346 insertions(+)

diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in
index d5a8414..ce43658 100644
--- a/docs/formatdomaincaps.html.in
+++ b/docs/formatdomaincaps.html.in
@@ -142,6 +142,50 @@
       <loader/> element.</dd>
     </dl>
 
+    <h3><a name="elementsCPU">CPU configuration</a></h3>
+
+    <p>
+      The <code>cpu</code> element exposes options usable for configuring
+      <a href="formatdomain.html#elementsCPU">guest CPUs</a>.
+    </p>
+
+<pre>
+<domainCapabilities>
+  ...
+  <cpu>
+    <mode name='host-passthrough' supported='yes'/>
+    <mode name='host-model' supported='yes'/>
+    <mode name='custom' supported='yes'>
+      <model>Broadwell</model>
+      <model>Broadwell-noTSX</model>
+      <model>Haswell</model>
+      ...
+    </mode>
+  </cpu>
+  ...
+<domainCapabilities>
+</pre>
+
+    <p>
+      Each CPU mode understood by libvirt is described with a
+      <code>mode</code> element which tells whether the particular mode
+      is supported and provides (when applicable) more details about it:
+    </p>
+
+    <dl>
+      <dt><code>host-passthrough</code></dt>
+      <dd>No mode specific details are provided.</dd>
+
+      <dt><code>host-model</code></dt>
+      <dd>No mode specific details are provided yet.</dd>
+
+      <dt><code>custom</code></dt>
+      <dd>
+        The <code>mode</code> element contains a list of supported CPU
+        models, each described by a dedicated <code>model</code> element.
+      </dd>
+    </dl>
+
     <h3><a name="elementsDevices">Devices</a></h3>
 
     <p>
diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng
index 97da41f..9f3d225 100644
--- a/docs/schemas/domaincaps.rng
+++ b/docs/schemas/domaincaps.rng
@@ -29,6 +29,9 @@
           <ref name='os'/>
         </optional>
         <optional>
+          <ref name='cpu'/>
+        </optional>
+        <optional>
           <ref name='devices'/>
         </optional>
         <optional>
@@ -68,6 +71,46 @@
     </element>
   </define>
 
+  <define name='cpu'>
+    <element name='cpu'>
+      <ref name='cpuHost'/>
+      <ref name='cpuHostModel'/>
+      <ref name='cpuCustom'/>
+    </element>
+  </define>
+
+  <define name='cpuHost'>
+    <element name='mode'>
+      <attribute name='name'>
+        <value>host-passthrough</value>
+      </attribute>
+      <ref name='supported'/>
+    </element>
+  </define>
+
+  <define name='cpuHostModel'>
+    <element name='mode'>
+      <attribute name='name'>
+        <value>host-model</value>
+      </attribute>
+      <ref name='supported'/>
+    </element>
+  </define>
+
+  <define name='cpuCustom'>
+    <element name='mode'>
+      <attribute name='name'>
+        <value>custom</value>
+      </attribute>
+      <ref name='supported'/>
+      <zeroOrMore>
+        <element name='model'>
+          <text/>
+        </element>
+      </zeroOrMore>
+    </element>
+  </define>
+
   <define name='devices'>
     <element name='devices'>
       <interleave>
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index 1676f0e..e47aa86 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -30,8 +30,10 @@
 #define VIR_FROM_THIS VIR_FROM_CAPABILITIES
 
 static virClassPtr virDomainCapsClass;
+static virClassPtr virDomainCapsCPUModelsClass;
 
 static void virDomainCapsDispose(void *obj);
+static void virDomainCapsCPUModelsDispose(void *obj);
 
 static int virDomainCapsOnceInit(void)
 {
@@ -40,6 +42,14 @@ static int virDomainCapsOnceInit(void)
                                            sizeof(virDomainCaps),
                                            virDomainCapsDispose)))
         return -1;
+
+    virDomainCapsCPUModelsClass = virClassNew(virClassForObject(),
+                                              "virDomainCapsCPUModelsClass",
+                                              sizeof(virDomainCapsCPUModels),
+                                              virDomainCapsCPUModelsDispose);
+    if (!virDomainCapsCPUModelsClass)
+        return -1;
+
     return 0;
 }
 
@@ -68,11 +78,25 @@ virDomainCapsDispose(void *obj)
 
     VIR_FREE(caps->path);
     VIR_FREE(caps->machine);
+    virObjectUnref(caps->cpu.custom);
 
     virDomainCapsStringValuesFree(&caps->os.loader.values);
 }
 
 
+static void
+virDomainCapsCPUModelsDispose(void *obj)
+{
+    virDomainCapsCPUModelsPtr cpuModels = obj;
+    size_t i;
+
+    for (i = 0; i < cpuModels->nmodels; i++)
+        VIR_FREE(cpuModels->models[i].name);
+
+    VIR_FREE(cpuModels->models);
+}
+
+
 virDomainCapsPtr
 virDomainCapsNew(const char *path,
                  const char *machine,
@@ -100,6 +124,85 @@ virDomainCapsNew(const char *path,
 }
 
 
+virDomainCapsCPUModelsPtr
+virDomainCapsCPUModelsNew(size_t nmodels)
+{
+    virDomainCapsCPUModelsPtr cpuModels = NULL;
+
+    if (virDomainCapsInitialize() < 0)
+        return NULL;
+
+    if (!(cpuModels = virObjectNew(virDomainCapsCPUModelsClass)))
+        return NULL;
+
+    if (VIR_ALLOC_N(cpuModels->models, nmodels) < 0)
+        goto error;
+    cpuModels->nmodels_max = nmodels;
+
+    return cpuModels;
+
+ error:
+    virObjectUnref(cpuModels);
+    return NULL;
+}
+
+
+virDomainCapsCPUModelsPtr
+virDomainCapsCPUModelsCopy(virDomainCapsCPUModelsPtr old)
+{
+    virDomainCapsCPUModelsPtr cpuModels;
+    size_t i;
+
+    if (!(cpuModels = virDomainCapsCPUModelsNew(old->nmodels)))
+        return NULL;
+
+    for (i = 0; i < old->nmodels; i++) {
+        if (virDomainCapsCPUModelsAdd(cpuModels, old->models[i].name, -1) < 0)
+            goto error;
+    }
+
+    return cpuModels;
+
+ error:
+    virObjectUnref(cpuModels);
+    return NULL;
+}
+
+
+int
+virDomainCapsCPUModelsAddSteal(virDomainCapsCPUModelsPtr cpuModels,
+                               char **name)
+{
+    if (VIR_RESIZE_N(cpuModels->models, cpuModels->nmodels_max,
+                     cpuModels->nmodels, 1) < 0)
+        return -1;
+
+    VIR_STEAL_PTR(cpuModels->models[cpuModels->nmodels++].name, *name);
+    return 0;
+}
+
+
+int
+virDomainCapsCPUModelsAdd(virDomainCapsCPUModelsPtr cpuModels,
+                          const char *name,
+                          ssize_t nameLen)
+{
+    char *copy = NULL;
+
+    if (VIR_STRNDUP(copy, name, nameLen) < 0)
+        goto error;
+
+    if (virDomainCapsCPUModelsAddSteal(cpuModels, &copy) < 0)
+        goto error;
+
+    return 0;
+
+ error:
+    VIR_FREE(copy);
+    return -1;
+}
+
+
 int
 virDomainCapsEnumSet(virDomainCapsEnumPtr capsEnum,
                      const char *capsEnumName,
@@ -234,6 +337,51 @@ virDomainCapsOSFormat(virBufferPtr buf,
 }
 
 static void
+virDomainCapsCPUCustomFormat(virBufferPtr buf,
+                             virDomainCapsCPUModelsPtr custom)
+{
+    size_t i;
+
+    virBufferAdjustIndent(buf, 2);
+
+    for (i = 0; i < custom->nmodels; i++) {
+        virBufferAsprintf(buf, "<model>%s</model>\n",
+                          custom->models[i].name);
+    }
+
+    virBufferAdjustIndent(buf, -2);
+}
+
+static void
+virDomainCapsCPUFormat(virBufferPtr buf,
+                       virDomainCapsCPUPtr cpu)
+{
+    virBufferAddLit(buf, "<cpu>\n");
+    virBufferAdjustIndent(buf, 2);
+
+    virBufferAsprintf(buf, "<mode name='%s' supported='%s'/>\n",
+                      virCPUModeTypeToString(VIR_CPU_MODE_HOST_PASSTHROUGH),
+                      cpu->hostPassthrough ? "yes" : "no");
+
+    virBufferAsprintf(buf, "<mode name='%s' supported='%s'/>\n",
+                      virCPUModeTypeToString(VIR_CPU_MODE_HOST_MODEL),
+                      cpu->hostModel ? "yes" : "no");
+
+    virBufferAsprintf(buf, "<mode name='%s' ",
+                      virCPUModeTypeToString(VIR_CPU_MODE_CUSTOM));
+    if (cpu->custom && cpu->custom->nmodels) {
+        virBufferAddLit(buf, "supported='yes'>\n");
+        virDomainCapsCPUCustomFormat(buf, cpu->custom);
+        virBufferAddLit(buf, "</mode>\n");
+    } else {
+        virBufferAddLit(buf, "supported='no'/>\n");
+    }
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</cpu>\n");
+}
+
+static void
 virDomainCapsDeviceDiskFormat(virBufferPtr buf,
                               virDomainCapsDeviceDiskPtr const disk)
 {
@@ -333,6 +481,7 @@ virDomainCapsFormatInternal(virBufferPtr buf,
         virBufferAsprintf(buf, "<vcpu max='%d'/>\n", caps->maxvcpus);
 
     virDomainCapsOSFormat(buf, &caps->os);
+    virDomainCapsCPUFormat(buf, &caps->cpu);
 
     virBufferAddLit(buf, "<devices>\n");
     virBufferAdjustIndent(buf, 2);
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index 492a9cf..149a13f 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -102,6 +102,30 @@ struct _virDomainCapsFeatureGIC {
     virDomainCapsEnum version; /* Info about virGICVersion */
 };
 
+typedef struct _virDomainCapsCPUModel virDomainCapsCPUModel;
+typedef virDomainCapsCPUModel *virDomainCapsCPUModelPtr;
+struct _virDomainCapsCPUModel {
+    char *name;
+};
+
+typedef struct _virDomainCapsCPUModels virDomainCapsCPUModels;
+typedef virDomainCapsCPUModels *virDomainCapsCPUModelsPtr;
+struct _virDomainCapsCPUModels {
+    virObject parent;
+
+    size_t nmodels_max;
+    size_t nmodels;
+    virDomainCapsCPUModelPtr models;
+};
+
+typedef struct _virDomainCapsCPU virDomainCapsCPU;
+typedef virDomainCapsCPU *virDomainCapsCPUPtr;
+struct _virDomainCapsCPU {
+    bool hostPassthrough;
+    bool hostModel;
+    virDomainCapsCPUModelsPtr custom;
+};
+
 struct _virDomainCaps {
     virObjectLockable parent;
 
@@ -114,6 +138,7 @@ struct _virDomainCaps {
     int maxvcpus;
 
     virDomainCapsOS os;
+    virDomainCapsCPU cpu;
     virDomainCapsDeviceDisk disk;
     virDomainCapsDeviceGraphics graphics;
     virDomainCapsDeviceVideo video;
@@ -129,6 +154,14 @@ virDomainCapsPtr virDomainCapsNew(const char *path,
                                   virArch arch,
                                   virDomainVirtType virttype);
 
+virDomainCapsCPUModelsPtr virDomainCapsCPUModelsNew(size_t nmodels);
+virDomainCapsCPUModelsPtr virDomainCapsCPUModelsCopy(virDomainCapsCPUModelsPtr old);
+int virDomainCapsCPUModelsAddSteal(virDomainCapsCPUModelsPtr cpuModels,
+                                   char **name);
+int virDomainCapsCPUModelsAdd(virDomainCapsCPUModelsPtr cpuModels,
+                              const char *name,
+                              ssize_t nameLen);
+
 # define VIR_DOMAIN_CAPS_ENUM_SET(capsEnum, ...)            \
     do {                                                    \
         unsigned int __values[] = {__VA_ARGS__};            \
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 9610e0c..46e805a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -153,6 +153,10 @@ virDomainAuditVcpu;
 
 
 # conf/domain_capabilities.h
+virDomainCapsCPUModelsAdd;
+virDomainCapsCPUModelsAddSteal;
+virDomainCapsCPUModelsCopy;
+virDomainCapsCPUModelsNew;
 virDomainCapsEnumClear;
 virDomainCapsEnumSet;
 virDomainCapsFormat;
diff --git a/tests/domaincapsschemadata/basic.xml b/tests/domaincapsschemadata/basic.xml
index 5513f99..6b788d9 100644
--- a/tests/domaincapsschemadata/basic.xml
+++ b/tests/domaincapsschemadata/basic.xml
@@ -4,6 +4,11 @@
   <machine>my-machine-type</machine>
   <arch>x86_64</arch>
   <os supported='no'/>
+  <cpu>
+    <mode name='host-passthrough' supported='no'/>
+    <mode name='host-model' supported='no'/>
+    <mode name='custom' supported='no'/>
+  </cpu>
   <devices>
     <disk supported='no'/>
     <graphics supported='no'/>
diff --git a/tests/domaincapsschemadata/full.xml b/tests/domaincapsschemadata/full.xml
index 2f529ff..80fd1f0 100644
--- a/tests/domaincapsschemadata/full.xml
+++ b/tests/domaincapsschemadata/full.xml
@@ -19,6 +19,15 @@
       </enum>
     </loader>
   </os>
+  <cpu>
+    <mode name='host-passthrough' supported='yes'/>
+    <mode name='host-model' supported='yes'/>
+    <mode name='custom' supported='yes'>
+      <model>Model1</model>
+      <model>Model2</model>
+      <model>Model3</model>
+    </mode>
+  </cpu>
   <devices>
     <disk supported='yes'>
       <enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/libxl-xenfv-usb.xml b/tests/domaincapsschemadata/libxl-xenfv-usb.xml
index c071d12..6a9e3d9 100644
--- a/tests/domaincapsschemadata/libxl-xenfv-usb.xml
+++ b/tests/domaincapsschemadata/libxl-xenfv-usb.xml
@@ -17,6 +17,11 @@
       </enum>
     </loader>
   </os>
+  <cpu>
+    <mode name='host-passthrough' supported='no'/>
+    <mode name='host-model' supported='no'/>
+    <mode name='custom' supported='no'/>
+  </cpu>
   <devices>
     <disk supported='yes'>
       <enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/libxl-xenfv.xml b/tests/domaincapsschemadata/libxl-xenfv.xml
index 9436ef8..d48e699 100644
--- a/tests/domaincapsschemadata/libxl-xenfv.xml
+++ b/tests/domaincapsschemadata/libxl-xenfv.xml
@@ -17,6 +17,11 @@
       </enum>
     </loader>
   </os>
+  <cpu>
+    <mode name='host-passthrough' supported='no'/>
+    <mode name='host-model' supported='no'/>
+    <mode name='custom' supported='no'/>
+  </cpu>
   <devices>
     <disk supported='yes'>
       <enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/libxl-xenpv-usb.xml b/tests/domaincapsschemadata/libxl-xenpv-usb.xml
index 4dd07bd..d1a3918 100644
--- a/tests/domaincapsschemadata/libxl-xenpv-usb.xml
+++ b/tests/domaincapsschemadata/libxl-xenpv-usb.xml
@@ -7,6 +7,11 @@
   <os supported='yes'>
     <loader supported='no'/>
   </os>
+  <cpu>
+    <mode name='host-passthrough' supported='no'/>
+    <mode name='host-model' supported='no'/>
+    <mode name='custom' supported='no'/>
+  </cpu>
   <devices>
     <disk supported='yes'>
       <enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/libxl-xenpv.xml b/tests/domaincapsschemadata/libxl-xenpv.xml
index ab00a28..c0e3193 100644
--- a/tests/domaincapsschemadata/libxl-xenpv.xml
+++ b/tests/domaincapsschemadata/libxl-xenpv.xml
@@ -7,6 +7,11 @@
   <os supported='yes'>
     <loader supported='no'/>
   </os>
+  <cpu>
+    <mode name='host-passthrough' supported='no'/>
+    <mode name='host-model' supported='no'/>
+    <mode name='custom' supported='no'/>
+  </cpu>
   <devices>
     <disk supported='yes'>
       <enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/qemu_1.7.0.x86_64.xml b/tests/domaincapsschemadata/qemu_1.7.0.x86_64.xml
index 161d0ab..6da28b0 100644
--- a/tests/domaincapsschemadata/qemu_1.7.0.x86_64.xml
+++ b/tests/domaincapsschemadata/qemu_1.7.0.x86_64.xml
@@ -18,6 +18,11 @@
       </enum>
     </loader>
   </os>
+  <cpu>
+    <mode name='host-passthrough' supported='no'/>
+    <mode name='host-model' supported='no'/>
+    <mode name='custom' supported='no'/>
+  </cpu>
   <devices>
     <disk supported='yes'>
       <enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/qemu_2.6.0-gicv2-virt.aarch64.xml b/tests/domaincapsschemadata/qemu_2.6.0-gicv2-virt.aarch64.xml
index f5f0f1c..ee51684 100644
--- a/tests/domaincapsschemadata/qemu_2.6.0-gicv2-virt.aarch64.xml
+++ b/tests/domaincapsschemadata/qemu_2.6.0-gicv2-virt.aarch64.xml
@@ -18,6 +18,11 @@
       </enum>
     </loader>
   </os>
+  <cpu>
+    <mode name='host-passthrough' supported='no'/>
+    <mode name='host-model' supported='no'/>
+    <mode name='custom' supported='no'/>
+  </cpu>
   <devices>
     <disk supported='yes'>
       <enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/qemu_2.6.0-gicv3-virt.aarch64.xml b/tests/domaincapsschemadata/qemu_2.6.0-gicv3-virt.aarch64.xml
index 1ae8172..88cced9 100644
--- a/tests/domaincapsschemadata/qemu_2.6.0-gicv3-virt.aarch64.xml
+++ b/tests/domaincapsschemadata/qemu_2.6.0-gicv3-virt.aarch64.xml
@@ -18,6 +18,11 @@
       </enum>
     </loader>
   </os>
+  <cpu>
+    <mode name='host-passthrough' supported='no'/>
+    <mode name='host-model' supported='no'/>
+    <mode name='custom' supported='no'/>
+  </cpu>
   <devices>
     <disk supported='yes'>
       <enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/qemu_2.6.0.aarch64.xml b/tests/domaincapsschemadata/qemu_2.6.0.aarch64.xml
index 4e87cd2..09c0e1c 100644
--- a/tests/domaincapsschemadata/qemu_2.6.0.aarch64.xml
+++ b/tests/domaincapsschemadata/qemu_2.6.0.aarch64.xml
@@ -18,6 +18,11 @@
       </enum>
     </loader>
   </os>
+  <cpu>
+    <mode name='host-passthrough' supported='no'/>
+    <mode name='host-model' supported='no'/>
+    <mode name='custom' supported='no'/>
+  </cpu>
   <devices>
     <disk supported='yes'>
       <enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/qemu_2.6.0.ppc64le.xml b/tests/domaincapsschemadata/qemu_2.6.0.ppc64le.xml
index 583fdf0..40b255e 100644
--- a/tests/domaincapsschemadata/qemu_2.6.0.ppc64le.xml
+++ b/tests/domaincapsschemadata/qemu_2.6.0.ppc64le.xml
@@ -18,6 +18,11 @@
       </enum>
     </loader>
   </os>
+  <cpu>
+    <mode name='host-passthrough' supported='no'/>
+    <mode name='host-model' supported='no'/>
+    <mode name='custom' supported='no'/>
+  </cpu>
   <devices>
     <disk supported='yes'>
       <enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/qemu_2.6.0.x86_64.xml b/tests/domaincapsschemadata/qemu_2.6.0.x86_64.xml
index c453ce3..6706fec 100644
--- a/tests/domaincapsschemadata/qemu_2.6.0.x86_64.xml
+++ b/tests/domaincapsschemadata/qemu_2.6.0.x86_64.xml
@@ -18,6 +18,11 @@
       </enum>
     </loader>
   </os>
+  <cpu>
+    <mode name='host-passthrough' supported='no'/>
+    <mode name='host-model' supported='no'/>
+    <mode name='custom' supported='no'/>
+  </cpu>
   <devices>
     <disk supported='yes'>
       <enum name='diskDevice'>
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index 5b7b7d0..907c0ad 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -60,6 +60,7 @@ fillAllCaps(virDomainCapsPtr domCaps)
 {
     virDomainCapsOSPtr os = &domCaps->os;
     virDomainCapsLoaderPtr loader = &os->loader;
+    virDomainCapsCPUPtr cpu = &domCaps->cpu;
     virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
     virDomainCapsDeviceGraphicsPtr graphics = &domCaps->graphics;
     virDomainCapsDeviceVideoPtr video = &domCaps->video;
@@ -77,6 +78,14 @@ fillAllCaps(virDomainCapsPtr domCaps)
                          NULL) < 0)
         return -1;
 
+    cpu->hostPassthrough = true;
+    cpu->hostModel = true;
+    if (!(cpu->custom = virDomainCapsCPUModelsNew(3)) ||
+        virDomainCapsCPUModelsAdd(cpu->custom, "Model1", -1) < 0 ||
+        virDomainCapsCPUModelsAdd(cpu->custom, "Model2", -1) < 0 ||
+        virDomainCapsCPUModelsAdd(cpu->custom, "Model3", -1) < 0)
+        return -1;
+
     disk->supported = true;
     SET_ALL_BITS(disk->diskDevice);
     SET_ALL_BITS(disk->bus);
-- 
2.10.0




More information about the libvir-list mailing list