On Tue, Mar 12, 2024 at 18:06:44 +0100, Jiri Denemark wrote:
Features marked with added='yes' in CPU model definitions
have to be
removed before migration, otherwise older libvirt would complain about
unknown CPU features. We only do this for features that were enabled for
a given CPU model even with older libvirt, which just ignored the
features. And only for features we added ourselves when updating CPU
definition during domain startup, that is we do not remove features
which were explicitly mentioned by a user.
That said, this is not the safest thing we could do, but it's
effectively the same thing we did before the affected features were
added: we ignored them completely on both sides of migration.
IIUC if the feature is part of the model it'll never be expanded into
the definition and thus will never be checked during migration, right?
Thus effectively the full checking could be done only for migration
between new versions if the destination somehow signals that it's new
enough for the source to not drop the features.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_domain.c | 50 ++++++++++++++++++++++++++++++--
src/qemu/qemu_domain.h | 3 +-
src/qemu/qemu_migration_cookie.c | 5 +++-
3 files changed, 54 insertions(+), 4 deletions(-)
[...]
@@ -6643,10 +6644,36 @@ qemuDomainDefCopy(virQEMUDriver *driver,
[...]
+static bool
+qemuDomainDropAddedCPUFeatures(const char *name,
+ virCPUFeaturePolicy policy G_GNUC_UNUSED,
+ void *opaque)
+{
+ qemuDomainDropAddedCPUFeaturesData *data = opaque;
+
+ if (!g_strv_contains(data->added, name))
+ return true;
+
+ if (data->keep && g_strv_contains((const char **) data->keep, name))
+ return true;
[...]
@@ -6664,6 +6691,25 @@ qemuDomainMakeCPUMigratable(virArch arch,
return -1;
}
+ if (virCPUx86GetAddedFeatures(cpu->model, &data.added) < 0)
+ return -1;
+
+ /* Drop features marked as added in a cpu model, but only
+ * when they are not mentioned in origCPU, i.e., when they were not
+ * explicitly mentioned by the user.
+ */
+ if (data.added) {
+ g_auto(GStrv) keep = NULL;
+
+ if (origCPU) {
+ keep = virCPUDefListFeatures(origCPU);
+ data.keep = keep;
+ }
+
+ if (virCPUDefFilterFeatures(cpu, qemuDomainDropAddedCPUFeatures, &data) <
0)
+ return -1;
Mmm, O(n^2) ...
+ }
Reviewed-by: Peter Krempa <pkrempa(a)redhat.com>