Add support for cpu mode attribute

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>
This commit is contained in:
Jiri Denemark 2011-08-18 12:14:36 +02:00
parent a6f88cbd2d
commit f7dd3a4e62
28 changed files with 245 additions and 70 deletions

View File

@ -566,6 +566,17 @@
&lt;/cpu&gt; &lt;/cpu&gt;
...</pre> ...</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> <p>
In case no restrictions need to be put on CPU model and its features, a In case no restrictions need to be put on CPU model and its features, a
simpler <code>cpu</code> element can be used. simpler <code>cpu</code> element can be used.
@ -603,6 +614,55 @@
<span class="since">Since 0.8.5</span> the <code>match</code> <span class="since">Since 0.8.5</span> the <code>match</code>
attribute can be omitted and will default to <code>exact</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> </dd>
<dt><code>model</code></dt> <dt><code>model</code></dt>

View File

@ -2538,6 +2538,20 @@
</interleave> </interleave>
</group> </group>
<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"/> <ref name="cpuMatch"/>
<interleave> <interleave>
<ref name="cpuModel"/> <ref name="cpuModel"/>
@ -2559,6 +2573,16 @@
</element> </element>
</define> </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"> <define name="cpuMatch">
<attribute name="match"> <attribute name="match">
<choice> <choice>
@ -2579,7 +2603,10 @@
</choice> </choice>
</attribute> </attribute>
</optional> </optional>
<text/> <choice>
<text/>
<empty/>
</choice>
</element> </element>
</define> </define>

View File

@ -691,7 +691,7 @@ virCapabilitiesFormatXML(virCapsPtr caps)
} }
virBufferAdjustIndent(&xml, 6); virBufferAdjustIndent(&xml, 6);
virCPUDefFormatBuf(&xml, caps->host.cpu); virCPUDefFormatBuf(&xml, caps->host.cpu, 0);
virBufferAdjustIndent(&xml, -6); virBufferAdjustIndent(&xml, -6);
virBufferAddLit(&xml, " </cpu>\n"); virBufferAddLit(&xml, " </cpu>\n");

View File

@ -39,6 +39,11 @@
VIR_ENUM_IMPL(virCPU, VIR_CPU_TYPE_LAST, VIR_ENUM_IMPL(virCPU, VIR_CPU_TYPE_LAST,
"host", "guest", "auto") "host", "guest", "auto")
VIR_ENUM_IMPL(virCPUMode, VIR_CPU_MODE_LAST,
"custom",
"host-model",
"host-passthrough")
VIR_ENUM_IMPL(virCPUMatch, VIR_CPU_MATCH_LAST, VIR_ENUM_IMPL(virCPUMatch, VIR_CPU_MATCH_LAST,
"minimum", "minimum",
"exact", "exact",
@ -100,6 +105,7 @@ virCPUDefCopy(const virCPUDefPtr cpu)
copy->nfeatures_max = cpu->nfeatures; copy->nfeatures_max = cpu->nfeatures;
copy->type = cpu->type; copy->type = cpu->type;
copy->mode = cpu->mode;
copy->match = cpu->match; copy->match = cpu->match;
copy->fallback = cpu->fallback; copy->fallback = cpu->fallback;
copy->sockets = cpu->sockets; copy->sockets = cpu->sockets;
@ -151,6 +157,7 @@ virCPUDefParseXML(const xmlNodePtr node,
xmlNodePtr *nodes = NULL; xmlNodePtr *nodes = NULL;
int n; int n;
unsigned int i; unsigned int i;
char *cpuMode;
if (!xmlStrEqual(node->name, BAD_CAST "cpu")) { if (!xmlStrEqual(node->name, BAD_CAST "cpu")) {
virCPUReportError(VIR_ERR_INTERNAL_ERROR, virCPUReportError(VIR_ERR_INTERNAL_ERROR,
@ -173,10 +180,35 @@ virCPUDefParseXML(const xmlNodePtr node,
goto error; goto error;
} }
def->type = VIR_CPU_TYPE_HOST; def->type = VIR_CPU_TYPE_HOST;
} else } else {
def->type = VIR_CPU_TYPE_GUEST; def->type = VIR_CPU_TYPE_GUEST;
} else }
} else {
def->type = mode; 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) { if (def->type == VIR_CPU_TYPE_GUEST) {
char *match = virXMLPropString(node, "match"); char *match = virXMLPropString(node, "match");
@ -214,7 +246,9 @@ virCPUDefParseXML(const xmlNodePtr node,
goto error; 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; const char *fallback;
fallback = virXPathString("string(./model[1]/@fallback)", ctxt); fallback = virXPathString("string(./model[1]/@fallback)", ctxt);
@ -311,9 +345,9 @@ virCPUDefParseXML(const xmlNodePtr node,
"%s", _("Invalid CPU feature policy")); "%s", _("Invalid CPU feature policy"));
goto error; goto error;
} }
} } else {
else
policy = -1; policy = -1;
}
if (!(name = virXMLPropString(nodes[i], "name")) || *name == 0) { if (!(name = virXMLPropString(nodes[i], "name")) || *name == 0) {
VIR_FREE(name); VIR_FREE(name);
@ -407,11 +441,12 @@ error:
char * char *
virCPUDefFormat(virCPUDefPtr def) virCPUDefFormat(virCPUDefPtr def,
unsigned int flags)
{ {
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
if (virCPUDefFormatBufFull(&buf, def) < 0) if (virCPUDefFormatBufFull(&buf, def, flags) < 0)
goto cleanup; goto cleanup;
if (virBufferError(&buf)) if (virBufferError(&buf))
@ -429,29 +464,44 @@ cleanup:
int int
virCPUDefFormatBufFull(virBufferPtr buf, virCPUDefFormatBufFull(virBufferPtr buf,
virCPUDefPtr def) virCPUDefPtr def,
unsigned int flags)
{ {
if (!def) if (!def)
return 0; return 0;
if (def->type == VIR_CPU_TYPE_GUEST && def->model) { virBufferAddLit(buf, "<cpu");
const char *match; if (def->type == VIR_CPU_TYPE_GUEST) {
if (!(match = virCPUMatchTypeToString(def->match))) { const char *tmp;
virCPUReportError(VIR_ERR_INTERNAL_ERROR,
_("Unexpected CPU match policy %d"), def->match); if (def->mode != VIR_CPU_MODE_CUSTOM || def->model) {
return -1; 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); if (def->model &&
} else { (def->mode == VIR_CPU_MODE_CUSTOM ||
virBufferAddLit(buf, "<cpu>\n"); (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) if (def->arch)
virBufferAsprintf(buf, " <arch>%s</arch>\n", def->arch); virBufferAsprintf(buf, " <arch>%s</arch>\n", def->arch);
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
if (virCPUDefFormatBuf(buf, def) < 0) if (virCPUDefFormatBuf(buf, def, flags) < 0)
return -1; return -1;
virBufferAdjustIndent(buf, -2); virBufferAdjustIndent(buf, -2);
@ -462,22 +512,31 @@ virCPUDefFormatBufFull(virBufferPtr buf,
int int
virCPUDefFormatBuf(virBufferPtr buf, virCPUDefFormatBuf(virBufferPtr buf,
virCPUDefPtr def) virCPUDefPtr def,
unsigned int flags)
{ {
unsigned int i; unsigned int i;
bool formatModel;
bool formatFallback;
if (!def) if (!def)
return 0; 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) { if (!def->model && def->nfeatures) {
virCPUReportError(VIR_ERR_INTERNAL_ERROR, virCPUReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Non-empty feature list specified without CPU model")); "%s", _("Non-empty feature list specified without CPU model"));
return -1; return -1;
} }
if (def->model) { if ((formatModel && def->model) || formatFallback) {
virBufferAddLit(buf, "<model"); virBufferAddLit(buf, "<model");
if (def->type == VIR_CPU_TYPE_GUEST) { if (formatFallback) {
const char *fallback; const char *fallback;
fallback = virCPUFallbackTypeToString(def->fallback); fallback = virCPUFallbackTypeToString(def->fallback);
@ -489,12 +548,15 @@ virCPUDefFormatBuf(virBufferPtr buf,
} }
virBufferAsprintf(buf, " fallback='%s'", fallback); 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); virBufferAsprintf(buf, "<vendor>%s</vendor>\n", def->vendor);
}
if (def->sockets && def->cores && def->threads) { if (def->sockets && def->cores && def->threads) {
virBufferAddLit(buf, "<topology"); virBufferAddLit(buf, "<topology");
@ -504,29 +566,32 @@ virCPUDefFormatBuf(virBufferPtr buf,
virBufferAddLit(buf, "/>\n"); virBufferAddLit(buf, "/>\n");
} }
for (i = 0 ; i < def->nfeatures ; i++) { if (formatModel) {
virCPUFeatureDefPtr feature = def->features + i; for (i = 0 ; i < def->nfeatures ; i++) {
virCPUFeatureDefPtr feature = def->features + i;
if (!feature->name) { 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) {
virCPUReportError(VIR_ERR_INTERNAL_ERROR, virCPUReportError(VIR_ERR_INTERNAL_ERROR,
_("Unexpected CPU feature policy %d"), feature->policy); "%s", _("Missing CPU feature name"));
return -1; return -1;
} }
virBufferAsprintf(buf, "<feature policy='%s' name='%s'/>\n",
policy, feature->name); if (def->type == VIR_CPU_TYPE_GUEST) {
} else { const char *policy;
virBufferAsprintf(buf, "<feature name='%s'/>\n",
feature->name); 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; 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)) { if (STRNEQ_NULLABLE(src->arch, dst->arch)) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU arch %s does not match source %s"), _("Target CPU arch %s does not match source %s"),

View File

@ -38,6 +38,16 @@ enum virCPUType {
VIR_ENUM_DECL(virCPU) 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 { enum virCPUMatch {
VIR_CPU_MATCH_MINIMUM, VIR_CPU_MATCH_MINIMUM,
VIR_CPU_MATCH_EXACT, VIR_CPU_MATCH_EXACT,
@ -89,6 +99,7 @@ typedef struct _virCPUDef virCPUDef;
typedef virCPUDef *virCPUDefPtr; typedef virCPUDef *virCPUDefPtr;
struct _virCPUDef { struct _virCPUDef {
int type; /* enum virCPUType */ int type; /* enum virCPUType */
int mode; /* enum virCPUMode */
int match; /* enum virCPUMatch */ int match; /* enum virCPUMatch */
char *arch; char *arch;
char *model; char *model;
@ -123,14 +134,17 @@ virCPUDefIsEqual(virCPUDefPtr src,
virCPUDefPtr dst); virCPUDefPtr dst);
char * char *
virCPUDefFormat(virCPUDefPtr def); virCPUDefFormat(virCPUDefPtr def,
unsigned int flags);
int int
virCPUDefFormatBuf(virBufferPtr buf, virCPUDefFormatBuf(virBufferPtr buf,
virCPUDefPtr def); virCPUDefPtr def,
unsigned int flags);
int int
virCPUDefFormatBufFull(virBufferPtr buf, virCPUDefFormatBufFull(virBufferPtr buf,
virCPUDefPtr def); virCPUDefPtr def,
unsigned int flags);
int int
virCPUDefAddFeature(virCPUDefPtr cpu, virCPUDefAddFeature(virCPUDefPtr cpu,

View File

@ -11639,7 +11639,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
} }
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
if (virCPUDefFormatBufFull(buf, def->cpu) < 0) if (virCPUDefFormatBufFull(buf, def->cpu, flags) < 0)
goto cleanup; goto cleanup;
virBufferAdjustIndent(buf, -2); virBufferAdjustIndent(buf, -2);

View File

@ -322,7 +322,7 @@ cpuBaselineXML(const char **xmlCPUs,
if (!(cpu = cpuBaseline(cpus, ncpus, models, nmodels))) if (!(cpu = cpuBaseline(cpus, ncpus, models, nmodels)))
goto error; goto error;
cpustr = virCPUDefFormat(cpu); cpustr = virCPUDefFormat(cpu, 0);
cleanup: cleanup:
if (cpus) { if (cpus) {

View File

@ -176,7 +176,7 @@ cpuTestCompareXML(const char *arch,
if (virtTestLoadFile(xml, &expected) < 0) if (virtTestLoadFile(xml, &expected) < 0)
goto cleanup; goto cleanup;
if (!(actual = virCPUDefFormat(cpu))) if (!(actual = virCPUDefFormat(cpu, 0)))
goto cleanup; goto cleanup;
if (STRNEQ(expected, actual)) { if (STRNEQ(expected, actual)) {

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<model fallback='allow'>Conroe</model> <model fallback='allow'>Conroe</model>
<vendor>Intel</vendor> <vendor>Intel</vendor>
<feature policy='disable' name='lahf_lm'/> <feature policy='disable' name='lahf_lm'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<model fallback='allow'>core2duo</model> <model fallback='allow'>core2duo</model>
<feature policy='disable' name='nx'/> <feature policy='disable' name='nx'/>
</cpu> </cpu>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<model fallback='allow'>Opteron_G2</model> <model fallback='allow'>Opteron_G2</model>
<feature policy='disable' name='svm'/> <feature policy='disable' name='svm'/>
<feature policy='disable' name='rdtscp'/> <feature policy='disable' name='rdtscp'/>

View File

@ -1,3 +1,3 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<model fallback='allow'>Opteron_G1</model> <model fallback='allow'>Opteron_G1</model>
</cpu> </cpu>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<arch>x86_64</arch> <arch>x86_64</arch>
<model fallback='allow'>486</model> <model fallback='allow'>486</model>
<feature policy='require' name='svm'/> <feature policy='require' name='svm'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<arch>x86_64</arch> <arch>x86_64</arch>
<model fallback='allow'>Nehalem</model> <model fallback='allow'>Nehalem</model>
<feature policy='require' name='svm'/> <feature policy='require' name='svm'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<arch>x86_64</arch> <arch>x86_64</arch>
<model fallback='allow'>qemu64</model> <model fallback='allow'>qemu64</model>
<feature policy='require' name='lahf_lm'/> <feature policy='require' name='lahf_lm'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<arch>x86_64</arch> <arch>x86_64</arch>
<model fallback='allow'>Nehalem</model> <model fallback='allow'>Nehalem</model>
<feature policy='require' name='svm'/> <feature policy='require' name='svm'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<arch>x86_64</arch> <arch>x86_64</arch>
<model fallback='allow'>Penryn</model> <model fallback='allow'>Penryn</model>
<feature policy='require' name='svm'/> <feature policy='require' name='svm'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<model fallback='allow'>Penryn</model> <model fallback='allow'>Penryn</model>
<topology sockets='2' cores='4' threads='1'/> <topology sockets='2' cores='4' threads='1'/>
<feature policy='require' name='dca'/> <feature policy='require' name='dca'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<model fallback='allow'>Penryn</model> <model fallback='allow'>Penryn</model>
<feature policy='require' name='dca'/> <feature policy='require' name='dca'/>
<feature policy='require' name='xtpr'/> <feature policy='require' name='xtpr'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<arch>x86_64</arch> <arch>x86_64</arch>
<model fallback='allow'>Nehalem</model> <model fallback='allow'>Nehalem</model>
</cpu> </cpu>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<model fallback='allow'>pentium3</model> <model fallback='allow'>pentium3</model>
<feature policy='require' name='lahf_lm'/> <feature policy='require' name='lahf_lm'/>
<feature policy='require' name='lm'/> <feature policy='require' name='lm'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<arch>x86_64</arch> <arch>x86_64</arch>
<model fallback='allow'>Penryn</model> <model fallback='allow'>Penryn</model>
<feature policy='require' name='3dnow'/> <feature policy='require' name='3dnow'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<arch>x86_64</arch> <arch>x86_64</arch>
<model fallback='allow'>core2duo</model> <model fallback='allow'>core2duo</model>
<feature policy='require' name='lahf_lm'/> <feature policy='require' name='lahf_lm'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<arch>x86_64</arch> <arch>x86_64</arch>
<model fallback='allow'>pentium3</model> <model fallback='allow'>pentium3</model>
<feature policy='require' name='lahf_lm'/> <feature policy='require' name='lahf_lm'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<arch>x86_64</arch> <arch>x86_64</arch>
<model fallback='allow'>Nehalem</model> <model fallback='allow'>Nehalem</model>
<feature policy='require' name='dca'/> <feature policy='require' name='dca'/>

View File

@ -1,4 +1,4 @@
<cpu match='exact'> <cpu mode='custom' match='exact'>
<arch>x86_64</arch> <arch>x86_64</arch>
<model fallback='allow'>Penryn</model> <model fallback='allow'>Penryn</model>
<feature policy='require' name='svm'/> <feature policy='require' name='svm'/>

View File

@ -15,7 +15,7 @@
<apic/> <apic/>
<pae/> <pae/>
</features> </features>
<cpu match='exact'> <cpu mode='custom' match='exact'>
<model fallback='allow'>core2duo</model> <model fallback='allow'>core2duo</model>
<vendor>Intel</vendor> <vendor>Intel</vendor>
<topology sockets='1' cores='2' threads='1'/> <topology sockets='1' cores='2' threads='1'/>

View File

@ -112,6 +112,7 @@ virCapsPtr testQemuCapsInit(void) {
}; };
static virCPUDef host_cpu = { static virCPUDef host_cpu = {
VIR_CPU_TYPE_HOST, /* type */ VIR_CPU_TYPE_HOST, /* type */
0, /* mode */
0, /* match */ 0, /* match */
(char *) "x86_64", /* arch */ (char *) "x86_64", /* arch */
(char *) "core2duo", /* model */ (char *) "core2duo", /* model */