From patchwork Fri Mar 25 08:44:46 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joerg Roedel X-Patchwork-Id: 661171 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2P8j9ke025629 for ; Fri, 25 Mar 2011 08:45:09 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755173Ab1CYIpE (ORCPT ); Fri, 25 Mar 2011 04:45:04 -0400 Received: from tx2ehsobe004.messaging.microsoft.com ([65.55.88.14]:45373 "EHLO TX2EHSOBE008.bigfish.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750926Ab1CYIpA (ORCPT ); Fri, 25 Mar 2011 04:45:00 -0400 Received: from mail136-tx2-R.bigfish.com (10.9.14.240) by TX2EHSOBE008.bigfish.com (10.9.40.28) with Microsoft SMTP Server id 14.1.225.8; Fri, 25 Mar 2011 08:45:00 +0000 Received: from mail136-tx2 (localhost.localdomain [127.0.0.1]) by mail136-tx2-R.bigfish.com (Postfix) with ESMTP id BC266968124; Fri, 25 Mar 2011 08:44:59 +0000 (UTC) X-SpamScore: -2 X-BigFish: VPS-2(zzbb2cKzz1202hzz8275bhz32i668h61h) X-Spam-TCS-SCL: 0:0 X-Forefront-Antispam-Report: KIP:(null); UIP:(null); IPVD:NLI; H:ausb3twp01.amd.com; RD:none; EFVD:NLI Received: from mail136-tx2 (localhost.localdomain [127.0.0.1]) by mail136-tx2 (MessageSwitch) id 1301042699357939_698; Fri, 25 Mar 2011 08:44:59 +0000 (UTC) Received: from TX2EHSMHS025.bigfish.com (unknown [10.9.14.248]) by mail136-tx2.bigfish.com (Postfix) with ESMTP id 52EBAB28053; Fri, 25 Mar 2011 08:44:59 +0000 (UTC) Received: from ausb3twp01.amd.com (163.181.249.108) by TX2EHSMHS025.bigfish.com (10.9.99.125) with Microsoft SMTP Server id 14.1.225.8; Fri, 25 Mar 2011 08:44:59 +0000 X-WSS-ID: 0LILUYU-01-KYJ-02 X-M-MSG: Received: from sausexedgep01.amd.com (sausexedgep01-ext.amd.com [163.181.249.72]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by ausb3twp01.amd.com (Tumbleweed MailGate 3.7.2) with ESMTP id 2152210287EF; Fri, 25 Mar 2011 03:44:53 -0500 (CDT) Received: from sausexhtp01.amd.com (163.181.3.165) by sausexedgep01.amd.com (163.181.36.54) with Microsoft SMTP Server (TLS) id 8.3.106.1; Fri, 25 Mar 2011 03:52:21 -0500 Received: from storexhtp02.amd.com (172.24.4.4) by sausexhtp01.amd.com (163.181.3.165) with Microsoft SMTP Server (TLS) id 8.3.83.0; Fri, 25 Mar 2011 03:44:56 -0500 Received: from gwo.osrc.amd.com (165.204.16.204) by storexhtp02.amd.com (172.24.4.4) with Microsoft SMTP Server id 8.3.83.0; Fri, 25 Mar 2011 04:44:55 -0400 Received: from lemmy.osrc.amd.com (lemmy.osrc.amd.com [165.204.15.93]) by gwo.osrc.amd.com (Postfix) with ESMTP id 43FA149C58F; Fri, 25 Mar 2011 08:44:54 +0000 (GMT) Received: by lemmy.osrc.amd.com (Postfix, from userid 1000) id 28EF4101BA4; Fri, 25 Mar 2011 09:44:54 +0100 (CET) From: Joerg Roedel To: Avi Kivity , Marcelo Tosatti CC: Zachary Amsden , , Joerg Roedel Subject: [PATCH 1/6] KVM: SVM: Implement infrastructure for TSC_RATE_MSR Date: Fri, 25 Mar 2011 09:44:46 +0100 Message-ID: <1301042691-22929-2-git-send-email-joerg.roedel@amd.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1301042691-22929-1-git-send-email-joerg.roedel@amd.com> References: <1301042691-22929-1-git-send-email-joerg.roedel@amd.com> MIME-Version: 1.0 X-OriginatorOrg: amd.com Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 25 Mar 2011 08:45:10 +0000 (UTC) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index fd5a1f3..a7b3e40 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -114,6 +114,7 @@ complete list. */ #define MSR_AMD64_PATCH_LEVEL 0x0000008b +#define MSR_AMD64_TSC_RATIO 0xc0000104 #define MSR_AMD64_NB_CFG 0xc001001f #define MSR_AMD64_PATCH_LOADER 0xc0010020 #define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140 diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 2a19322..2ce734c 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -63,6 +63,8 @@ MODULE_LICENSE("GPL"); #define DEBUGCTL_RESERVED_BITS (~(0x3fULL)) +#define TSC_RATIO_RSVD 0xffffff0000000000ULL + static bool erratum_383_found __read_mostly; static const u32 host_save_user_msrs[] = { @@ -144,8 +146,13 @@ struct vcpu_svm { unsigned int3_injected; unsigned long int3_rip; u32 apf_reason; + + u64 tsc_ratio; }; +static DEFINE_PER_CPU(u64, current_tsc_ratio); +#define TSC_RATIO_DEFAULT 0x0100000000ULL + #define MSR_INVALID 0xffffffffU static struct svm_direct_access_msrs { @@ -569,6 +576,10 @@ static int has_svm(void) static void svm_hardware_disable(void *garbage) { + /* Make sure we clean up behind us */ + if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) + wrmsrl(MSR_AMD64_TSC_RATIO, TSC_RATIO_DEFAULT); + cpu_svm_disable(); } @@ -610,6 +621,11 @@ static int svm_hardware_enable(void *garbage) wrmsrl(MSR_VM_HSAVE_PA, page_to_pfn(sd->save_area) << PAGE_SHIFT); + if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) { + wrmsrl(MSR_AMD64_TSC_RATIO, TSC_RATIO_DEFAULT); + __get_cpu_var(current_tsc_ratio) = TSC_RATIO_DEFAULT; + } + svm_init_erratum_383(); return 0; @@ -854,6 +870,32 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type) seg->base = 0; } +static u64 __scale_tsc(u64 ratio, u64 tsc) +{ + u64 mult, frac, _tsc; + + mult = ratio >> 32; + frac = ratio & ((1ULL << 32) - 1); + + _tsc = tsc; + _tsc *= mult; + _tsc += (tsc >> 32) * frac; + _tsc += ((tsc & ((1ULL << 32) - 1)) * frac) >> 32; + + return _tsc; +} + +static u64 svm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc) +{ + struct vcpu_svm *svm = to_svm(vcpu); + u64 _tsc = tsc; + + if (svm->tsc_ratio != TSC_RATIO_DEFAULT) + _tsc = __scale_tsc(svm->tsc_ratio, tsc); + + return _tsc; +} + static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset) { struct vcpu_svm *svm = to_svm(vcpu); @@ -1048,6 +1090,8 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) goto out; } + svm->tsc_ratio = TSC_RATIO_DEFAULT; + err = kvm_vcpu_init(&svm->vcpu, kvm, id); if (err) goto free_svm; @@ -1141,6 +1185,12 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); + + if (static_cpu_has(X86_FEATURE_TSCRATEMSR) && + svm->tsc_ratio != __get_cpu_var(current_tsc_ratio)) { + __get_cpu_var(current_tsc_ratio) = svm->tsc_ratio; + wrmsrl(MSR_AMD64_TSC_RATIO, svm->tsc_ratio); + } } static void svm_vcpu_put(struct kvm_vcpu *vcpu) @@ -2813,7 +2863,9 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) case MSR_IA32_TSC: { struct vmcb *vmcb = get_host_vmcb(svm); - *data = vmcb->control.tsc_offset + native_read_tsc(); + *data = vmcb->control.tsc_offset + + svm_scale_tsc(vcpu, native_read_tsc()); + break; } case MSR_STAR: