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>
---
Notes:
Version 2:
- added documentation
- fixed XML examples and schema
docs/formatdomain.html.in | 51 +++++++
docs/schemas/domaincommon.rng | 29 ++++-
src/conf/capabilities.c | 2 +-
src/conf/cpu_conf.c | 159 ++++++++++++++------
src/conf/cpu_conf.h | 20 ++-
src/conf/domain_conf.c | 2 +-
src/cpu/cpu.c | 2 +-
tests/cputest.c | 2 +-
tests/cputestdata/x86-baseline-1-result.xml | 2 +-
tests/cputestdata/x86-baseline-2-result.xml | 2 +-
.../cputestdata/x86-baseline-no-vendor-result.xml | 2 +-
.../x86-baseline-some-vendors-result.xml | 2 +-
.../cputestdata/x86-host+guest,model486-result.xml | 2 +-
.../x86-host+guest,models,Penryn-result.xml | 2 +-
.../x86-host+guest,models,qemu64-result.xml | 2 +-
tests/cputestdata/x86-host+guest,models-result.xml | 2 +-
tests/cputestdata/x86-host+guest-result.xml | 2 +-
tests/cputestdata/x86-host+guest.xml | 2 +-
tests/cputestdata/x86-host+min.xml | 2 +-
.../cputestdata/x86-host+nehalem-force-result.xml | 2 +-
tests/cputestdata/x86-host+pentium3.xml | 2 +-
.../x86-host+strict-force-extra-result.xml | 2 +-
.../x86-host-better+pentium3,core2duo-result.xml | 2 +-
.../x86-host-better+pentium3,pentium3-result.xml | 2 +-
.../x86-host-better+pentium3-result.xml | 2 +-
tests/cputestdata/x86-host-worse+guest-result.xml | 2 +-
.../qemuxml2xmlout-graphics-spice-timeout.xml | 2 +-
tests/testutilsqemu.c | 1 +
28 files changed, 236 insertions(+), 70 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 8961fed..bdb182d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -566,6 +566,17 @@
</cpu>
...</pre>
+<pre>
+ <cpu mode='host-model'>
+ <model fallback='forbid'/>
+ <topology sockets='1' cores='2' threads='1'/>
+ </cpu>
+ ...</pre>
+
+<pre>
+ <cpu mode='host-passthrough'/>
+ ...</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.
@@ -603,6 +614,46 @@
<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 value
+ when no <code>mode</code> attribute is specified.</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.</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.
</dd>
<dt><code>model</code></dt>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index a3ad3d3..d8eacf8 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2426,6 +2426,20 @@
</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"/>
@@ -2447,6 +2461,16 @@
</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>
@@ -2467,7 +2491,10 @@
</choice>
</attribute>
</optional>
- <text/>
+ <choice>
+ <text/>
+ <empty/>
+ </choice>
</element>
</define>
diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
index ac050df..ed0ae99 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -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");
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index c8e29e4..31862e2 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -39,6 +39,11 @@
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"),
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index 0c50f90..4b0b35b 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -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,
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 180dd2b..173351b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -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);
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index e4149e2..1f39934 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -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) {
diff --git a/tests/cputest.c b/tests/cputest.c
index 2dd89f2..d8c1713 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -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)) {
diff --git a/tests/cputestdata/x86-baseline-1-result.xml
b/tests/cputestdata/x86-baseline-1-result.xml
index 99e43d0..96c4f43 100644
--- a/tests/cputestdata/x86-baseline-1-result.xml
+++ b/tests/cputestdata/x86-baseline-1-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-baseline-2-result.xml
b/tests/cputestdata/x86-baseline-2-result.xml
index 76c13aa..a11352d 100644
--- a/tests/cputestdata/x86-baseline-2-result.xml
+++ b/tests/cputestdata/x86-baseline-2-result.xml
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
<model fallback='allow'>core2duo</model>
<feature policy='disable' name='nx'/>
</cpu>
diff --git a/tests/cputestdata/x86-baseline-no-vendor-result.xml
b/tests/cputestdata/x86-baseline-no-vendor-result.xml
index 8b97d2c..a14bb7e 100644
--- a/tests/cputestdata/x86-baseline-no-vendor-result.xml
+++ b/tests/cputestdata/x86-baseline-no-vendor-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-baseline-some-vendors-result.xml
b/tests/cputestdata/x86-baseline-some-vendors-result.xml
index bac0e5d..2927611 100644
--- a/tests/cputestdata/x86-baseline-some-vendors-result.xml
+++ b/tests/cputestdata/x86-baseline-some-vendors-result.xml
@@ -1,3 +1,3 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
<model fallback='allow'>Opteron_G1</model>
</cpu>
diff --git a/tests/cputestdata/x86-host+guest,model486-result.xml
b/tests/cputestdata/x86-host+guest,model486-result.xml
index 9fd67eb..e21c8b8 100644
--- a/tests/cputestdata/x86-host+guest,model486-result.xml
+++ b/tests/cputestdata/x86-host+guest,model486-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host+guest,models,Penryn-result.xml
b/tests/cputestdata/x86-host+guest,models,Penryn-result.xml
index 9ae11c9..6a31dcd 100644
--- a/tests/cputestdata/x86-host+guest,models,Penryn-result.xml
+++ b/tests/cputestdata/x86-host+guest,models,Penryn-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host+guest,models,qemu64-result.xml
b/tests/cputestdata/x86-host+guest,models,qemu64-result.xml
index 7582ddc..1f15d6e 100644
--- a/tests/cputestdata/x86-host+guest,models,qemu64-result.xml
+++ b/tests/cputestdata/x86-host+guest,models,qemu64-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host+guest,models-result.xml
b/tests/cputestdata/x86-host+guest,models-result.xml
index 9ae11c9..6a31dcd 100644
--- a/tests/cputestdata/x86-host+guest,models-result.xml
+++ b/tests/cputestdata/x86-host+guest,models-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host+guest-result.xml
b/tests/cputestdata/x86-host+guest-result.xml
index e596c43..9d37dec 100644
--- a/tests/cputestdata/x86-host+guest-result.xml
+++ b/tests/cputestdata/x86-host+guest-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host+guest.xml b/tests/cputestdata/x86-host+guest.xml
index 2a786fd..137a3d6 100644
--- a/tests/cputestdata/x86-host+guest.xml
+++ b/tests/cputestdata/x86-host+guest.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host+min.xml b/tests/cputestdata/x86-host+min.xml
index fe55058..8101151 100644
--- a/tests/cputestdata/x86-host+min.xml
+++ b/tests/cputestdata/x86-host+min.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host+nehalem-force-result.xml
b/tests/cputestdata/x86-host+nehalem-force-result.xml
index 41e7356..000bc0d 100644
--- a/tests/cputestdata/x86-host+nehalem-force-result.xml
+++ b/tests/cputestdata/x86-host+nehalem-force-result.xml
@@ -1,4 +1,4 @@
-<cpu match='exact'>
+<cpu mode='custom' match='exact'>
<arch>x86_64</arch>
<model fallback='allow'>Nehalem</model>
</cpu>
diff --git a/tests/cputestdata/x86-host+pentium3.xml
b/tests/cputestdata/x86-host+pentium3.xml
index e122ba5..d46525c 100644
--- a/tests/cputestdata/x86-host+pentium3.xml
+++ b/tests/cputestdata/x86-host+pentium3.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host+strict-force-extra-result.xml
b/tests/cputestdata/x86-host+strict-force-extra-result.xml
index f3d52a1..68db412 100644
--- a/tests/cputestdata/x86-host+strict-force-extra-result.xml
+++ b/tests/cputestdata/x86-host+strict-force-extra-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host-better+pentium3,core2duo-result.xml
b/tests/cputestdata/x86-host-better+pentium3,core2duo-result.xml
index 5d4528b..0c436d9 100644
--- a/tests/cputestdata/x86-host-better+pentium3,core2duo-result.xml
+++ b/tests/cputestdata/x86-host-better+pentium3,core2duo-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host-better+pentium3,pentium3-result.xml
b/tests/cputestdata/x86-host-better+pentium3,pentium3-result.xml
index 1530a07..1e4f488 100644
--- a/tests/cputestdata/x86-host-better+pentium3,pentium3-result.xml
+++ b/tests/cputestdata/x86-host-better+pentium3,pentium3-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host-better+pentium3-result.xml
b/tests/cputestdata/x86-host-better+pentium3-result.xml
index 917d63f..07be0f7 100644
--- a/tests/cputestdata/x86-host-better+pentium3-result.xml
+++ b/tests/cputestdata/x86-host-better+pentium3-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host-worse+guest-result.xml
b/tests/cputestdata/x86-host-worse+guest-result.xml
index 78e170a..441259f 100644
--- a/tests/cputestdata/x86-host-worse+guest-result.xml
+++ b/tests/cputestdata/x86-host-worse+guest-result.xml
@@ -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'/>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml
b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml
index caa5f0a..ac72822 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml
@@ -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'/>
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index c6adec9..8e621fe 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -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 */
--
1.7.8.3