]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
cpu: Run arch specific code for virCPUUpdate for all custom CPUs
authorJiri Denemark <jdenemar@redhat.com>
Thu, 19 Nov 2020 20:35:41 +0000 (21:35 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Tue, 24 Nov 2020 19:13:23 +0000 (20:13 +0100)
Until now, the function returned immediately when the guest CPU
definition did not use optional features or minimum match. Clearly,
there's nothing to be updated according to the host CPU in this case,
but the arch specific code may still want to do some compatibility
updates based on the model and features used in the guest CPU
definition.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Tim Wiederhake <twiederh@redhat.com>
src/cpu/cpu.c
src/cpu/cpu.h
src/cpu/cpu_arm.c
src/cpu/cpu_ppc64.c
src/cpu/cpu_s390.c
src/cpu/cpu_x86.c

index bf948119604c0f0653e68338a11c435863b6ec16..44094bd0dff3ba575dcde1ff111d0429b9df4242 100644 (file)
@@ -538,12 +538,11 @@ virCPUBaseline(virArch arch,
  * @guest: guest CPU definition to be updated
  * @host: host CPU definition
  *
- * Updates @guest CPU definition according to @host CPU. This is required to
- * support guest CPU definitions specified relatively to host CPU, such as
- * CPUs with VIR_CPU_MODE_CUSTOM and optional features or
- * VIR_CPU_MATCH_MINIMUM, or CPUs with VIR_CPU_MODE_HOST_MODEL.
- * When the guest CPU was not specified relatively, the function does nothing
- * and returns success.
+ * Updates @guest CPU definition possibly taking @host CPU into account. This
+ * is required for maintaining compatibility with older libvirt releases or to
+ * support guest CPU definitions specified relatively to host CPU, such as CPUs
+ * with VIR_CPU_MODE_CUSTOM and optional features or VIR_CPU_MATCH_MINIMUM, or
+ * CPUs with VIR_CPU_MODE_HOST_MODEL.
  *
  * Returns 0 on success, -1 on error.
  */
@@ -553,6 +552,7 @@ virCPUUpdate(virArch arch,
              const virCPUDef *host)
 {
     struct cpuArchDriver *driver;
+    bool relative;
 
     VIR_DEBUG("arch=%s, guest=%p mode=%s model=%s, host=%p model=%s",
               virArchToString(arch), guest, virCPUModeTypeToString(guest->mode),
@@ -561,30 +561,36 @@ virCPUUpdate(virArch arch,
     if (!(driver = cpuGetSubDriver(arch)))
         return -1;
 
-    if (guest->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
+    switch ((virCPUMode) guest->mode) {
+    case VIR_CPU_MODE_HOST_PASSTHROUGH:
         return 0;
 
-    if (guest->mode == VIR_CPU_MODE_CUSTOM &&
-        guest->match != VIR_CPU_MATCH_MINIMUM) {
-        size_t i;
-        bool optional = false;
+    case VIR_CPU_MODE_HOST_MODEL:
+        relative = true;
+        break;
 
-        for (i = 0; i < guest->nfeatures; i++) {
-            if (guest->features[i].policy == VIR_CPU_FEATURE_OPTIONAL) {
-                optional = true;
-                break;
+    case VIR_CPU_MODE_CUSTOM:
+        if (guest->match == VIR_CPU_MATCH_MINIMUM) {
+            relative = true;
+        } else {
+            size_t i;
+
+            relative = false;
+            for (i = 0; i < guest->nfeatures; i++) {
+                if (guest->features[i].policy == VIR_CPU_FEATURE_OPTIONAL) {
+                    relative = true;
+                    break;
+                }
             }
         }
+        break;
 
-        if (!optional)
-            return 0;
+    case VIR_CPU_MODE_LAST:
+    default:
+        virReportEnumRangeError(virCPUMode, guest->mode);
+        return -1;
     }
 
-    /* We get here if guest CPU is either
-     *  - host-model
-     *  - custom with minimum match
-     *  - custom with optional features
-     */
     if (!driver->update) {
         virReportError(VIR_ERR_NO_SUPPORT,
                        _("cannot update guest CPU for %s architecture"),
@@ -592,7 +598,7 @@ virCPUUpdate(virArch arch,
         return -1;
     }
 
-    if (driver->update(guest, host) < 0)
+    if (driver->update(guest, host, relative) < 0)
         return -1;
 
     VIR_DEBUG("model=%s", NULLSTR(guest->model));
index cc2d132275c4a10a2ad2a148e5562d0fce68aea0..ff4fb7e1033afde2ff39315b9c1b84d68bb47874 100644 (file)
@@ -79,7 +79,8 @@ typedef virCPUDefPtr
 
 typedef int
 (*virCPUArchUpdate)(virCPUDefPtr guest,
-                    const virCPUDef *host);
+                    const virCPUDef *host,
+                    bool relative);
 
 typedef int
 (*virCPUArchUpdateLive)(virCPUDefPtr cpu,
index 31997b59cd7aba19ef455ae80e6050bc265f13e5..8a408a324a39ed45d771bd347ac27bbd4d1d8596 100644 (file)
@@ -415,11 +415,12 @@ virCPUarmGetMap(void)
 
 static int
 virCPUarmUpdate(virCPUDefPtr guest,
-                const virCPUDef *host)
+                const virCPUDef *host,
+                bool relative)
 {
     g_autoptr(virCPUDef) updated = NULL;
 
-    if (guest->mode != VIR_CPU_MODE_HOST_MODEL)
+    if (!relative || guest->mode != VIR_CPU_MODE_HOST_MODEL)
         return 0;
 
     if (!host) {
index 555eeecbe7f96d1aa94114278749e94f3606af4a..d71d147207958a2ebbaa9718c814066d846fb5c8 100644 (file)
@@ -614,7 +614,8 @@ virCPUppc64GetHost(virCPUDefPtr cpu,
 
 static int
 virCPUppc64Update(virCPUDefPtr guest,
-                  const virCPUDef *host G_GNUC_UNUSED)
+                  const virCPUDef *host G_GNUC_UNUSED,
+                  bool relative G_GNUC_UNUSED)
 {
     /*
      * - host-passthrough doesn't even get here
index c1c56862444b30fa43f77bd46d1afeab330a3fdd..17321dc04af2f5467c0a4202d77bfb547f2781df 100644 (file)
@@ -43,11 +43,15 @@ virCPUs390Compare(virCPUDefPtr host G_GNUC_UNUSED,
 
 static int
 virCPUs390Update(virCPUDefPtr guest,
-                 const virCPUDef *host)
+                 const virCPUDef *host,
+                 bool relative)
 {
     g_autoptr(virCPUDef) updated = NULL;
     size_t i;
 
+    if (!relative)
+        return 0;
+
     if (guest->mode == VIR_CPU_MODE_CUSTOM) {
         if (guest->match == VIR_CPU_MATCH_MINIMUM) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
index 0e533c62e13ac2b12fb5f4a7f64344203baeec3a..72f17070e1c7e7dea88870e4d26ac39dfe153da8 100644 (file)
@@ -2936,12 +2936,16 @@ x86UpdateHostModel(virCPUDefPtr guest,
 
 static int
 virCPUx86Update(virCPUDefPtr guest,
-                const virCPUDef *host)
+                const virCPUDef *host,
+                bool relative)
 {
     g_autoptr(virCPUx86Model) model = NULL;
     virCPUx86MapPtr map;
     size_t i;
 
+    if (!relative)
+        return 0;
+
     if (!host) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("unknown host CPU model"));