linux/arch/x86/kernel/kvmclock.c
<<
>>
Prefs
   1/*  KVM paravirtual clock driver. A clocksource implementation
   2    Copyright (C) 2008 Glauber de Oliveira Costa, Red Hat Inc.
   3
   4    This program is free software; you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 2 of the License, or
   7    (at your option) any later version.
   8
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13
  14    You should have received a copy of the GNU General Public License
  15    along with this program; if not, write to the Free Software
  16    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17*/
  18
  19#include <linux/clocksource.h>
  20#include <linux/kvm_para.h>
  21#include <asm/pvclock.h>
  22#include <asm/msr.h>
  23#include <asm/apic.h>
  24#include <linux/percpu.h>
  25
  26#include <asm/x86_init.h>
  27#include <asm/reboot.h>
  28
  29#define KVM_SCALE 22
  30
  31static int kvmclock = 1;
  32
  33static int parse_no_kvmclock(char *arg)
  34{
  35        kvmclock = 0;
  36        return 0;
  37}
  38early_param("no-kvmclock", parse_no_kvmclock);
  39
  40/* The hypervisor will put information about time periodically here */
  41static DEFINE_PER_CPU_SHARED_ALIGNED(struct pvclock_vcpu_time_info, hv_clock);
  42static struct pvclock_wall_clock wall_clock;
  43
  44/*
  45 * The wallclock is the time of day when we booted. Since then, some time may
  46 * have elapsed since the hypervisor wrote the data. So we try to account for
  47 * that with system time
  48 */
  49static unsigned long kvm_get_wallclock(void)
  50{
  51        struct pvclock_vcpu_time_info *vcpu_time;
  52        struct timespec ts;
  53        int low, high;
  54
  55        low = (int)__pa_symbol(&wall_clock);
  56        high = ((u64)__pa_symbol(&wall_clock) >> 32);
  57        native_write_msr(MSR_KVM_WALL_CLOCK, low, high);
  58
  59        vcpu_time = &get_cpu_var(hv_clock);
  60        pvclock_read_wallclock(&wall_clock, vcpu_time, &ts);
  61        put_cpu_var(hv_clock);
  62
  63        return ts.tv_sec;
  64}
  65
  66static int kvm_set_wallclock(unsigned long now)
  67{
  68        return -1;
  69}
  70
  71static cycle_t kvm_clock_read(void)
  72{
  73        struct pvclock_vcpu_time_info *src;
  74        cycle_t ret;
  75
  76        src = &get_cpu_var(hv_clock);
  77        ret = pvclock_clocksource_read(src);
  78        put_cpu_var(hv_clock);
  79        return ret;
  80}
  81
  82static cycle_t kvm_clock_get_cycles(struct clocksource *cs)
  83{
  84        return kvm_clock_read();
  85}
  86
  87/*
  88 * If we don't do that, there is the possibility that the guest
  89 * will calibrate under heavy load - thus, getting a lower lpj -
  90 * and execute the delays themselves without load. This is wrong,
  91 * because no delay loop can finish beforehand.
  92 * Any heuristics is subject to fail, because ultimately, a large
  93 * poll of guests can be running and trouble each other. So we preset
  94 * lpj here
  95 */
  96static unsigned long kvm_get_tsc_khz(void)
  97{
  98        struct pvclock_vcpu_time_info *src;
  99        src = &per_cpu(hv_clock, 0);
 100        return pvclock_tsc_khz(src);
 101}
 102
 103static void kvm_get_preset_lpj(void)
 104{
 105        unsigned long khz;
 106        u64 lpj;
 107
 108        khz = kvm_get_tsc_khz();
 109
 110        lpj = ((u64)khz * 1000);
 111        do_div(lpj, HZ);
 112        preset_lpj = lpj;
 113}
 114
 115static struct clocksource kvm_clock = {
 116        .name = "kvm-clock",
 117        .read = kvm_clock_get_cycles,
 118        .rating = 400,
 119        .mask = CLOCKSOURCE_MASK(64),
 120        .mult = 1 << KVM_SCALE,
 121        .shift = KVM_SCALE,
 122        .flags = CLOCK_SOURCE_IS_CONTINUOUS,
 123};
 124
 125static int kvm_register_clock(char *txt)
 126{
 127        int cpu = smp_processor_id();
 128        int low, high;
 129        low = (int)__pa(&per_cpu(hv_clock, cpu)) | 1;
 130        high = ((u64)__pa(&per_cpu(hv_clock, cpu)) >> 32);
 131        printk(KERN_INFO "kvm-clock: cpu %d, msr %x:%x, %s\n",
 132               cpu, high, low, txt);
 133        return native_write_msr_safe(MSR_KVM_SYSTEM_TIME, low, high);
 134}
 135
 136#ifdef CONFIG_X86_LOCAL_APIC
 137static void __cpuinit kvm_setup_secondary_clock(void)
 138{
 139        /*
 140         * Now that the first cpu already had this clocksource initialized,
 141         * we shouldn't fail.
 142         */
 143        WARN_ON(kvm_register_clock("secondary cpu clock"));
 144        /* ok, done with our trickery, call native */
 145        setup_secondary_APIC_clock();
 146}
 147#endif
 148
 149#ifdef CONFIG_SMP
 150static void __init kvm_smp_prepare_boot_cpu(void)
 151{
 152        WARN_ON(kvm_register_clock("primary cpu clock"));
 153        native_smp_prepare_boot_cpu();
 154}
 155#endif
 156
 157/*
 158 * After the clock is registered, the host will keep writing to the
 159 * registered memory location. If the guest happens to shutdown, this memory
 160 * won't be valid. In cases like kexec, in which you install a new kernel, this
 161 * means a random memory location will be kept being written. So before any
 162 * kind of shutdown from our side, we unregister the clock by writting anything
 163 * that does not have the 'enable' bit set in the msr
 164 */
 165#ifdef CONFIG_KEXEC
 166static void kvm_crash_shutdown(struct pt_regs *regs)
 167{
 168        native_write_msr_safe(MSR_KVM_SYSTEM_TIME, 0, 0);
 169        native_machine_crash_shutdown(regs);
 170}
 171#endif
 172
 173static void kvm_shutdown(void)
 174{
 175        native_write_msr_safe(MSR_KVM_SYSTEM_TIME, 0, 0);
 176        native_machine_shutdown();
 177}
 178
 179void __init kvmclock_init(void)
 180{
 181        if (!kvm_para_available())
 182                return;
 183
 184        if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) {
 185                if (kvm_register_clock("boot clock"))
 186                        return;
 187                pv_time_ops.sched_clock = kvm_clock_read;
 188                x86_platform.calibrate_tsc = kvm_get_tsc_khz;
 189                x86_platform.get_wallclock = kvm_get_wallclock;
 190                x86_platform.set_wallclock = kvm_set_wallclock;
 191#ifdef CONFIG_X86_LOCAL_APIC
 192                x86_cpuinit.setup_percpu_clockev =
 193                        kvm_setup_secondary_clock;
 194#endif
 195#ifdef CONFIG_SMP
 196                smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu;
 197#endif
 198                machine_ops.shutdown  = kvm_shutdown;
 199#ifdef CONFIG_KEXEC
 200                machine_ops.crash_shutdown  = kvm_crash_shutdown;
 201#endif
 202                kvm_get_preset_lpj();
 203                clocksource_register(&kvm_clock);
 204                pv_info.paravirt_enabled = 1;
 205                pv_info.name = "KVM";
 206        }
 207}
 208