[libvirt] [PATCHv3] Add invariant TSC cpu flag

Ján Tomko jtomko at redhat.com
Thu May 15 08:31:05 UTC 2014


Add suport for invariant TSC flag (CPUID 0x80000007, bit 8 of EDX).
If this flag is enabled, the TSC ticks at a constant rate across
all ACPI P-, C- and T-states.

This can be enabled by adding:
<feature name='invtsc'/>
to the <cpu> element.

Migration and saving the domain does not work with this flag.

QEMU support for this is not merged yet:
https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg05024.html

The feature name "invtsc" differs from the name "" used by the linux kernel:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/powerflags.c?id=30321c7b#n18
---
v1: https://www.redhat.com/archives/libvir-list/2014-May/msg00183.html
v2: https://www.redhat.com/archives/libvir-list/2014-May/msg00297.html
  add it as a cpu flag instead of a timer
v3:
    check if the feature wasn't filtered out on domain startup

 src/cpu/cpu_map.xml       |  5 +++++
 src/qemu/qemu_migration.c | 14 ++++++++++++++
 src/qemu/qemu_process.c   | 15 +++++++++++++++
 3 files changed, 34 insertions(+)

diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
index 7d34d40..ffaeb92 100644
--- a/src/cpu/cpu_map.xml
+++ b/src/cpu/cpu_map.xml
@@ -327,6 +327,11 @@
       <cpuid function='0x00000007' ebx='0x00100000'/>
     </feature>
 
+    <!-- Advanced Power Management edx features -->
+    <feature name='invtsc'>
+      <cpuid function='0x80000007' edx='0x00000100'/>
+    </feature>
+
     <!-- models -->
     <model name='486'>
       <feature name='fpu'/>
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index f0df1a6..7504a38 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1513,6 +1513,20 @@ 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;
+
+        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 a83780f..0824afe 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3568,6 +3568,7 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, virDomainObjPtr vm)
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int rc;
     bool ret = false;
+    size_t i;
 
     switch (arch) {
     case VIR_ARCH_I686:
@@ -3590,6 +3591,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:
-- 
1.8.3.2




More information about the libvir-list mailing list