diff mbox

[07/16] KVM-GST: Implement wallclock over KVM - KVM Virtual Memory

Message ID 1295892397-11354-8-git-send-email-glommer@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Glauber Costa Jan. 24, 2011, 6:06 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index f98d3ea..b8809f0 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -31,6 +31,7 @@ 
 static int kvmclock = 1;
 static int msr_kvm_system_time = MSR_KVM_SYSTEM_TIME;
 static int msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK;
+static int kvm_memory_area_available = 0;
 
 static int parse_no_kvmclock(char *arg)
 {
@@ -43,6 +44,27 @@  early_param("no-kvmclock", parse_no_kvmclock);
 static DEFINE_PER_CPU_SHARED_ALIGNED(struct pvclock_vcpu_time_info, hv_clock);
 static struct pvclock_wall_clock wall_clock;
 
+static int kvm_register_mem_area(u64 base, int type, int size)
+{
+	int low, high;
+
+	struct kvm_memory_area mem;
+
+	if (!kvm_memory_area_available)
+		return 1;
+
+	mem.base = base;
+	mem.size = size;
+	mem.type = type;
+
+	low = (int)__pa_symbol(&mem);
+	high = ((u64)__pa_symbol(&mem) >> 32);
+
+	native_write_msr(MSR_KVM_REGISTER_MEM_AREA, low, high);
+	return mem.result;
+}
+
+
 /*
  * The wallclock is the time of day when we booted. Since then, some time may
  * have elapsed since the hypervisor wrote the data. So we try to account for
@@ -53,11 +75,17 @@  static unsigned long kvm_get_wallclock(void)
 	struct pvclock_vcpu_time_info *vcpu_time;
 	struct timespec ts;
 	int low, high;
-
-	low = (int)__pa_symbol(&wall_clock);
-	high = ((u64)__pa_symbol(&wall_clock) >> 32);
-
-	native_write_msr(msr_kvm_wall_clock, low, high);
+	u64 addr = __pa_symbol(&wall_clock);
+	int ret;
+	
+	ret = kvm_register_mem_area(addr, KVM_AREA_WALLCLOCK,
+				    sizeof(wall_clock));
+	if (ret != 0) {
+		low = (int)addr;
+		high = ((u64)addr >> 32);
+
+		native_write_msr(msr_kvm_wall_clock, low, high);
+	}
 
 	vcpu_time = &get_cpu_var(hv_clock);
 	pvclock_read_wallclock(&wall_clock, vcpu_time, &ts);
@@ -179,6 +207,9 @@  void __init kvmclock_init(void)
 	if (!kvm_para_available())
 		return;
 
+	if (kvm_para_has_feature(KVM_FEATURE_MEMORY_AREA))
+		kvm_memory_area_available = 1;
+
 	if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE2)) {
 		msr_kvm_system_time = MSR_KVM_SYSTEM_TIME_NEW;
 		msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK_NEW;