diff options
| -rw-r--r-- | arch/x86/kernel/kvmclock.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index feaeb0d3aa4f..59c740fcb9b3 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c | |||
| @@ -29,6 +29,8 @@ | |||
| 29 | #define KVM_SCALE 22 | 29 | #define KVM_SCALE 22 |
| 30 | 30 | ||
| 31 | static int kvmclock = 1; | 31 | static int kvmclock = 1; |
| 32 | static int msr_kvm_system_time = MSR_KVM_SYSTEM_TIME; | ||
| 33 | static int msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK; | ||
| 32 | 34 | ||
| 33 | static int parse_no_kvmclock(char *arg) | 35 | static int parse_no_kvmclock(char *arg) |
| 34 | { | 36 | { |
| @@ -54,7 +56,8 @@ static unsigned long kvm_get_wallclock(void) | |||
| 54 | 56 | ||
| 55 | low = (int)__pa_symbol(&wall_clock); | 57 | low = (int)__pa_symbol(&wall_clock); |
| 56 | high = ((u64)__pa_symbol(&wall_clock) >> 32); | 58 | high = ((u64)__pa_symbol(&wall_clock) >> 32); |
| 57 | native_write_msr(MSR_KVM_WALL_CLOCK, low, high); | 59 | |
| 60 | native_write_msr(msr_kvm_wall_clock, low, high); | ||
| 58 | 61 | ||
| 59 | vcpu_time = &get_cpu_var(hv_clock); | 62 | vcpu_time = &get_cpu_var(hv_clock); |
| 60 | pvclock_read_wallclock(&wall_clock, vcpu_time, &ts); | 63 | pvclock_read_wallclock(&wall_clock, vcpu_time, &ts); |
| @@ -130,7 +133,8 @@ static int kvm_register_clock(char *txt) | |||
| 130 | high = ((u64)__pa(&per_cpu(hv_clock, cpu)) >> 32); | 133 | high = ((u64)__pa(&per_cpu(hv_clock, cpu)) >> 32); |
| 131 | printk(KERN_INFO "kvm-clock: cpu %d, msr %x:%x, %s\n", | 134 | printk(KERN_INFO "kvm-clock: cpu %d, msr %x:%x, %s\n", |
| 132 | cpu, high, low, txt); | 135 | cpu, high, low, txt); |
| 133 | return native_write_msr_safe(MSR_KVM_SYSTEM_TIME, low, high); | 136 | |
| 137 | return native_write_msr_safe(msr_kvm_system_time, low, high); | ||
| 134 | } | 138 | } |
| 135 | 139 | ||
| 136 | #ifdef CONFIG_X86_LOCAL_APIC | 140 | #ifdef CONFIG_X86_LOCAL_APIC |
| @@ -165,14 +169,14 @@ static void __init kvm_smp_prepare_boot_cpu(void) | |||
| 165 | #ifdef CONFIG_KEXEC | 169 | #ifdef CONFIG_KEXEC |
| 166 | static void kvm_crash_shutdown(struct pt_regs *regs) | 170 | static void kvm_crash_shutdown(struct pt_regs *regs) |
| 167 | { | 171 | { |
| 168 | native_write_msr_safe(MSR_KVM_SYSTEM_TIME, 0, 0); | 172 | native_write_msr(msr_kvm_system_time, 0, 0); |
| 169 | native_machine_crash_shutdown(regs); | 173 | native_machine_crash_shutdown(regs); |
| 170 | } | 174 | } |
| 171 | #endif | 175 | #endif |
| 172 | 176 | ||
| 173 | static void kvm_shutdown(void) | 177 | static void kvm_shutdown(void) |
| 174 | { | 178 | { |
| 175 | native_write_msr_safe(MSR_KVM_SYSTEM_TIME, 0, 0); | 179 | native_write_msr(msr_kvm_system_time, 0, 0); |
| 176 | native_machine_shutdown(); | 180 | native_machine_shutdown(); |
| 177 | } | 181 | } |
| 178 | 182 | ||
| @@ -181,27 +185,34 @@ void __init kvmclock_init(void) | |||
| 181 | if (!kvm_para_available()) | 185 | if (!kvm_para_available()) |
| 182 | return; | 186 | return; |
| 183 | 187 | ||
| 184 | if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { | 188 | if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE2)) { |
| 185 | if (kvm_register_clock("boot clock")) | 189 | msr_kvm_system_time = MSR_KVM_SYSTEM_TIME_NEW; |
| 186 | return; | 190 | msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK_NEW; |
| 187 | pv_time_ops.sched_clock = kvm_clock_read; | 191 | } else if (!(kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE))) |
| 188 | x86_platform.calibrate_tsc = kvm_get_tsc_khz; | 192 | return; |
| 189 | x86_platform.get_wallclock = kvm_get_wallclock; | 193 | |
| 190 | x86_platform.set_wallclock = kvm_set_wallclock; | 194 | printk(KERN_INFO "kvm-clock: Using msrs %x and %x", |
| 195 | msr_kvm_system_time, msr_kvm_wall_clock); | ||
| 196 | |||
| 197 | if (kvm_register_clock("boot clock")) | ||
| 198 | return; | ||
| 199 | pv_time_ops.sched_clock = kvm_clock_read; | ||
| 200 | x86_platform.calibrate_tsc = kvm_get_tsc_khz; | ||
| 201 | x86_platform.get_wallclock = kvm_get_wallclock; | ||
| 202 | x86_platform.set_wallclock = kvm_set_wallclock; | ||
| 191 | #ifdef CONFIG_X86_LOCAL_APIC | 203 | #ifdef CONFIG_X86_LOCAL_APIC |
| 192 | x86_cpuinit.setup_percpu_clockev = | 204 | x86_cpuinit.setup_percpu_clockev = |
| 193 | kvm_setup_secondary_clock; | 205 | kvm_setup_secondary_clock; |
| 194 | #endif | 206 | #endif |
| 195 | #ifdef CONFIG_SMP | 207 | #ifdef CONFIG_SMP |
| 196 | smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu; | 208 | smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu; |
| 197 | #endif | 209 | #endif |
| 198 | machine_ops.shutdown = kvm_shutdown; | 210 | machine_ops.shutdown = kvm_shutdown; |
| 199 | #ifdef CONFIG_KEXEC | 211 | #ifdef CONFIG_KEXEC |
| 200 | machine_ops.crash_shutdown = kvm_crash_shutdown; | 212 | machine_ops.crash_shutdown = kvm_crash_shutdown; |
| 201 | #endif | 213 | #endif |
| 202 | kvm_get_preset_lpj(); | 214 | kvm_get_preset_lpj(); |
| 203 | clocksource_register(&kvm_clock); | 215 | clocksource_register(&kvm_clock); |
| 204 | pv_info.paravirt_enabled = 1; | 216 | pv_info.paravirt_enabled = 1; |
| 205 | pv_info.name = "KVM"; | 217 | pv_info.name = "KVM"; |
| 206 | } | ||
| 207 | } | 218 | } |
