Re: [PATCH 01/22] cpu: x86: Add support for adding features to existing CPU models

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Mar 12, 2024 at 18:06:41 +0100, Jiri Denemark wrote:
> This is not a good idea in general, but we can (and have to) do it in
> specific cases when a feature has always been part of a CPU model in
> hypervisor's definition, but we ignored it and did not include the
> feature in our definition.
> 
> Blindly adding the features to the CPU map and not adding them to
> existing CPU models breaks migration between old and new libvirt in both
> directions. New libvirt would complain the features got unexpectedly
> enabled (as they were not mentioned in the incoming domain XML) even
> though they were also enabled on the source and the old libvirt just
> didn't know about them. On the other hand, old libvirt would refuse to
> accept incoming migration of a domain started by new libvirt because the
> domain XML would contain CPU features unknown to the old libvirt.
> 
> This is exactly what happened when several vmx-* features were added a
> few releases back. Migration between libvirt releases before and after
> the addition is now broken.
> 
> This patch adds support for added these features to existing CPU models
> by marking them with added='yes'. The features will not be considered
> part of the CPU model and will be described explicitly via additional
> <feature/> elements, but the compatibility check will not complain if
> they are enabled by the hypervisor even though they were not explicitly
> mentioned in the CPU definition and incoming migration from old libvirt
> will succeed.
> 
> To fix outgoing migration to old libvirt, we also need to drop all those
> features from domain XML unless they were explicitly requested by the
> user. This will be handled by a later patch.
> 
> Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx>
> ---
>  src/cpu/cpu_x86.c        | 69 ++++++++++++++++++++++++++++++++++++++--
>  src/cpu/cpu_x86.h        |  3 ++
>  src/libvirt_private.syms |  1 +
>  3 files changed, 70 insertions(+), 3 deletions(-)
> @@ -3030,11 +3057,13 @@ virCPUx86UpdateLive(virCPUDef *cpu,

[...]

Even in the context of virCPUx86UpdateLive this conidtion is getting a
bit overcrowded with the extra check. Please add a comment at least
stating that this specifically ignores the features added later.

>          if (expected == VIR_CPU_FEATURE_DISABLE &&
>              x86DataIsSubset(&enabled, &feature->data)) {
>              VIR_DEBUG("Feature '%s' enabled by the hypervisor", feature->name);
> -            if (cpu->check == VIR_CPU_CHECK_FULL)
> +            if (cpu->check == VIR_CPU_CHECK_FULL &&
> +                !g_strv_contains((const char **) model->addedFeatures, feature->name)) {
>                  virBufferAsprintf(&bufAdded, "%s,", feature->name);
> -            else if (virCPUDefUpdateFeature(cpu, feature->name,
> -                                            VIR_CPU_FEATURE_REQUIRE) < 0)
> +            } else if (virCPUDefUpdateFeature(cpu, feature->name,
> +                                              VIR_CPU_FEATURE_REQUIRE) < 0) {
>                  return -1;
> +            }
>          }
>  
>          if (x86DataIsSubset(&disabled, &feature->data) ||
> @@ -3499,6 +3528,40 @@ virCPUx86FeatureFilterDropMSR(const char *name,
>  }
>  
>  
> +/**
> + * virCPUx86GetAddedFeatures:
> + * @modelName: CPU model
> + * @features: where to store a pointer to the list of added features
> + *
> + * Gets a list of features added to a specified CPU model after its original
> + * version was already released. The @features will be set to NULL if the list
> + * is empty or it will point to internal structures and thus it must not be
> + * freed or modified by the caller. The pointer is valid for the whole lifetime
> + * of the process.
> + *
> + * Returns 0 on success, -1 otherwise.
> + */
> +int
> +virCPUx86GetAddedFeatures(const char *modelName,
> +                          const char * const **features)
> +{
> +    virCPUx86Map *map;
> +    virCPUx86Model *model;
> +
> +    if (!(map = virCPUx86GetMap()))
> +        return -1;
> +
> +    if (!(model = x86ModelFind(map, modelName))) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("unknown CPU model %1$s"), modelName);

While I didn't yet check where this is used using INTERNAL_ERROR for a
CPU model which most likely came from the user is weird. Consider using
VIR_ERR_INVALID_ARG.

Reviewed-by: Peter Krempa <pkrempa@xxxxxxxxxx>
_______________________________________________
Devel mailing list -- devel@xxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux