From patchwork Wed May 29 21:40:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bandan Das X-Patchwork-Id: 2632861 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 6402A40077 for ; Wed, 29 May 2013 21:42:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935218Ab3E2VmE (ORCPT ); Wed, 29 May 2013 17:42:04 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59386 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935180Ab3E2VmC (ORCPT ); Wed, 29 May 2013 17:42:02 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r4TLg2ZE017456 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 29 May 2013 17:42:02 -0400 Received: from aqua.bos.redhat.com (dhcp-185-29.bos.redhat.com [10.16.185.29]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r4TLfDhe005289; Wed, 29 May 2013 17:42:01 -0400 From: Bandan Das To: kvm@vger.kernel.org Cc: Gleb Natapov , Paolo Bonzini , Marcelo Tosatti , Bandan Das Subject: [PATCH 2/2] kvm: x86: emulate MSR_PLATFORM_INFO Date: Wed, 29 May 2013 17:40:13 -0400 Message-Id: <1369863613-14781-3-git-send-email-bsd@redhat.com> In-Reply-To: <1369863613-14781-1-git-send-email-bsd@redhat.com> References: <1369863613-14781-1-git-send-email-bsd@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org To emulate MSR_PLATFORM_INFO, we divide guest virtual_tsc_khz by the base clock - which is guest CPU model dependent. The relevant bits in this emulated MSR are : Max Non-Turbo Ratio (15:8) - virtual_tsc_khz/bclk Max Effi Ratio (47:40) - virtual_tsc_khz/bclk Prog Ratio Limit for Trubo (28) - 0 Prog TDC-TDP Limit for Turbo (29) - 0 Signed-off-by: Bandan Das --- arch/x86/include/uapi/asm/msr-index.h | 2 ++ arch/x86/kvm/cpuid.c | 18 +++++++++++++ arch/x86/kvm/cpuid.h | 16 ++++++++++++ arch/x86/kvm/x86.c | 48 +++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+) diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index 2af848d..b0268d5 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h @@ -331,6 +331,8 @@ #define MSR_IA32_MISC_ENABLE 0x000001a0 +#define MSR_IA32_PLATFORM_INFO 0x000000ce + #define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 #define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0 diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index a20ecb5..04cb30c 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -608,6 +608,24 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, } EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry); +u8 kvm_guest_vcpu_model(struct kvm_vcpu *vcpu) +{ + struct kvm_cpuid_entry2 *best; + u8 cpuid_model, cpuid_extmodel; + + if (!vendor_intel(vcpu)) + return CPUID_MODEL_UNKNOWN; + + best = kvm_find_cpuid_entry(vcpu, 1, 0); + + cpuid_model = (best->eax >> 4) & 0xf; + cpuid_extmodel = (best->eax >> 16) & 0xf; + + cpuid_model += (cpuid_extmodel << 4); + + return cpuid_model; +} + int cpuid_maxphyaddr(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index b7fd079..4fad70d 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -3,6 +3,21 @@ #include "x86.h" +#define MODEL_NEHALEM_CLARKSFIELD 0x1e /* Core i7 and Ex BCLK: 133Mhz */ +#define MODEL_NEHALEM_BLOOMFIELD 0x1a /* Core i7 Xeon 3000 BCLK: 133 Mhz */ +#define MODEL_NEHALEM_EX 0x2e /* Core i7 and i5 Nehalem BCLK: 133 Mhz */ +#define MODEL_WESTMERE_ARRANDALE 0x25 /* Celeron/Pentium/Core i3/i5/i7 BCLK: 133 Mhz */ +#define MODEL_WESTMERE_EX 0x2f /* Xeon E7 BCLK: 133 Mhz */ +#define MODEL_WESTMERE_GULFTOWN 0x2c /* Core i7 Xeon 3000 BCLK: 133 Mhz */ +#define MODEL_SANDYBRIDGE_SANDY 0x2a /* Core/Celeron/Pentium/Xeon BCLK: 133 Mhz */ +#define MODEL_SANDYBRIDGE_E 0x2d /* Core i7 and Ex BCLK: 100 Mhz */ +#define MODEL_IVYBRIDGE_IVY 0x3a /* Core i3/i5/i7 (Ex) and Xeon E3 BCLK: 100 Mhz */ +#define MODEL_HASWELL_HASWELL 0x3c /* BCLK: 100 Mhz */ +#define CPUID_MODEL_UNKNOWN 0x0 /* Everything else */ + +#define BCLK_133_DEFAULT (133 * 1000) +#define BCLK_100_DEFAULT (100 * 1000) + void kvm_update_cpuid(struct kvm_vcpu *vcpu); struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, u32 function, u32 index); @@ -18,6 +33,7 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, struct kvm_cpuid_entry2 __user *entries); void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); +u8 kvm_guest_vcpu_model(struct kvm_vcpu *vcpu); static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 2fb4faf..7d06729 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -236,6 +236,49 @@ void kvm_set_shared_msr(unsigned slot, u64 value, u64 mask) } EXPORT_SYMBOL_GPL(kvm_set_shared_msr); +static u64 kvm_get_platform_info(struct kvm_vcpu *vcpu) +{ + u8 cpumodel; + u32 bclk; + + /* + * Programmable Ratio Limit for Turbo Mode (bit 28): 0 + * Programmable TDC-TDP Limit for Turbo Mode (bit 29): 0 + */ + u64 platform_info = 0, max_nonturbo_ratio = 0, max_effi_ratio = 0; + + cpumodel = kvm_guest_vcpu_model(vcpu); + + switch (cpumodel) { + case MODEL_NEHALEM_CLARKSFIELD: + case MODEL_NEHALEM_BLOOMFIELD: + case MODEL_NEHALEM_EX: + case MODEL_WESTMERE_ARRANDALE: + case MODEL_WESTMERE_GULFTOWN: + case MODEL_WESTMERE_EX: + bclk = BCLK_133_DEFAULT; + break; + case MODEL_SANDYBRIDGE_SANDYBRIDGE: + case MODEL_SANDYBRIDGE_E: + case MODEL_IVYBRIDGE_IVYBRIDGE: + case MODEL_HASWELL_HASWELL: + bclk = BCLK_100_DEFAULT; + break; + default: + bclk = 0; + break; + } + + if (bclk) { + max_nonturbo_ratio = max_effi_ratio + = (u8)(vcpu->arch.virtual_tsc_khz / bclk); + platform_info = (max_effi_ratio << 40) + | (max_nonturbo_ratio << 8); + } + + return platform_info; +} + static void drop_user_return_notifiers(void *ignore) { unsigned int cpu = smp_processor_id(); @@ -1971,6 +2014,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_IA32_MISC_ENABLE: vcpu->arch.ia32_misc_enable_msr = data; break; + case MSR_IA32_PLATFORM_INFO: + return 1; case MSR_KVM_WALL_CLOCK_NEW: case MSR_KVM_WALL_CLOCK: vcpu->kvm->arch.wall_clock = data; @@ -2336,6 +2381,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_IA32_MISC_ENABLE: data = vcpu->arch.ia32_misc_enable_msr; break; + case MSR_IA32_PLATFORM_INFO: + data = kvm_get_platform_info(vcpu); + break; case MSR_IA32_PERF_STATUS: /* TSC increment by tick */ data = 1000ULL;