diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2011-03-25 04:44:49 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-05-11 07:57:05 -0400 |
commit | 4051b18801f5b47bb0369feefdc80e57819d0ddf (patch) | |
tree | ac0b50efc768bbf7bfe42fcd70e9d97bf46185b9 /arch/x86/kvm/svm.c | |
parent | 8f6055cbaf68cbd9ff2692a2cfa691b43629ccd4 (diff) |
KVM: X86: Implement call-back to propagate virtual_tsc_khz
This patch implements a call-back into the architecture code
to allow the propagation of changes to the virtual tsc_khz
of the vcpu.
On SVM it updates the tsc_ratio variable, on VMX it does
nothing.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 830150099958..a39fde4f5fe8 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -885,6 +885,38 @@ static u64 svm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc) | |||
885 | return _tsc; | 885 | return _tsc; |
886 | } | 886 | } |
887 | 887 | ||
888 | static void svm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz) | ||
889 | { | ||
890 | struct vcpu_svm *svm = to_svm(vcpu); | ||
891 | u64 ratio; | ||
892 | u64 khz; | ||
893 | |||
894 | /* TSC scaling supported? */ | ||
895 | if (!boot_cpu_has(X86_FEATURE_TSCRATEMSR)) | ||
896 | return; | ||
897 | |||
898 | /* TSC-Scaling disabled or guest TSC same frequency as host TSC? */ | ||
899 | if (user_tsc_khz == 0) { | ||
900 | vcpu->arch.virtual_tsc_khz = 0; | ||
901 | svm->tsc_ratio = TSC_RATIO_DEFAULT; | ||
902 | return; | ||
903 | } | ||
904 | |||
905 | khz = user_tsc_khz; | ||
906 | |||
907 | /* TSC scaling required - calculate ratio */ | ||
908 | ratio = khz << 32; | ||
909 | do_div(ratio, tsc_khz); | ||
910 | |||
911 | if (ratio == 0 || ratio & TSC_RATIO_RSVD) { | ||
912 | WARN_ONCE(1, "Invalid TSC ratio - virtual-tsc-khz=%u\n", | ||
913 | user_tsc_khz); | ||
914 | return; | ||
915 | } | ||
916 | vcpu->arch.virtual_tsc_khz = user_tsc_khz; | ||
917 | svm->tsc_ratio = ratio; | ||
918 | } | ||
919 | |||
888 | static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset) | 920 | static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset) |
889 | { | 921 | { |
890 | struct vcpu_svm *svm = to_svm(vcpu); | 922 | struct vcpu_svm *svm = to_svm(vcpu); |
@@ -4159,6 +4191,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
4159 | 4191 | ||
4160 | .has_wbinvd_exit = svm_has_wbinvd_exit, | 4192 | .has_wbinvd_exit = svm_has_wbinvd_exit, |
4161 | 4193 | ||
4194 | .set_tsc_khz = svm_set_tsc_khz, | ||
4162 | .write_tsc_offset = svm_write_tsc_offset, | 4195 | .write_tsc_offset = svm_write_tsc_offset, |
4163 | .adjust_tsc_offset = svm_adjust_tsc_offset, | 4196 | .adjust_tsc_offset = svm_adjust_tsc_offset, |
4164 | 4197 | ||