#include "backup_conf.h"
#include "virutil.h"
#include "virsecureerase.h"
+#include "cpu/cpu_x86.h"
#include <sys/time.h>
#include <fcntl.h>
}
+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))
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;
}
}
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
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;