mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
cpu: Allow fine tuning of "host-model" cpu
https://bugzilla.redhat.com/show_bug.cgi?id=799354 Until now, the "host-model" cpu mode couldn't be influenced. This patch allows to use the <feature> elements to either enable or disable specific CPU flags. This can be used to force flags that can be emulated even if the host CPU doesn't support them.
This commit is contained in:
parent
90f9fb5a7c
commit
3c8be55c04
@ -901,11 +901,15 @@
|
|||||||
copying host CPU definition from capabilities XML into domain XML.
|
copying host CPU definition from capabilities XML into domain XML.
|
||||||
Since the CPU definition is copied just before starting a domain,
|
Since the CPU definition is copied just before starting a domain,
|
||||||
exactly the same XML can be used on different hosts while still
|
exactly the same XML can be used on different hosts while still
|
||||||
providing the best guest CPU each host supports. Neither
|
providing the best guest CPU each host supports. The
|
||||||
<code>match</code> attribute nor any <code>feature</code> elements
|
<code>match</code> attribute can't be used in this mode. Specifying
|
||||||
can be used in this mode. Specifying CPU model is not supported
|
CPU model is not supported either, but <code>model</code>'s
|
||||||
either, but <code>model</code>'s <code>fallback</code> attribute may
|
<code>fallback</code> attribute may still be used. Using the
|
||||||
still be used. Libvirt does not model every aspect of each CPU so
|
<code>feature</code> element, specific flags may be enabled or
|
||||||
|
disabled specifically in addition to the host model. This may be
|
||||||
|
used to fine tune features that can be emulated.
|
||||||
|
<span class="since">(Since 1.1.1)</span>.
|
||||||
|
Libvirt does not model every aspect of each CPU so
|
||||||
the guest CPU will not match the host CPU exactly. On the other
|
the guest CPU will not match the host CPU exactly. On the other
|
||||||
hand, the ABI provided to the guest is reproducible. During
|
hand, the ABI provided to the guest is reproducible. During
|
||||||
migration, complete CPU model definition is transferred to the
|
migration, complete CPU model definition is transferred to the
|
||||||
|
@ -361,7 +361,7 @@ virCPUDefParseXML(const xmlNodePtr node,
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
if (!def->model) {
|
if (!def->model && def->mode != VIR_CPU_MODE_HOST_MODEL) {
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
_("Non-empty feature list specified without "
|
_("Non-empty feature list specified without "
|
||||||
"CPU model"));
|
"CPU model"));
|
||||||
@ -574,7 +574,9 @@ virCPUDefFormatBuf(virBufferPtr buf,
|
|||||||
(def->mode == VIR_CPU_MODE_HOST_MODEL ||
|
(def->mode == VIR_CPU_MODE_HOST_MODEL ||
|
||||||
(def->mode == VIR_CPU_MODE_CUSTOM && def->model)));
|
(def->mode == VIR_CPU_MODE_CUSTOM && def->model)));
|
||||||
|
|
||||||
if (!def->model && def->nfeatures) {
|
if (!def->model &&
|
||||||
|
def->mode != VIR_CPU_MODE_HOST_MODEL &&
|
||||||
|
def->nfeatures) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("Non-empty feature list specified without CPU model"));
|
_("Non-empty feature list specified without CPU model"));
|
||||||
return -1;
|
return -1;
|
||||||
@ -614,7 +616,6 @@ virCPUDefFormatBuf(virBufferPtr buf,
|
|||||||
virBufferAddLit(buf, "/>\n");
|
virBufferAddLit(buf, "/>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (formatModel) {
|
|
||||||
for (i = 0; i < def->nfeatures; i++) {
|
for (i = 0; i < def->nfeatures; i++) {
|
||||||
virCPUFeatureDefPtr feature = def->features + i;
|
virCPUFeatureDefPtr feature = def->features + i;
|
||||||
|
|
||||||
@ -641,7 +642,6 @@ virCPUDefFormatBuf(virBufferPtr buf,
|
|||||||
feature->name);
|
feature->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (def->ncells) {
|
if (def->ncells) {
|
||||||
virBufferAddLit(buf, "<numa>\n");
|
virBufferAddLit(buf, "<numa>\n");
|
||||||
|
@ -1739,6 +1739,41 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
x86UpdateHostModel(virCPUDefPtr guest,
|
||||||
|
const virCPUDefPtr host)
|
||||||
|
{
|
||||||
|
virCPUDefPtr oldguest;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
guest->match = VIR_CPU_MATCH_EXACT;
|
||||||
|
|
||||||
|
/* no updates are required */
|
||||||
|
if (guest->nfeatures == 0) {
|
||||||
|
virCPUDefFreeModel(guest);
|
||||||
|
return virCPUDefCopyModel(guest, host, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update the host model according to the desired configuration */
|
||||||
|
if (!(oldguest = virCPUDefCopy(guest)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
virCPUDefFreeModel(guest);
|
||||||
|
if (virCPUDefCopyModel(guest, host, true) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < oldguest->nfeatures; i++) {
|
||||||
|
if (virCPUDefUpdateFeature(guest,
|
||||||
|
oldguest->features[i].name,
|
||||||
|
oldguest->features[i].policy) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
x86Update(virCPUDefPtr guest,
|
x86Update(virCPUDefPtr guest,
|
||||||
const virCPUDefPtr host)
|
const virCPUDefPtr host)
|
||||||
@ -1748,10 +1783,9 @@ x86Update(virCPUDefPtr guest,
|
|||||||
return x86UpdateCustom(guest, host);
|
return x86UpdateCustom(guest, host);
|
||||||
|
|
||||||
case VIR_CPU_MODE_HOST_MODEL:
|
case VIR_CPU_MODE_HOST_MODEL:
|
||||||
|
return x86UpdateHostModel(guest, host);
|
||||||
|
|
||||||
case VIR_CPU_MODE_HOST_PASSTHROUGH:
|
case VIR_CPU_MODE_HOST_PASSTHROUGH:
|
||||||
if (guest->mode == VIR_CPU_MODE_HOST_MODEL)
|
|
||||||
guest->match = VIR_CPU_MATCH_EXACT;
|
|
||||||
else
|
|
||||||
guest->match = VIR_CPU_MATCH_MINIMUM;
|
guest->match = VIR_CPU_MATCH_MINIMUM;
|
||||||
virCPUDefFreeModel(guest);
|
virCPUDefFreeModel(guest);
|
||||||
return virCPUDefCopyModel(guest, host, true);
|
return virCPUDefCopyModel(guest, host, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user