diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index aa7ea61258..2493be595f 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -1226,6 +1226,13 @@ following collection of elements. :since:`Since 0.7.5` ... +:: + + + + + ... + 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` @@ -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 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 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 @@ -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 in which case the best CPU the hypervisor is able to emulate may be used 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`` 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 diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c index f98b0a0eb3..eb4bfbbcfa 100644 --- a/src/conf/cpu_conf.c +++ b/src/conf/cpu_conf.c @@ -44,6 +44,7 @@ VIR_ENUM_IMPL(virCPUMode, "custom", "host-model", "host-passthrough", + "maximum", ); VIR_ENUM_IMPL(virCPUMatch, @@ -402,10 +403,11 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, if ((migratable = virXMLPropString(ctxt->node, "migratable"))) { 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", _("Attribute migratable is only allowed for " - "host-passthrough CPU")); + "'host-passthrough' / 'maximum' CPU mode")); return -1; } @@ -500,7 +502,8 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, } 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 ((def->fallback = virCPUFallbackTypeFromString(fallback)) < 0) { @@ -727,7 +730,9 @@ virCPUDefFormatBufFull(virBufferPtr buf, 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'", virTristateSwitchTypeToString(def->migratable)); } diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h index b744b06c2d..7ab198d370 100644 --- a/src/conf/cpu_conf.h +++ b/src/conf/cpu_conf.h @@ -44,6 +44,7 @@ typedef enum { VIR_CPU_MODE_CUSTOM, VIR_CPU_MODE_HOST_MODEL, VIR_CPU_MODE_HOST_PASSTHROUGH, + VIR_CPU_MODE_MAXIMUM, VIR_CPU_MODE_LAST } virCPUMode; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 44094bd0df..6ff88d6a9f 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -563,6 +563,7 @@ virCPUUpdate(virArch arch, switch ((virCPUMode) guest->mode) { case VIR_CPU_MODE_HOST_PASSTHROUGH: + case VIR_CPU_MODE_MAXIMUM: return 0; case VIR_CPU_MODE_HOST_MODEL: diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index ebd6607888..fb302c8e0c 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2334,6 +2334,7 @@ virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps, cpus = virQEMUCapsGetAccel(qemuCaps, type)->cpuModels; return cpus && cpus->ncpus > 0; + case VIR_CPU_MODE_MAXIMUM: case VIR_CPU_MODE_LAST: break; } diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 92036d26c0..059563d92f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6356,6 +6356,7 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver, virBufferAdd(buf, cpu->model, -1); break; + case VIR_CPU_MODE_MAXIMUM: case VIR_CPU_MODE_LAST: break; } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 0f09e321fb..d89aea340b 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4151,6 +4151,7 @@ qemuDomainDefCPUPostParse(virDomainDefPtr def, def->cpu->check = VIR_CPU_CHECK_PARTIAL; break; + case VIR_CPU_MODE_MAXIMUM: case VIR_CPU_MODE_LAST: break; } diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 78e80b7919..bf4ac19104 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -396,6 +396,7 @@ qemuValidateDomainDefCpu(virQEMUDriverPtr driver, * CUSTOM. */ break; + case VIR_CPU_MODE_MAXIMUM: case VIR_CPU_MODE_CUSTOM: case VIR_CPU_MODE_LAST: break;