<span class="since">Since 0.8.5</span> the <code>match</code>
attribute can be omitted and will default to <code>exact</code>.
+ Sometimes the hypervisor is not able to create a virtual CPU exactly
+ matching the specification passed by libvirt.
+ <span class="since">Since 3.2.0</span>, an optional <code>check</code>
+ attribute can be used to request a specific way of checking whether
+ the virtual CPU matches the specification. It is usually safe to omit
+ this attribute when starting a domain and stick with the default
+ value. Once the domain starts, libvirt will automatically change the
+ <code>check</code> attribute to the best supported value to ensure the
+ virtual CPU does not change when the domain is migrated to another
+ host. The following values can be used:
+
+ <dl>
+ <dt><code>none</code></dt>
+ <dd>Libvirt does no checking and it is up to the hypervisor to
+ refuse to start the domain if it cannot provide the requested CPU.
+ With QEMU this means no checking is done at all since the default
+ behavior of QEMU is to emit warnings, but start the domain anyway.
+ </dd>
+
+ <dt><code>partial</code></dt>
+ <dd>Libvirt will check the guest CPU specification before starting
+ a domain, but the rest is left on the hypervisor. It can still
+ provide a different virtual CPU.</dd>
+
+ <dt><code>full</code></dt>
+ <dd>The virtual CPU created by the hypervisor will be checked
+ against the CPU specification and the domain will not be started
+ unless the two CPUs match.</dd>
+ </dl>
+
<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
</attribute>
</define>
+ <define name="cpuCheck">
+ <attribute name="check">
+ <choice>
+ <value>none</value>
+ <value>partial</value>
+ <value>full</value>
+ </choice>
+ </attribute>
+ </define>
+
<define name="cpuModel">
<element name="model">
<optional>
<optional>
<ref name="cpuMatch"/>
</optional>
+ <optional>
+ <ref name="cpuCheck"/>
+ </optional>
<interleave>
<optional>
<ref name="cpuModel"/>
"exact",
"strict")
+VIR_ENUM_IMPL(virCPUCheck, VIR_CPU_CHECK_LAST,
+ "default",
+ "none",
+ "partial",
+ "full")
+
VIR_ENUM_IMPL(virCPUFallback, VIR_CPU_FALLBACK_LAST,
"allow",
"forbid")
copy->type = cpu->type;
copy->mode = cpu->mode;
copy->match = cpu->match;
+ copy->check = cpu->check;
copy->fallback = cpu->fallback;
copy->sockets = cpu->sockets;
copy->cores = cpu->cores;
if (def->type == VIR_CPU_TYPE_GUEST) {
char *match = virXMLPropString(node, "match");
+ char *check;
if (!match) {
if (virXPathBoolean("boolean(./model)", ctxt))
goto error;
}
}
+
+ if ((check = virXMLPropString(node, "check"))) {
+ int value = virCPUCheckTypeFromString(check);
+ VIR_FREE(check);
+
+ if (value < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Invalid check attribute for CPU "
+ "specification"));
+ goto error;
+ }
+ def->check = value;
+ }
}
if (def->type == VIR_CPU_TYPE_HOST) {
}
virBufferAsprintf(&attributeBuf, " match='%s'", tmp);
}
+
+ if (def->check) {
+ virBufferAsprintf(&attributeBuf, " check='%s'",
+ virCPUCheckTypeToString(def->check));
+ }
}
/* Format children */
VIR_ENUM_DECL(virCPUMatch)
+typedef enum {
+ VIR_CPU_CHECK_DEFAULT,
+ VIR_CPU_CHECK_NONE,
+ VIR_CPU_CHECK_PARTIAL,
+ VIR_CPU_CHECK_FULL,
+
+ VIR_CPU_CHECK_LAST
+} virCPUCheck;
+
+VIR_ENUM_DECL(virCPUCheck)
+
typedef enum {
VIR_CPU_FALLBACK_ALLOW,
VIR_CPU_FALLBACK_FORBID,
int type; /* enum virCPUType */
int mode; /* enum virCPUMode */
int match; /* enum virCPUMatch */
+ virCPUCheck check;
virArch arch;
char *model;
char *vendor_id; /* vendor id returned by CPUID in the guest */
}
+static int
+virDomainDefPostParseCPU(virDomainDefPtr def)
+{
+ if (!def->cpu)
+ return 0;
+
+ if (def->cpu->mode == VIR_CPU_MODE_CUSTOM &&
+ !def->cpu->model &&
+ def->cpu->check != VIR_CPU_CHECK_DEFAULT) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("check attribute specified for CPU with no model"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
virDomainDefPostParseInternal(virDomainDefPtr def,
struct virDomainDefPostParseDeviceIteratorData *data)
virDomainDefPostParseGraphics(def);
+ if (virDomainDefPostParseCPU(def) < 0)
+ return -1;
+
return 0;
}