conf: define a new "maximum" CPU mode

For hardware virtualization this is functionally identical to the
existing host-passthrough mode so the same caveats apply.

For emulated guest this exposes the maximum featureset supported by
the emulator. Note that despite being emulated this is not guaranteed
to be migration safe, especially if different emulator software versions
are used on each host.

Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2021-02-05 15:51:09 +00:00
parent 676e56e515
commit d153c101d2
8 changed files with 39 additions and 4 deletions

View File

@ -1226,6 +1226,13 @@ following collection of elements. :since:`Since 0.7.5`
<feature policy='disable' name='lahf_lm'/> <feature policy='disable' name='lahf_lm'/>
... ...
::
<cpu mode='maximum' migratable='off'>
<cache mode='passthrough'/>
<feature policy='disable' name='lahf_lm'/>
...
In case no restrictions need to be put on CPU model and its features, a simpler In case no restrictions need to be put on CPU model and its features, a simpler
``cpu`` element can be used. :since:`Since 0.7.6` ``cpu`` element can be used. :since:`Since 0.7.6`
@ -1351,6 +1358,18 @@ In case no restrictions need to be put on CPU model and its features, a simpler
another host safer: even with ``migratable='on'`` migration will be another host safer: even with ``migratable='on'`` migration will be
dangerous unless both hosts are identical as described above. dangerous unless both hosts are identical as described above.
``maximum``
When running a guest with hardware virtualization this CPU model is
functionally identical to ``host-passthrough``, so refer to the docs
above.
When running a guest with CPU emulation, this CPU model will enable
the maximum set of features that the emulation engine is able to support.
Note that even with ``migratable='on'`` migration will be dangerous
unless both hosts are running identical versions of the emulation code.
:since:`Since 7.1.0` with the QEMU driver.
Both ``host-model`` and ``host-passthrough`` modes make sense when a domain Both ``host-model`` and ``host-passthrough`` modes make sense when a domain
can run directly on the host CPUs (for example, domains with type ``kvm``). can run directly on the host CPUs (for example, domains with type ``kvm``).
The actual host CPU is irrelevant for domains with emulated virtual CPUs The actual host CPU is irrelevant for domains with emulated virtual CPUs
@ -1358,6 +1377,11 @@ In case no restrictions need to be put on CPU model and its features, a simpler
``host-model`` may be implemented even for domains running on emulated CPUs ``host-model`` may be implemented even for domains running on emulated CPUs
in which case the best CPU the hypervisor is able to emulate may be used in which case the best CPU the hypervisor is able to emulate may be used
rather then trying to mimic the host CPU model. rather then trying to mimic the host CPU model.
If an application does not care about a specific CPU, just wants the
best featureset without a need for migration compatibility, the
``maximum`` model is a good choice on hypervisors where it is available.
``model`` ``model``
The content of the ``model`` element specifies CPU model requested by the The content of the ``model`` element specifies CPU model requested by the
guest. The list of available CPU models and their definition can be found in guest. The list of available CPU models and their definition can be found in

View File

@ -44,6 +44,7 @@ VIR_ENUM_IMPL(virCPUMode,
"custom", "custom",
"host-model", "host-model",
"host-passthrough", "host-passthrough",
"maximum",
); );
VIR_ENUM_IMPL(virCPUMatch, VIR_ENUM_IMPL(virCPUMatch,
@ -402,10 +403,11 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
if ((migratable = virXMLPropString(ctxt->node, "migratable"))) { if ((migratable = virXMLPropString(ctxt->node, "migratable"))) {
int val; int val;
if (def->mode != VIR_CPU_MODE_HOST_PASSTHROUGH) { if (def->mode != VIR_CPU_MODE_HOST_PASSTHROUGH &&
def->mode != VIR_CPU_MODE_MAXIMUM) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Attribute migratable is only allowed for " _("Attribute migratable is only allowed for "
"host-passthrough CPU")); "'host-passthrough' / 'maximum' CPU mode"));
return -1; return -1;
} }
@ -500,7 +502,8 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
} }
if (def->type == VIR_CPU_TYPE_GUEST && if (def->type == VIR_CPU_TYPE_GUEST &&
def->mode != VIR_CPU_MODE_HOST_PASSTHROUGH) { def->mode != VIR_CPU_MODE_HOST_PASSTHROUGH &&
def->mode != VIR_CPU_MODE_MAXIMUM) {
if ((fallback = virXPathString("string(./model[1]/@fallback)", ctxt))) { if ((fallback = virXPathString("string(./model[1]/@fallback)", ctxt))) {
if ((def->fallback = virCPUFallbackTypeFromString(fallback)) < 0) { if ((def->fallback = virCPUFallbackTypeFromString(fallback)) < 0) {
@ -727,7 +730,9 @@ virCPUDefFormatBufFull(virBufferPtr buf,
virCPUCheckTypeToString(def->check)); virCPUCheckTypeToString(def->check));
} }
if (def->mode == VIR_CPU_MODE_HOST_PASSTHROUGH && def->migratable) { if ((def->mode == VIR_CPU_MODE_HOST_PASSTHROUGH ||
def->mode == VIR_CPU_MODE_MAXIMUM) &&
def->migratable) {
virBufferAsprintf(&attributeBuf, " migratable='%s'", virBufferAsprintf(&attributeBuf, " migratable='%s'",
virTristateSwitchTypeToString(def->migratable)); virTristateSwitchTypeToString(def->migratable));
} }

View File

@ -44,6 +44,7 @@ typedef enum {
VIR_CPU_MODE_CUSTOM, VIR_CPU_MODE_CUSTOM,
VIR_CPU_MODE_HOST_MODEL, VIR_CPU_MODE_HOST_MODEL,
VIR_CPU_MODE_HOST_PASSTHROUGH, VIR_CPU_MODE_HOST_PASSTHROUGH,
VIR_CPU_MODE_MAXIMUM,
VIR_CPU_MODE_LAST VIR_CPU_MODE_LAST
} virCPUMode; } virCPUMode;

View File

@ -563,6 +563,7 @@ virCPUUpdate(virArch arch,
switch ((virCPUMode) guest->mode) { switch ((virCPUMode) guest->mode) {
case VIR_CPU_MODE_HOST_PASSTHROUGH: case VIR_CPU_MODE_HOST_PASSTHROUGH:
case VIR_CPU_MODE_MAXIMUM:
return 0; return 0;
case VIR_CPU_MODE_HOST_MODEL: case VIR_CPU_MODE_HOST_MODEL:

View File

@ -2334,6 +2334,7 @@ virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
cpus = virQEMUCapsGetAccel(qemuCaps, type)->cpuModels; cpus = virQEMUCapsGetAccel(qemuCaps, type)->cpuModels;
return cpus && cpus->ncpus > 0; return cpus && cpus->ncpus > 0;
case VIR_CPU_MODE_MAXIMUM:
case VIR_CPU_MODE_LAST: case VIR_CPU_MODE_LAST:
break; break;
} }

View File

@ -6356,6 +6356,7 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
virBufferAdd(buf, cpu->model, -1); virBufferAdd(buf, cpu->model, -1);
break; break;
case VIR_CPU_MODE_MAXIMUM:
case VIR_CPU_MODE_LAST: case VIR_CPU_MODE_LAST:
break; break;
} }

View File

@ -4151,6 +4151,7 @@ qemuDomainDefCPUPostParse(virDomainDefPtr def,
def->cpu->check = VIR_CPU_CHECK_PARTIAL; def->cpu->check = VIR_CPU_CHECK_PARTIAL;
break; break;
case VIR_CPU_MODE_MAXIMUM:
case VIR_CPU_MODE_LAST: case VIR_CPU_MODE_LAST:
break; break;
} }

View File

@ -396,6 +396,7 @@ qemuValidateDomainDefCpu(virQEMUDriverPtr driver,
* CUSTOM. * CUSTOM.
*/ */
break; break;
case VIR_CPU_MODE_MAXIMUM:
case VIR_CPU_MODE_CUSTOM: case VIR_CPU_MODE_CUSTOM:
case VIR_CPU_MODE_LAST: case VIR_CPU_MODE_LAST:
break; break;