diff mbox

[4/6] KVM: SVM: Propagate requested TSC frequency on vcpu init

Message ID 1300952424-32014-5-git-send-email-joerg.roedel@amd.com (mailing list archive)
State New, archived
Headers show

Commit Message

Joerg Roedel March 24, 2011, 7:40 a.m. UTC
None
diff mbox

Patch

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 40ade85..d747db8 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)