]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/kvmclock.c
kvm_setup_secondary_clock() is cpuinit
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / kvmclock.c
index d02def06ca91540dd174f219eee8fe6eee6f095c..e169ae9b6a62e9f3d2b4d914de87ce4157c26569 100644 (file)
@@ -78,6 +78,34 @@ static cycle_t kvm_clock_read(void)
        return ret;
 }
 
+/*
+ * If we don't do that, there is the possibility that the guest
+ * will calibrate under heavy load - thus, getting a lower lpj -
+ * and execute the delays themselves without load. This is wrong,
+ * because no delay loop can finish beforehand.
+ * Any heuristics is subject to fail, because ultimately, a large
+ * poll of guests can be running and trouble each other. So we preset
+ * lpj here
+ */
+static unsigned long kvm_get_tsc_khz(void)
+{
+       return preset_lpj;
+}
+
+static void kvm_get_preset_lpj(void)
+{
+       struct pvclock_vcpu_time_info *src;
+       unsigned long khz;
+       u64 lpj;
+
+       src = &per_cpu(hv_clock, 0);
+       khz = pvclock_tsc_khz(src);
+
+       lpj = ((u64)khz * 1000);
+       do_div(lpj, HZ);
+       preset_lpj = lpj;
+}
+
 static struct clocksource kvm_clock = {
        .name = "kvm-clock",
        .read = kvm_clock_read,
@@ -100,7 +128,7 @@ static int kvm_register_clock(char *txt)
 }
 
 #ifdef CONFIG_X86_LOCAL_APIC
-static void kvm_setup_secondary_clock(void)
+static void __cpuinit kvm_setup_secondary_clock(void)
 {
        /*
         * Now that the first cpu already had this clocksource initialized,
@@ -153,6 +181,7 @@ void __init kvmclock_init(void)
                pv_time_ops.get_wallclock = kvm_get_wallclock;
                pv_time_ops.set_wallclock = kvm_set_wallclock;
                pv_time_ops.sched_clock = kvm_clock_read;
+               pv_time_ops.get_tsc_khz = kvm_get_tsc_khz;
 #ifdef CONFIG_X86_LOCAL_APIC
                pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock;
 #endif
@@ -163,6 +192,7 @@ void __init kvmclock_init(void)
 #ifdef CONFIG_KEXEC
                machine_ops.crash_shutdown  = kvm_crash_shutdown;
 #endif
+               kvm_get_preset_lpj();
                clocksource_register(&kvm_clock);
        }
 }