aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6a31dfb8849c..6f758567831a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1326,6 +1326,8 @@ out:
1326void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 1326void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
1327{ 1327{
1328 kvm_x86_ops->vcpu_load(vcpu, cpu); 1328 kvm_x86_ops->vcpu_load(vcpu, cpu);
1329 if (unlikely(per_cpu(cpu_tsc_khz, cpu) == 0))
1330 per_cpu(cpu_tsc_khz, cpu) = cpufreq_quick_get(cpu);
1329 kvm_request_guest_time_update(vcpu); 1331 kvm_request_guest_time_update(vcpu);
1330} 1332}
1331 1333
@@ -3063,9 +3065,6 @@ static void bounce_off(void *info)
3063 /* nothing */ 3065 /* nothing */
3064} 3066}
3065 3067
3066static unsigned int ref_freq;
3067static unsigned long tsc_khz_ref;
3068
3069static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long val, 3068static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
3070 void *data) 3069 void *data)
3071{ 3070{
@@ -3074,14 +3073,11 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va
3074 struct kvm_vcpu *vcpu; 3073 struct kvm_vcpu *vcpu;
3075 int i, send_ipi = 0; 3074 int i, send_ipi = 0;
3076 3075
3077 if (!ref_freq)
3078 ref_freq = freq->old;
3079
3080 if (val == CPUFREQ_PRECHANGE && freq->old > freq->new) 3076 if (val == CPUFREQ_PRECHANGE && freq->old > freq->new)
3081 return 0; 3077 return 0;
3082 if (val == CPUFREQ_POSTCHANGE && freq->old < freq->new) 3078 if (val == CPUFREQ_POSTCHANGE && freq->old < freq->new)
3083 return 0; 3079 return 0;
3084 per_cpu(cpu_tsc_khz, freq->cpu) = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); 3080 per_cpu(cpu_tsc_khz, freq->cpu) = freq->new;
3085 3081
3086 spin_lock(&kvm_lock); 3082 spin_lock(&kvm_lock);
3087 list_for_each_entry(kvm, &vm_list, vm_list) { 3083 list_for_each_entry(kvm, &vm_list, vm_list) {
@@ -3122,12 +3118,14 @@ static void kvm_timer_init(void)
3122{ 3118{
3123 int cpu; 3119 int cpu;
3124 3120
3125 for_each_possible_cpu(cpu)
3126 per_cpu(cpu_tsc_khz, cpu) = tsc_khz;
3127 if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) { 3121 if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
3128 tsc_khz_ref = tsc_khz;
3129 cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, 3122 cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block,
3130 CPUFREQ_TRANSITION_NOTIFIER); 3123 CPUFREQ_TRANSITION_NOTIFIER);
3124 for_each_online_cpu(cpu)
3125 per_cpu(cpu_tsc_khz, cpu) = cpufreq_get(cpu);
3126 } else {
3127 for_each_possible_cpu(cpu)
3128 per_cpu(cpu_tsc_khz, cpu) = tsc_khz;
3131 } 3129 }
3132} 3130}
3133 3131
@@ -4700,6 +4698,14 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)
4700 4698
4701int kvm_arch_hardware_enable(void *garbage) 4699int kvm_arch_hardware_enable(void *garbage)
4702{ 4700{
4701 /*
4702 * Since this may be called from a hotplug notifcation,
4703 * we can't get the CPU frequency directly.
4704 */
4705 if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
4706 int cpu = raw_smp_processor_id();
4707 per_cpu(cpu_tsc_khz, cpu) = 0;
4708 }
4703 return kvm_x86_ops->hardware_enable(garbage); 4709 return kvm_x86_ops->hardware_enable(garbage);
4704} 4710}
4705 4711