]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
cpu: Add removedPolicy parameter to virCPUUpdate
authorJiri Denemark <jdenemar@redhat.com>
Fri, 26 Apr 2024 07:57:31 +0000 (09:57 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Thu, 2 May 2024 17:56:45 +0000 (19:56 +0200)
virCPUUpdate check the CPU definition for features that were marked as
removed in the specified CPU model and explicitly adds those that were
not mentioned in the definition. So far such features were added with
VIR_CPU_FEATURE_DISABLE policy, but the caller may want to use a
different policy in some situations, which is now possible via the
removedPolicy parameter.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/cpu/cpu.c
src/cpu/cpu.h
src/cpu/cpu_arm.c
src/cpu/cpu_loongarch.c
src/cpu/cpu_ppc64.c
src/cpu/cpu_riscv64.c
src/cpu/cpu_s390.c
src/cpu/cpu_x86.c
src/qemu/qemu_domain.c
src/qemu/qemu_process.c
tests/cputest.c

index 33701811fb97b1a9dc14c288933943086a7d1d3b..a2518d7cc7b35adc981ab5990e0977ceac23960f 100644 (file)
@@ -560,19 +560,23 @@ virCPUBaseline(virArch arch,
  * @arch: CPU architecture
  * @guest: guest CPU definition to be updated
  * @host: host CPU definition
+ * @removedPolicy: default policy for features removed from the CPU model
  *
  * 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.
+ * CPUs with VIR_CPU_MODE_HOST_MODEL. If @guest CPU uses a CPU model which
+ * specifies some features as removed, such features that were not already
+ * present in the @guest CPU definition will be added there with @removedPolicy.
  *
  * Returns 0 on success, -1 on error.
  */
 int
 virCPUUpdate(virArch arch,
              virCPUDef *guest,
-             const virCPUDef *host)
+             const virCPUDef *host,
+             virCPUFeaturePolicy removedPolicy)
 {
     struct cpuArchDriver *driver;
     bool relative;
@@ -622,7 +626,7 @@ virCPUUpdate(virArch arch,
         return -1;
     }
 
-    if (driver->update(guest, host, relative) < 0)
+    if (driver->update(guest, host, relative, removedPolicy) < 0)
         return -1;
 
     VIR_DEBUG("model=%s", NULLSTR(guest->model));
index a4cdb37f03a616678cf96f5405399d62a2d8e878..d092b4f3f0653f168ae54e981fd353199d597c8b 100644 (file)
@@ -81,7 +81,8 @@ typedef virCPUDef *
 typedef int
 (*virCPUArchUpdate)(virCPUDef *guest,
                     const virCPUDef *host,
-                    bool relative);
+                    bool relative,
+                    virCPUFeaturePolicy removedPolicy);
 
 typedef int
 (*virCPUArchUpdateLive)(virCPUDef *cpu,
@@ -229,7 +230,8 @@ virCPUBaseline(virArch arch,
 int
 virCPUUpdate(virArch arch,
              virCPUDef *guest,
-             const virCPUDef *host)
+             const virCPUDef *host,
+             virCPUFeaturePolicy removedPolicy)
     ATTRIBUTE_NONNULL(2);
 
 int
index 324c701e81adeb3f876dd7bc44beab41a862e7a4..7a9c8163c8db6addd60757d3072931889404f56f 100644 (file)
@@ -448,7 +448,8 @@ virCPUarmGetMap(void)
 static int
 virCPUarmUpdate(virCPUDef *guest,
                 const virCPUDef *host,
-                bool relative)
+                bool relative,
+                virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
 {
     g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);
 
index 78d9941320970b5861f6e0f784fa00053ee86da8..0e2b0b58481cb94de3779fbb75330ec886eea5de 100644 (file)
@@ -39,7 +39,8 @@ virCPULoongArchCompare(virCPUDef *host G_GNUC_UNUSED,
 static int
 virCPULoongArchUpdate(virCPUDef *guest G_GNUC_UNUSED,
                       const virCPUDef *host G_GNUC_UNUSED,
-                      bool relative G_GNUC_UNUSED)
+                      bool relative G_GNUC_UNUSED,
+                      virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
 {
     return 0;
 }
index 448a0a7d85301d6530fcf60b32098b4eb82f3628..13f5fc9c2ca7aebd101095cdb6dc669905b2d5d0 100644 (file)
@@ -654,7 +654,8 @@ virCPUppc64GetHost(virCPUDef *cpu,
 static int
 virCPUppc64Update(virCPUDef *guest,
                   const virCPUDef *host G_GNUC_UNUSED,
-                  bool relative G_GNUC_UNUSED)
+                  bool relative G_GNUC_UNUSED,
+                  virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
 {
     /*
      * - host-passthrough doesn't even get here
index 4cb795f849d38a152db5264c1dcf015301616de7..276c80a4015ff74be32f2e663bff5e45c4d71a20 100644 (file)
@@ -49,7 +49,8 @@ virCPURiscv64ValidateFeatures(virCPUDef *cpu G_GNUC_UNUSED)
 static int
 virCPURiscv64Update(virCPUDef *guest,
                     const virCPUDef *host,
-                    bool relative)
+                    bool relative,
+                    virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
 {
     g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);
 
index 13695ee97a9c502829c643bb933d97fa6f919308..bcfe3fc07a20b9e96eb447db0284b301159a2d16 100644 (file)
@@ -42,7 +42,8 @@ virCPUs390Compare(virCPUDef *host G_GNUC_UNUSED,
 static int
 virCPUs390Update(virCPUDef *guest,
                  const virCPUDef *host,
-                 bool relative)
+                 bool relative,
+                 virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
 {
     g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);
     size_t i;
index 8770f52d15993c48d976dbaacb02228cbb3fad16..7a70eed9e7f8072070ef5067f9fba3fb9a12ac34 100644 (file)
@@ -829,6 +829,22 @@ x86DataAddSignature(virCPUx86Data *data,
 }
 
 
+/*
+ * Adds features removed from the CPU @model to @cpu with a specified @policy
+ * unless the features were already explicitly mentioned in @cpu.
+ */
+static void
+virCPUx86AddRemovedFeatures(virCPUDef *cpu,
+                            virCPUx86Model *model,
+                            virCPUFeaturePolicy policy)
+{
+    char **feat;
+
+    for (feat = model->removedFeatures; feat && *feat; feat++)
+        virCPUDefAddFeatureIfMissing(cpu, *feat, policy);
+}
+
+
 /*
  * Disables features removed from the CPU @model unless they are already
  * mentioned in @cpu to make sure these features will always be explicitly
@@ -838,15 +854,7 @@ static void
 virCPUx86DisableRemovedFeatures(virCPUDef *cpu,
                                 virCPUx86Model *model)
 {
-    char **feat = model->removedFeatures;
-
-    if (!feat)
-        return;
-
-    while (*feat) {
-        virCPUDefAddFeatureIfMissing(cpu, *feat, VIR_CPU_FEATURE_DISABLE);
-        feat++;
-    }
+    virCPUx86AddRemovedFeatures(cpu, model, VIR_CPU_FEATURE_DISABLE);
 }
 
 
@@ -2940,7 +2948,8 @@ x86UpdateHostModel(virCPUDef *guest,
 static int
 virCPUx86Update(virCPUDef *guest,
                 const virCPUDef *host,
-                bool relative)
+                bool relative,
+                virCPUFeaturePolicy removedPolicy)
 {
     g_autoptr(virCPUx86Model) model = NULL;
     virCPUx86Model *guestModel;
@@ -2985,7 +2994,7 @@ virCPUx86Update(virCPUDef *guest,
         return -1;
     }
 
-    virCPUx86DisableRemovedFeatures(guest, guestModel);
+    virCPUx86AddRemovedFeatures(guest, guestModel, removedPolicy);
 
     return 0;
 }
index e42b04865b95a9be37a69e0474253831cfd7babf..bda62f2e5c8c5a9a00f5c05d31cd7608fd6056c1 100644 (file)
@@ -6763,7 +6763,8 @@ qemuDomainDefFormatBufInternal(virQEMUDriver *driver,
 
         if (virCPUUpdate(def->os.arch, def->cpu,
                          virQEMUCapsGetHostModel(qCaps, def->virtType,
-                                                 VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
+                                                 VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE),
+                         VIR_CPU_FEATURE_DISABLE) < 0)
             return -1;
     }
 
index da2b024f92d7a7f958ad0fdc236b61d1cb8f47a5..d5c53429667855eac0ec211424d3f909668799be 100644 (file)
@@ -6281,7 +6281,8 @@ qemuProcessUpdateGuestCPU(virDomainDef *def,
 
         if (virCPUUpdate(def->os.arch, def->cpu,
                          virQEMUCapsGetHostModel(qemuCaps, def->virtType,
-                                                 VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
+                                                 VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE),
+                         VIR_CPU_FEATURE_DISABLE) < 0)
             return -1;
 
         cpuModels = virQEMUCapsGetCPUModels(qemuCaps, def->virtType, NULL, NULL);
@@ -8914,7 +8915,8 @@ qemuProcessRefreshCPU(virQEMUDriver *driver,
         virCPUDefCopyModelFilter(cpu, hostmig, false, virQEMUCapsCPUFilterFeatures,
                                  &host->arch);
 
-        if (virCPUUpdate(vm->def->os.arch, vm->def->cpu, cpu) < 0)
+        if (virCPUUpdate(vm->def->os.arch, vm->def->cpu, cpu,
+                         VIR_CPU_FEATURE_DISABLE) < 0)
             return -1;
 
         if (qemuProcessUpdateCPU(vm, VIR_ASYNC_JOB_NONE) < 0)
index 93cd0e12a794f693deefd535d69145513d5a68a5..32bf86997ae4f39123f181f5b29dc2250c95ce21 100644 (file)
@@ -236,7 +236,7 @@ cpuTestGuestCPU(const void *arg)
         goto cleanup;
     }
 
-    if (virCPUUpdate(host->arch, cpu, host) < 0 ||
+    if (virCPUUpdate(host->arch, cpu, host, VIR_CPU_FEATURE_DISABLE) < 0 ||
         virCPUTranslate(host->arch, cpu, data->models) < 0) {
         ret = -1;
         goto cleanup;
@@ -363,7 +363,7 @@ cpuTestUpdate(const void *arg)
     if (!(migHost = virCPUCopyMigratable(data->arch, host)))
         return -1;
 
-    if (virCPUUpdate(host->arch, cpu, migHost) < 0)
+    if (virCPUUpdate(host->arch, cpu, migHost, VIR_CPU_FEATURE_DISABLE) < 0)
         return -1;
 
     result = g_strdup_printf("%s+%s", data->host, data->name);