[libvirt PATCH 1/5] conf: define a new "maximum" CPU mode

Daniel P. Berrangé berrange at redhat.com
Tue Feb 9 13:58:57 UTC 2021


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.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 docs/formatdomain.rst        | 24 ++++++++++++++++++++++++
 src/conf/cpu_conf.c          | 13 +++++++++----
 src/conf/cpu_conf.h          |  1 +
 src/cpu/cpu.c                |  1 +
 src/qemu/qemu_capabilities.c |  1 +
 src/qemu/qemu_command.c      |  1 +
 src/qemu/qemu_domain.c       |  1 +
 src/qemu/qemu_validate.c     |  1 +
 8 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 0f78aa3a8c..976770bdb6 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1226,6 +1226,13 @@ following collection of elements. :since:`Since 0.7.5`
      <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
 ``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 d41b4a4753..d0378f94bc 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;
-- 
2.29.2




More information about the libvir-list mailing list