147 lines
4.7 KiB
Diff
147 lines
4.7 KiB
Diff
|
From 14d3517410021d59cb53fb4c841a5d9922e814d1 Mon Sep 17 00:00:00 2001
|
||
|
From: Jiri Denemark <jdenemar@redhat.com>
|
||
|
Date: Mon, 11 Mar 2024 17:04:48 +0100
|
||
|
Subject: [PATCH] qemu: domain: Drop added features from migratable CPU
|
||
|
|
||
|
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.
|
||
|
|
||
|
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
||
|
Reviewed-by: Tim Wiederhake <twiederh@redhat.com>
|
||
|
Reviewed-by: Peter Krempa <pkrempa@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(-)
|
||
|
|
||
|
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
||
|
index 31a6509166d..bc6cf133d4c 100644
|
||
|
--- a/src/qemu/qemu_domain.c
|
||
|
+++ b/src/qemu/qemu_domain.c
|
||
|
@@ -66,6 +66,7 @@
|
||
|
#include "backup_conf.h"
|
||
|
#include "virutil.h"
|
||
|
#include "virsecureerase.h"
|
||
|
+#include "cpu/cpu_x86.h"
|
||
|
|
||
|
#include <sys/time.h>
|
||
|
#include <fcntl.h>
|
||
|
@@ -6587,10 +6588,36 @@ qemuDomainDefCopy(virQEMUDriver *driver,
|
||
|
}
|
||
|
|
||
|
|
||
|
+typedef struct {
|
||
|
+ const char * const *added;
|
||
|
+ GStrv keep;
|
||
|
+} qemuDomainDropAddedCPUFeaturesData;
|
||
|
+
|
||
|
+
|
||
|
+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;
|
||
|
+
|
||
|
+ return false;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
int
|
||
|
qemuDomainMakeCPUMigratable(virArch arch,
|
||
|
- virCPUDef *cpu)
|
||
|
+ virCPUDef *cpu,
|
||
|
+ virCPUDef *origCPU)
|
||
|
{
|
||
|
+ qemuDomainDropAddedCPUFeaturesData data = { 0 };
|
||
|
+
|
||
|
if (cpu->mode != VIR_CPU_MODE_CUSTOM ||
|
||
|
!cpu->model ||
|
||
|
!ARCH_IS_X86(arch))
|
||
|
@@ -6608,6 +6635,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 = virCPUDefListExplicitFeatures(origCPU);
|
||
|
+ data.keep = keep;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (virCPUDefFilterFeatures(cpu, qemuDomainDropAddedCPUFeatures, &data) < 0)
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -6787,7 +6833,7 @@ qemuDomainDefFormatBufInternal(virQEMUDriver *driver,
|
||
|
}
|
||
|
|
||
|
if (def->cpu &&
|
||
|
- qemuDomainMakeCPUMigratable(def->os.arch, def->cpu) < 0)
|
||
|
+ qemuDomainMakeCPUMigratable(def->os.arch, def->cpu, origCPU) < 0)
|
||
|
return -1;
|
||
|
|
||
|
/* Old libvirt doesn't understand <audio> elements so
|
||
|
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
|
||
|
index 07b03182587..626df6338f1 100644
|
||
|
--- a/src/qemu/qemu_domain.h
|
||
|
+++ b/src/qemu/qemu_domain.h
|
||
|
@@ -1046,7 +1046,8 @@ qemuDomainSupportsCheckpointsBlockjobs(virDomainObj *vm)
|
||
|
|
||
|
int
|
||
|
qemuDomainMakeCPUMigratable(virArch arch,
|
||
|
- virCPUDef *cpu);
|
||
|
+ virCPUDef *cpu,
|
||
|
+ virCPUDef *origCPU);
|
||
|
|
||
|
int
|
||
|
qemuDomainInitializePflashStorageSource(virDomainObj *vm,
|
||
|
diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
|
||
|
index c53d42a0184..90cc079c1a2 100644
|
||
|
--- a/src/qemu/qemu_migration_cookie.c
|
||
|
+++ b/src/qemu/qemu_migration_cookie.c
|
||
|
@@ -540,12 +540,15 @@ static int
|
||
|
qemuMigrationCookieAddCPU(qemuMigrationCookie *mig,
|
||
|
virDomainObj *vm)
|
||
|
{
|
||
|
+ qemuDomainObjPrivate *priv = vm->privateData;
|
||
|
+
|
||
|
if (mig->cpu)
|
||
|
return 0;
|
||
|
|
||
|
mig->cpu = virCPUDefCopy(vm->def->cpu);
|
||
|
|
||
|
- if (qemuDomainMakeCPUMigratable(vm->def->os.arch, mig->cpu) < 0)
|
||
|
+ if (qemuDomainMakeCPUMigratable(vm->def->os.arch, mig->cpu,
|
||
|
+ priv->origCPU) < 0)
|
||
|
return -1;
|
||
|
|
||
|
mig->flags |= QEMU_MIGRATION_COOKIE_CPU;
|