]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add support for cpu mode attribute
authorJiri Denemark <jdenemar@redhat.com>
Thu, 18 Aug 2011 10:14:36 +0000 (12:14 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Tue, 17 Jan 2012 10:39:23 +0000 (11:39 +0100)
The mode can be either of "custom" (default), "host-model",
"host-passthrough". The semantics of each mode is described in the
following examples:

- guest CPU is a default model with specified topology:
    <cpu>
      <topology sockets='1' cores='2' threads='1'/>
    </cpu>

- guest CPU matches selected model:
    <cpu mode='custom' match='exact'>
      <model>core2duo</model>
    </cpu>

- guest CPU should be a copy of host CPU as advertised by capabilities
  XML (this is a short cut for manually copying host CPU specification
  from capabilities to domain XML):
    <cpu mode='host-model'/>

  In case a hypervisor does not support the exact host model, libvirt
  automatically falls back to a closest supported CPU model and
  removes/adds features to match host. This behavior can be disabled by
    <cpu mode='host-model'>
      <model fallback='forbid'/>
    </cpu>

- the same as previous returned by virDomainGetXMLDesc with
  VIR_DOMAIN_XML_UPDATE_CPU flag:
    <cpu mode='host-model' match='exact'>
      <model fallback='allow'>Penryn</model>       --+
      <vendor>Intel</vendor>                         |
      <topology sockets='2' cores='4' threads='1'/>  + copied from
      <feature policy='require' name='dca'/>         | capabilities XML
      <feature policy='require' name='xtpr'/>        |
      ...                                          --+
    </cpu>

- guest CPU should be exactly the same as host CPU even in the aspects
  libvirt doesn't model (such domain cannot be migrated unless both
  hosts contain exactly the same CPUs):
    <cpu mode='host-passthrough'/>

- the same as previous returned by virDomainGetXMLDesc with
  VIR_DOMAIN_XML_UPDATE_CPU flag:
    <cpu mode='host-passthrough' match='minimal'>
      <model>Penryn</model>                        --+ copied from caps
      <vendor>Intel</vendor>                         | XML but doesn't
      <topology sockets='2' cores='4' threads='1'/>  | describe all
      <feature policy='require' name='dca'/>         | aspects of the
      <feature policy='require' name='xtpr'/>        | actual guest CPU
      ...                                          --+
    </cpu>

28 files changed:
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/capabilities.c
src/conf/cpu_conf.c
src/conf/cpu_conf.h
src/conf/domain_conf.c
src/cpu/cpu.c
tests/cputest.c
tests/cputestdata/x86-baseline-1-result.xml
tests/cputestdata/x86-baseline-2-result.xml
tests/cputestdata/x86-baseline-no-vendor-result.xml
tests/cputestdata/x86-baseline-some-vendors-result.xml
tests/cputestdata/x86-host+guest,model486-result.xml
tests/cputestdata/x86-host+guest,models,Penryn-result.xml
tests/cputestdata/x86-host+guest,models,qemu64-result.xml
tests/cputestdata/x86-host+guest,models-result.xml
tests/cputestdata/x86-host+guest-result.xml
tests/cputestdata/x86-host+guest.xml
tests/cputestdata/x86-host+min.xml
tests/cputestdata/x86-host+nehalem-force-result.xml
tests/cputestdata/x86-host+pentium3.xml
tests/cputestdata/x86-host+strict-force-extra-result.xml
tests/cputestdata/x86-host-better+pentium3,core2duo-result.xml
tests/cputestdata/x86-host-better+pentium3,pentium3-result.xml
tests/cputestdata/x86-host-better+pentium3-result.xml
tests/cputestdata/x86-host-worse+guest-result.xml
tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml
tests/testutilsqemu.c

index cb7532e2bd85f1cd8aafaa5bbd94daf44172793a..6bb5721a74a342ce17dd96d4c83765e47d570f1c 100644 (file)
   &lt;/cpu&gt;
   ...</pre>
 
+<pre>
+  &lt;cpu mode='host-model'&gt;
+    &lt;model fallback='forbid'/&gt;
+    &lt;topology sockets='1' cores='2' threads='1'/&gt;
+  &lt;/cpu&gt;
+  ...</pre>
+
+<pre>
+  &lt;cpu mode='host-passthrough'/&gt;
+  ...</pre>
+
     <p>
       In case no restrictions need to be put on CPU model and its features, a
       simpler <code>cpu</code> element can be used.
 
         <span class="since">Since 0.8.5</span> the <code>match</code>
         attribute can be omitted and will default to <code>exact</code>.
+
+        <span class="since">Since 0.9.10</span>, an optional <code>mode</code>
+        attribute may be used to make it easier to configure a guest CPU to be
+        as close to host CPU as possible. Possible values for the
+        <code>mode</code> attribute are:
+
+        <dl>
+          <dt><code>custom</code></dt>
+          <dd>In this mode, the <code>cpu</code> element describes the CPU
+          that should be presented to the guest. This is the default when no
+          <code>mode</code> attribute is specified. This mode makes it so that
+          a persistent guest will see the same hardware no matter what host
+          the guest is booted on.</dd>
+          <dt><code>host-model</code></dt>
+          <dd>The <code>host-model</code> mode is essentially a shortcut to
+          copying host CPU definition from capabilities XML into domain XML.
+          Since the CPU definition is copied just before starting a domain,
+          exactly the same XML can be used on different hosts while still
+          providing the best guest CPU each host supports. Neither
+          <code>match</code> attribute nor any <code>feature</code> elements
+          can be used in this mode. Specifying CPU model is not supported
+          either, but <code>model</code>'s <code>fallback</code> attribute may
+          still be used. Libvirt does not model every aspect of each CPU so
+          the guest CPU will not match the host CPU exactly. On the other
+          hand, the ABI provided to the guest is reproducible. During
+          migration, complete CPU model definition is transferred to the
+          destination host so the migrated guest will see exactly the same CPU
+          model even if the destination host contains more capable CPUs for
+          the running instance of the guest; but shutting down and restarting
+          the guest may present different hardware to the guest according to
+          the capabilities of the new host.</dd>
+          <dt><code>host-passthrough</code></dt>
+          <dd>With this mode, the CPU visible to the guest should be exactly
+          the same as the host CPU even in the aspects that libvirt does not
+          understand. Though the downside of this mode is that the guest
+          environment cannot be reproduced on different hardware. Thus, if you
+          hit any bugs, you are on your own. Neither <code>model</code> nor
+          <code>feature</code> elements are allowed in this mode.</dd>
+        </dl>
+
+        In both <code>host-model</code> and <code>host-passthrough</code>
+        mode, the real (approximate in <code>host-passthrough</code> mode) CPU
+        definition which would be used on current host can be determined by
+        specifying <code>VIR_DOMAIN_XML_UPDATE_CPU</code> flag when calling
+        <code>virDomainGetXMLDesc</code> API. When running a guest that might
+        be prone to operating system reactivation when presented with
+        different hardware, and which will be migrated between hosts with
+        different capabilities, you can use this output to rewrite XML to the
+        <code>custom</code> mode for more robust migration.
       </dd>
 
       <dt><code>model</code></dt>
index 133b7f7a826d71c33f324eb863c74ae74d57bdf9..27b9a1f0467c6eac1a63766633ff2c3e209555ff 100644 (file)
           </interleave>
         </group>
         <group>
+          <ref name="cpuMode"/>
+          <interleave>
+            <optional>
+              <ref name="cpuModel"/>
+            </optional>
+            <optional>
+              <ref name="cpuNuma"/>
+            </optional>
+          </interleave>
+        </group>
+        <group>
+          <optional>
+            <ref name="cpuMode"/>
+          </optional>
           <ref name="cpuMatch"/>
           <interleave>
             <ref name="cpuModel"/>
     </element>
   </define>
 
+  <define name="cpuMode">
+    <attribute name="mode">
+      <choice>
+        <value>custom</value>
+        <value>host-model</value>
+        <value>host-passthrough</value>
+      </choice>
+    </attribute>
+  </define>
+
   <define name="cpuMatch">
     <attribute name="match">
       <choice>
           </choice>
         </attribute>
       </optional>
-      <text/>
+      <choice>
+        <text/>
+        <empty/>
+      </choice>
     </element>
   </define>
 
index ac050df2d3e2c9deddf25733c1877b73b3ec2768..ed0ae998308d9ae5cddb0514dafeb6dbd33e7325 100644 (file)
@@ -691,7 +691,7 @@ virCapabilitiesFormatXML(virCapsPtr caps)
     }
 
     virBufferAdjustIndent(&xml, 6);
-    virCPUDefFormatBuf(&xml, caps->host.cpu);
+    virCPUDefFormatBuf(&xml, caps->host.cpu, 0);
     virBufferAdjustIndent(&xml, -6);
 
     virBufferAddLit(&xml, "    </cpu>\n");
index c8e29e4cd8dc0e798683092c57399e8412c62652..31862e2bfeca368fa50ee4798f4738b6eeaf0daf 100644 (file)
 VIR_ENUM_IMPL(virCPU, VIR_CPU_TYPE_LAST,
               "host", "guest", "auto")
 
+VIR_ENUM_IMPL(virCPUMode, VIR_CPU_MODE_LAST,
+              "custom",
+              "host-model",
+              "host-passthrough")
+
 VIR_ENUM_IMPL(virCPUMatch, VIR_CPU_MATCH_LAST,
               "minimum",
               "exact",
@@ -100,6 +105,7 @@ virCPUDefCopy(const virCPUDefPtr cpu)
     copy->nfeatures_max = cpu->nfeatures;
 
     copy->type = cpu->type;
+    copy->mode = cpu->mode;
     copy->match = cpu->match;
     copy->fallback = cpu->fallback;
     copy->sockets = cpu->sockets;
@@ -151,6 +157,7 @@ virCPUDefParseXML(const xmlNodePtr node,
     xmlNodePtr *nodes = NULL;
     int n;
     unsigned int i;
+    char *cpuMode;
 
     if (!xmlStrEqual(node->name, BAD_CAST "cpu")) {
         virCPUReportError(VIR_ERR_INTERNAL_ERROR,
@@ -173,10 +180,35 @@ virCPUDefParseXML(const xmlNodePtr node,
                 goto error;
             }
             def->type = VIR_CPU_TYPE_HOST;
-        } else
+        } else {
             def->type = VIR_CPU_TYPE_GUEST;
-    } else
+        }
+    } else {
         def->type = mode;
+    }
+
+    if ((cpuMode = virXMLPropString(node, "mode"))) {
+        if (def->type == VIR_CPU_TYPE_HOST) {
+            VIR_FREE(cpuMode);
+            virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                              _("Attribute mode is only allowed for guest CPU"));
+            goto error;
+        } else {
+            def->mode = virCPUModeTypeFromString(cpuMode);
+            VIR_FREE(cpuMode);
+
+            if (def->mode < 0) {
+                virCPUReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                  _("Invalid mode attribute"));
+                goto error;
+            }
+        }
+    } else {
+        if (def->type == VIR_CPU_TYPE_HOST)
+            def->mode = -1;
+        else
+            def->mode = VIR_CPU_MODE_CUSTOM;
+    }
 
     if (def->type == VIR_CPU_TYPE_GUEST) {
         char *match = virXMLPropString(node, "match");
@@ -214,7 +246,9 @@ virCPUDefParseXML(const xmlNodePtr node,
         goto error;
     }
 
-    if (def->model && def->type == VIR_CPU_TYPE_GUEST) {
+    if (def->type == VIR_CPU_TYPE_GUEST &&
+        def->mode != VIR_CPU_MODE_HOST_PASSTHROUGH &&
+        virXPathBoolean("boolean(./model[1]/@fallback)", ctxt)) {
         const char *fallback;
 
         fallback = virXPathString("string(./model[1]/@fallback)", ctxt);
@@ -311,9 +345,9 @@ virCPUDefParseXML(const xmlNodePtr node,
                         "%s", _("Invalid CPU feature policy"));
                 goto error;
             }
-        }
-        else
+        } else {
             policy = -1;
+        }
 
         if (!(name = virXMLPropString(nodes[i], "name")) || *name == 0) {
             VIR_FREE(name);
@@ -407,11 +441,12 @@ error:
 
 
 char *
-virCPUDefFormat(virCPUDefPtr def)
+virCPUDefFormat(virCPUDefPtr def,
+                unsigned int flags)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
 
-    if (virCPUDefFormatBufFull(&buf, def) < 0)
+    if (virCPUDefFormatBufFull(&buf, def, flags) < 0)
         goto cleanup;
 
     if (virBufferError(&buf))
@@ -429,29 +464,44 @@ cleanup:
 
 int
 virCPUDefFormatBufFull(virBufferPtr buf,
-                       virCPUDefPtr def)
+                       virCPUDefPtr def,
+                       unsigned int flags)
 {
     if (!def)
         return 0;
 
-    if (def->type == VIR_CPU_TYPE_GUEST && def->model) {
-        const char *match;
-        if (!(match = virCPUMatchTypeToString(def->match))) {
-            virCPUReportError(VIR_ERR_INTERNAL_ERROR,
-                              _("Unexpected CPU match policy %d"), def->match);
-            return -1;
+    virBufferAddLit(buf, "<cpu");
+    if (def->type == VIR_CPU_TYPE_GUEST) {
+        const char *tmp;
+
+        if (def->mode != VIR_CPU_MODE_CUSTOM || def->model) {
+            if (!(tmp = virCPUModeTypeToString(def->mode))) {
+                virCPUReportError(VIR_ERR_INTERNAL_ERROR,
+                                  _("Unexpected CPU mode %d"), def->mode);
+                return -1;
+            }
+            virBufferAsprintf(buf, " mode='%s'", tmp);
         }
 
-        virBufferAsprintf(buf, "<cpu match='%s'>\n", match);
-    } else {
-        virBufferAddLit(buf, "<cpu>\n");
+        if (def->model &&
+            (def->mode == VIR_CPU_MODE_CUSTOM ||
+             (flags & VIR_DOMAIN_XML_UPDATE_CPU))) {
+            if (!(tmp = virCPUMatchTypeToString(def->match))) {
+                virCPUReportError(VIR_ERR_INTERNAL_ERROR,
+                                  _("Unexpected CPU match policy %d"),
+                                  def->match);
+                return -1;
+            }
+            virBufferAsprintf(buf, " match='%s'", tmp);
+        }
     }
+    virBufferAddLit(buf, ">\n");
 
     if (def->arch)
         virBufferAsprintf(buf, "  <arch>%s</arch>\n", def->arch);
 
     virBufferAdjustIndent(buf, 2);
-    if (virCPUDefFormatBuf(buf, def) < 0)
+    if (virCPUDefFormatBuf(buf, def, flags) < 0)
         return -1;
     virBufferAdjustIndent(buf, -2);
 
@@ -462,22 +512,31 @@ virCPUDefFormatBufFull(virBufferPtr buf,
 
 int
 virCPUDefFormatBuf(virBufferPtr buf,
-                   virCPUDefPtr def)
+                   virCPUDefPtr def,
+                   unsigned int flags)
 {
     unsigned int i;
+    bool formatModel;
+    bool formatFallback;
 
     if (!def)
         return 0;
 
+    formatModel = (def->mode == VIR_CPU_MODE_CUSTOM ||
+                   (flags & VIR_DOMAIN_XML_UPDATE_CPU));
+    formatFallback = (def->type == VIR_CPU_TYPE_GUEST &&
+                      (def->mode == VIR_CPU_MODE_HOST_MODEL ||
+                       (def->mode == VIR_CPU_MODE_CUSTOM && def->model)));
+
     if (!def->model && def->nfeatures) {
         virCPUReportError(VIR_ERR_INTERNAL_ERROR,
                 "%s", _("Non-empty feature list specified without CPU model"));
         return -1;
     }
 
-    if (def->model) {
+    if ((formatModel && def->model) || formatFallback) {
         virBufferAddLit(buf, "<model");
-        if (def->type == VIR_CPU_TYPE_GUEST) {
+        if (formatFallback) {
             const char *fallback;
 
             fallback = virCPUFallbackTypeToString(def->fallback);
@@ -489,12 +548,15 @@ virCPUDefFormatBuf(virBufferPtr buf,
             }
             virBufferAsprintf(buf, " fallback='%s'", fallback);
         }
-        virBufferAsprintf(buf, ">%s</model>\n", def->model);
+        if (formatModel && def->model) {
+            virBufferAsprintf(buf, ">%s</model>\n", def->model);
+        } else {
+            virBufferAddLit(buf, "/>\n");
+        }
     }
 
-    if (def->vendor) {
+    if (formatModel && def->vendor)
         virBufferAsprintf(buf, "<vendor>%s</vendor>\n", def->vendor);
-    }
 
     if (def->sockets && def->cores && def->threads) {
         virBufferAddLit(buf, "<topology");
@@ -504,29 +566,32 @@ virCPUDefFormatBuf(virBufferPtr buf,
         virBufferAddLit(buf, "/>\n");
     }
 
-    for (i = 0 ; i < def->nfeatures ; i++) {
-        virCPUFeatureDefPtr feature = def->features + i;
+    if (formatModel) {
+        for (i = 0 ; i < def->nfeatures ; i++) {
+            virCPUFeatureDefPtr feature = def->features + i;
 
-        if (!feature->name) {
-            virCPUReportError(VIR_ERR_INTERNAL_ERROR,
-                    "%s", _("Missing CPU feature name"));
-            return -1;
-        }
-
-        if (def->type == VIR_CPU_TYPE_GUEST) {
-            const char *policy;
-
-            policy = virCPUFeaturePolicyTypeToString(feature->policy);
-            if (!policy) {
+            if (!feature->name) {
                 virCPUReportError(VIR_ERR_INTERNAL_ERROR,
-                        _("Unexpected CPU feature policy %d"), feature->policy);
+                        "%s", _("Missing CPU feature name"));
                 return -1;
             }
-            virBufferAsprintf(buf, "<feature policy='%s' name='%s'/>\n",
-                              policy, feature->name);
-        } else {
-            virBufferAsprintf(buf, "<feature name='%s'/>\n",
-                              feature->name);
+
+            if (def->type == VIR_CPU_TYPE_GUEST) {
+                const char *policy;
+
+                policy = virCPUFeaturePolicyTypeToString(feature->policy);
+                if (!policy) {
+                    virCPUReportError(VIR_ERR_INTERNAL_ERROR,
+                                      _("Unexpected CPU feature policy %d"),
+                                      feature->policy);
+                    return -1;
+                }
+                virBufferAsprintf(buf, "<feature policy='%s' name='%s'/>\n",
+                                  policy, feature->name);
+            } else {
+                virBufferAsprintf(buf, "<feature name='%s'/>\n",
+                                  feature->name);
+            }
         }
     }
 
@@ -603,6 +668,14 @@ virCPUDefIsEqual(virCPUDefPtr src,
         goto cleanup;
     }
 
+    if (src->mode != dst->mode) {
+        virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                          _("Target CPU mode %s does not match source %s"),
+                          virCPUModeTypeToString(dst->mode),
+                          virCPUModeTypeToString(src->mode));
+        goto cleanup;
+    }
+
     if (STRNEQ_NULLABLE(src->arch, dst->arch)) {
         virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Target CPU arch %s does not match source %s"),
index 0c50f90b156791fae3ec850849094892cbe8ef16..4b0b35bda3122f17549dbe210b184605bc5dd994 100644 (file)
@@ -38,6 +38,16 @@ enum virCPUType {
 
 VIR_ENUM_DECL(virCPU)
 
+enum virCPUMode {
+    VIR_CPU_MODE_CUSTOM,
+    VIR_CPU_MODE_HOST_MODEL,
+    VIR_CPU_MODE_HOST_PASSTHROUGH,
+
+    VIR_CPU_MODE_LAST
+};
+
+VIR_ENUM_DECL(virCPUMode)
+
 enum virCPUMatch {
     VIR_CPU_MATCH_MINIMUM,
     VIR_CPU_MATCH_EXACT,
@@ -89,6 +99,7 @@ typedef struct _virCPUDef virCPUDef;
 typedef virCPUDef *virCPUDefPtr;
 struct _virCPUDef {
     int type;           /* enum virCPUType */
+    int mode;           /* enum virCPUMode */
     int match;          /* enum virCPUMatch */
     char *arch;
     char *model;
@@ -123,14 +134,17 @@ virCPUDefIsEqual(virCPUDefPtr src,
                  virCPUDefPtr dst);
 
 char *
-virCPUDefFormat(virCPUDefPtr def);
+virCPUDefFormat(virCPUDefPtr def,
+                unsigned int flags);
 
 int
 virCPUDefFormatBuf(virBufferPtr buf,
-                   virCPUDefPtr def);
+                   virCPUDefPtr def,
+                   unsigned int flags);
 int
 virCPUDefFormatBufFull(virBufferPtr buf,
-                       virCPUDefPtr def);
+                       virCPUDefPtr def,
+                       unsigned int flags);
 
 int
 virCPUDefAddFeature(virCPUDefPtr cpu,
index 6c42f36f1e8009fa675664443bfb65351c52fa52..dcc32465ac9e8d5e4dd886004286524ee579ed55 100644 (file)
@@ -11639,7 +11639,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
     }
 
     virBufferAdjustIndent(buf, 2);
-    if (virCPUDefFormatBufFull(buf, def->cpu) < 0)
+    if (virCPUDefFormatBufFull(buf, def->cpu, flags) < 0)
         goto cleanup;
     virBufferAdjustIndent(buf, -2);
 
index e4149e284a6372585d1d21a53600c84233632728..1f3993429ea55d07c53b7b1289acc31e6712a33c 100644 (file)
@@ -322,7 +322,7 @@ cpuBaselineXML(const char **xmlCPUs,
     if (!(cpu = cpuBaseline(cpus, ncpus, models, nmodels)))
         goto error;
 
-    cpustr = virCPUDefFormat(cpu);
+    cpustr = virCPUDefFormat(cpu, 0);
 
 cleanup:
     if (cpus) {
index 2dd89f28bed4c5c67770f27046571d2a93d65d80..d8c171398c1b1297860382c5ef7adff323cd8f93 100644 (file)
@@ -176,7 +176,7 @@ cpuTestCompareXML(const char *arch,
     if (virtTestLoadFile(xml, &expected) < 0)
         goto cleanup;
 
-    if (!(actual = virCPUDefFormat(cpu)))
+    if (!(actual = virCPUDefFormat(cpu, 0)))
         goto cleanup;
 
     if (STRNEQ(expected, actual)) {
index 99e43d018ff9d894a76ce524ed92099fd91f6bab..96c4f43b3dcd114b2e0106f555a4605cf06917dc 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <model fallback='allow'>Conroe</model>
   <vendor>Intel</vendor>
   <feature policy='disable' name='lahf_lm'/>
index 76c13aa505bace44c25f1857360b7be5b0c06274..a11352d0b141420f2d812531050a843016ccb167 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <model fallback='allow'>core2duo</model>
   <feature policy='disable' name='nx'/>
 </cpu>
index 8b97d2c130924c203db26bcee24cad4eec9a921f..a14bb7e6afb4aba9c29b59e74f631c4396dee9fc 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <model fallback='allow'>Opteron_G2</model>
   <feature policy='disable' name='svm'/>
   <feature policy='disable' name='rdtscp'/>
index bac0e5d38f2fcf4250291bedc1f4716a8c7280a0..2927611f7b38fa74154ce57e30bfdf312428aaf7 100644 (file)
@@ -1,3 +1,3 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <model fallback='allow'>Opteron_G1</model>
 </cpu>
index 9fd67eb1a74350d538010e76dd7827060cb157b8..e21c8b81f49431d3dabd062b458875ca8a9dedc4 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <arch>x86_64</arch>
   <model fallback='allow'>486</model>
   <feature policy='require' name='svm'/>
index 9ae11c95006fcdd7668a8e6e69900f0f19ebf6ca..6a31dcd2aa4c070ae46d6cfc2bd906da904d4d6c 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <arch>x86_64</arch>
   <model fallback='allow'>Nehalem</model>
   <feature policy='require' name='svm'/>
index 7582ddc8c5ab97dad7588018416ae452f382b123..1f15d6ec8b67970ea886388d1ec001dc91b72fd6 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <arch>x86_64</arch>
   <model fallback='allow'>qemu64</model>
   <feature policy='require' name='lahf_lm'/>
index 9ae11c95006fcdd7668a8e6e69900f0f19ebf6ca..6a31dcd2aa4c070ae46d6cfc2bd906da904d4d6c 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <arch>x86_64</arch>
   <model fallback='allow'>Nehalem</model>
   <feature policy='require' name='svm'/>
index e596c4320992543f25f967437e6deb72a536a42f..9d37dec9cab9356e06d1cbe5a8d5461ffc62a77c 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <arch>x86_64</arch>
   <model fallback='allow'>Penryn</model>
   <feature policy='require' name='svm'/>
index 2a786fd3aa335cf484425d921b25772c14e7d422..137a3d6647f47db83caf922e89b3562e62824a1b 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <model fallback='allow'>Penryn</model>
   <topology sockets='2' cores='4' threads='1'/>
   <feature policy='require' name='dca'/>
index fe55058992e8516e0b75df3a01151731b3aa70f6..81011517bb6bdecfa902d7c6684dfa8c17e5e9d7 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <model fallback='allow'>Penryn</model>
   <feature policy='require' name='dca'/>
   <feature policy='require' name='xtpr'/>
index 41e7356796dbb119c68929ea673196e4633d2e5d..000bc0d61bc8b2033e42c7cadab722230e3ef598 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <arch>x86_64</arch>
   <model fallback='allow'>Nehalem</model>
 </cpu>
index e122ba53d6e6ddee87f6d810b9ecf832000dd0f4..d46525ce59821d026891a1282e3e907f660e9a8c 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <model fallback='allow'>pentium3</model>
   <feature policy='require' name='lahf_lm'/>
   <feature policy='require' name='lm'/>
index f3d52a14b3cc3d84e7b7d915544df9fbb25ab6d2..68db4129c2f7d940d09f94daa24fd7d21188e133 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <arch>x86_64</arch>
   <model fallback='allow'>Penryn</model>
   <feature policy='require' name='3dnow'/>
index 5d4528bd6d1aaf1669f3219c7ed6df70fe997aa2..0c436d9216afaa7ef7064d4a3b615a596f08d3a9 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <arch>x86_64</arch>
   <model fallback='allow'>core2duo</model>
   <feature policy='require' name='lahf_lm'/>
index 1530a07e0ac351e292281593f518d3a8c5bd2cc8..1e4f488616f64794a9887992335db88ad957062a 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <arch>x86_64</arch>
   <model fallback='allow'>pentium3</model>
   <feature policy='require' name='lahf_lm'/>
index 917d63f06992754f2b5b14e00dcd8b6417e87144..07be0f7d643fb92d43fd8439431629d0ef253fc8 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <arch>x86_64</arch>
   <model fallback='allow'>Nehalem</model>
   <feature policy='require' name='dca'/>
index 78e170adbc7b2d0ee4f19eae73b11e313c7ea55d..441259fac85573ec7e9cba41970f71bd89b75121 100644 (file)
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
   <arch>x86_64</arch>
   <model fallback='allow'>Penryn</model>
   <feature policy='require' name='svm'/>
index caa5f0a0c0385ac79db15808ee04716244800d8f..ac72822508b932da3ca8a31b291d6e66f6d3ea42 100644 (file)
@@ -15,7 +15,7 @@
     <apic/>
     <pae/>
   </features>
-  <cpu match='exact'>
+  <cpu mode='custom' match='exact'>
     <model fallback='allow'>core2duo</model>
     <vendor>Intel</vendor>
     <topology sockets='1' cores='2' threads='1'/>
index c6adec924c34c5f3f09504342872f8d6316cfcd5..8e621fe0d4610a19c4ca260e90db97b428c257ce 100644 (file)
@@ -112,6 +112,7 @@ virCapsPtr testQemuCapsInit(void) {
     };
     static virCPUDef host_cpu = {
         VIR_CPU_TYPE_HOST,      /* type */
+        0,                      /* mode */
         0,                      /* match */
         (char *) "x86_64",      /* arch */
         (char *) "core2duo",    /* model */