This patch implements the propagation of the VM
virtual_tsc_khz into each vcpu data-structure to enable the
tsc-scaling feature.

Signed-off-by: Joerg Roedel <[email protected]>
---
 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 b91547a..ae5ac88 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -888,6 +888,36 @@ static u64 svm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
        return _tsc;
 }
 
+static bool svm_vcpu_init_tsc(struct kvm *kvm, struct vcpu_svm *svm)
+{
+       u64 ratio;
+       u64 khz;
+
+       /* TSC scaling supported? */
+       if (!boot_cpu_has(X86_FEATURE_TSCRATEMSR))
+               return true;
+
+       /* Guest tsc same frequency as host tsc? */
+       if (kvm->arch.virtual_tsc_khz == tsc_khz)
+               return true;
+
+       khz = kvm->arch.virtual_tsc_khz;
+
+       if (khz == 0)
+               return false;
+
+       /* TSC scaling required  - calculate ratio */
+       ratio = (u64)khz << 32;
+       do_div(ratio, tsc_khz);
+       if (ratio == 0 || ratio & TSC_RATIO_RSVD)
+               return false;
+
+       svm->tsc_scale.ratio   = ratio;
+       svm->tsc_scale.enabled = true;
+
+       return true;
+}
+
 static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
@@ -1093,6 +1123,9 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, 
unsigned int id)
        if (err)
                goto free_svm;
 
+       if (!svm_vcpu_init_tsc(kvm, svm))
+               goto uninit;
+
        err = -ENOMEM;
        page = alloc_page(GFP_KERNEL);
        if (!page)
-- 
1.7.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to