diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml index d704e59b73..12987a0d87 100644 --- a/src/cpu/cpu_map.xml +++ b/src/cpu/cpu_map.xml @@ -327,6 +327,11 @@ + + + + + diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 7684aec1b2..bbfb09ac34 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1513,6 +1513,21 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, virDomainObjPtr vm, return false; } + for (i = 0; i < def->cpu->nfeatures; i++) { + virCPUFeatureDefPtr feature = &def->cpu->features[i]; + + if (feature->policy != VIR_CPU_FEATURE_REQUIRE) + continue; + + /* QEMU blocks migration and save with invariant TSC enabled */ + if (STREQ(feature->name, "invtsc")) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("domain has CPU feature: %s"), + feature->name); + return false; + } + } + return true; } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 5b598bebe6..a39cc0a0aa 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3612,6 +3612,7 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, virDomainObjPtr vm) qemuDomainObjPrivatePtr priv = vm->privateData; int rc; bool ret = false; + size_t i; switch (arch) { case VIR_ARCH_I686: @@ -3634,6 +3635,20 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, virDomainObjPtr vm) goto cleanup; } } + + for (i = 0; i < def->cpu->nfeatures; i++) { + virCPUFeatureDefPtr feature = &def->cpu->features[i]; + + if (feature->policy != VIR_CPU_FEATURE_REQUIRE) + continue; + + if (STREQ(feature->name, "invtsc") && + !cpuHasFeature(guestcpu, feature->name)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("host doesn't support invariant TSC")); + goto cleanup; + } + } break; default: