[patch 2/2] kvm: x86: support pvclock userspace time msr

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Save/restore MSR if enabled, name cpuid bit.

Signed-off-by: Marcelo Tosatti <mtosatti@xxxxxxxxxx>

Index: qemu-kvm-vsyscall/target-i386/cpu.h
===================================================================
--- qemu-kvm-vsyscall.orig/target-i386/cpu.h
+++ qemu-kvm-vsyscall/target-i386/cpu.h
@@ -700,6 +700,8 @@ typedef struct CPUX86State {
     uint64_t wall_clock_msr;
     uint64_t async_pf_en_msr;
 
+    uint64_t userspace_time_msr;
+
     uint64_t tsc;
     uint64_t tsc_deadline;
 
Index: qemu-kvm-vsyscall/target-i386/kvm.c
===================================================================
--- qemu-kvm-vsyscall.orig/target-i386/kvm.c
+++ qemu-kvm-vsyscall/target-i386/kvm.c
@@ -65,6 +65,7 @@ static bool has_msr_hsave_pa;
 static bool has_msr_tsc_deadline;
 static bool has_msr_async_pf_en;
 static bool has_msr_misc_enable;
+static bool has_msr_userspace_time;
 static int lm_capable_kernel;
 
 bool kvm_allows_irq0_override(void)
@@ -105,6 +106,7 @@ struct kvm_para_features {
     { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
     { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
     { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
+    { KVM_CAP_USERSPACE_CLOCKSOURCE, KVM_FEATURE_USERSPACE_CLOCKSOURCE },
     { -1, -1 }
 };
 
@@ -455,6 +457,7 @@ int kvm_arch_init_vcpu(CPUX86State *env)
     }
 
     has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
+    has_msr_userspace_time = c->eax & (1 << KVM_FEATURE_USERSPACE_CLOCKSOURCE);
 
     cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
 
@@ -1014,6 +1017,10 @@ static int kvm_put_msrs(CPUX86State *env
         kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME,
                           env->system_time_msr);
         kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
+        if (has_msr_userspace_time) {
+            kvm_msr_entry_set(&msrs[n++], MSR_KVM_USERSPACE_TIME,
+				         env->userspace_time_msr);
+        }
         if (has_msr_async_pf_en) {
             kvm_msr_entry_set(&msrs[n++], MSR_KVM_ASYNC_PF_EN,
                               env->async_pf_en_msr);
@@ -1260,6 +1267,9 @@ static int kvm_get_msrs(CPUX86State *env
     if (has_msr_async_pf_en) {
         msrs[n++].index = MSR_KVM_ASYNC_PF_EN;
     }
+    if (has_msr_userspace_time) {
+        msrs[n++].index = MSR_KVM_USERSPACE_TIME;
+    }
 
     if (env->mcg_cap) {
         msrs[n++].index = MSR_MCG_STATUS;
@@ -1339,6 +1349,9 @@ static int kvm_get_msrs(CPUX86State *env
         case MSR_KVM_ASYNC_PF_EN:
             env->async_pf_en_msr = msrs[i].data;
             break;
+        case MSR_KVM_USERSPACE_TIME:
+            env->userspace_time_msr = msrs[i].data;
+            break;
         }
     }
 
Index: qemu-kvm-vsyscall/target-i386/machine.c
===================================================================
--- qemu-kvm-vsyscall.orig/target-i386/machine.c
+++ qemu-kvm-vsyscall/target-i386/machine.c
@@ -346,6 +346,24 @@ static const VMStateDescription vmstate_
     }
 };
 
+static bool utime_needed(void *opaque)
+{
+    CPUX86State *env = opaque;
+
+    return env->userspace_time_msr != 0;
+}
+
+static const VMStateDescription vmstate_userspace_time_msr = {
+    .name = "cpu/userspace_time_msr",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT64(userspace_time_msr, CPUX86State),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_cpu = {
     .name = "cpu",
     .version_id = CPU_SAVE_VERSION,
@@ -462,6 +480,9 @@ static const VMStateDescription vmstate_
         }, {
             .vmsd = &vmstate_msr_ia32_misc_enable,
             .needed = misc_enable_needed,
+        }, {
+            .vmsd = &vmstate_userspace_time_msr,
+            .needed = utime_needed,
         } , {
             /* empty */
         }
Index: qemu-kvm-vsyscall/target-i386/cpu.c
===================================================================
--- qemu-kvm-vsyscall.orig/target-i386/cpu.c
+++ qemu-kvm-vsyscall/target-i386/cpu.c
@@ -80,7 +80,7 @@ static const char *ext3_feature_name[] =
 };
 
 static const char *kvm_feature_name[] = {
-    "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, "kvm_pv_eoi", NULL,
+    "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, "kvm_pv_eoi", "kvm_userspace_clock",
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux