diff options
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 26 |
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: | |||
1326 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 1326 | void 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 | ||
3066 | static unsigned int ref_freq; | ||
3067 | static unsigned long tsc_khz_ref; | ||
3068 | |||
3069 | static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | 3068 | static 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 | ||
4701 | int kvm_arch_hardware_enable(void *garbage) | 4699 | int 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 | ||