diff mbox

[v2,2/2] kvm: x86: emulate MSR_PLATFORM_INFO

Message ID 1370361738-4277-3-git-send-email-bsd@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Bandan Das June 4, 2013, 4:02 p.m. UTC
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

v2:
Change function name to kvm_cpuid_get_intel_model and 
call the new vendor_intel()

Signed-off-by: Bandan Das <bsd@redhat.com>
---
 arch/x86/include/uapi/asm/msr-index.h |  2 ++
 arch/x86/kvm/cpuid.c                  | 19 ++++++++++++++
 arch/x86/kvm/cpuid.h                  | 16 ++++++++++++
 arch/x86/kvm/x86.c                    | 48 +++++++++++++++++++++++++++++++++++
 4 files changed, 85 insertions(+)

Comments

Paolo Bonzini June 18, 2013, 2:07 p.m. UTC | #1
Il 04/06/2013 18:02, Bandan Das ha scritto:
> +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_cpuid_get_intel_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;

Just one change: please rename this to base_clock_khz and remove the
BCLK_*_DEFAULT constants please.

Paolo

> +		break;
> +	case MODEL_SANDYBRIDGE_SANDY:
> +	case MODEL_SANDYBRIDGE_E:
> +	case MODEL_IVYBRIDGE_IVY:
> +	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);
> +	}

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Bandan Das June 18, 2013, 3:11 p.m. UTC | #2
Paolo Bonzini <pbonzini@redhat.com> writes:

> Il 04/06/2013 18:02, Bandan Das ha scritto:
>> +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_cpuid_get_intel_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;
>
> Just one change: please rename this to base_clock_khz and remove the
> BCLK_*_DEFAULT constants please.

Thanks for the review! I thought the base clock is usually referred to 
as bclk in Intel parlance but not sure :) 

Anyway, I will send a new one.


> Paolo
>
>> +		break;
>> +	case MODEL_SANDYBRIDGE_SANDY:
>> +	case MODEL_SANDYBRIDGE_E:
>> +	case MODEL_IVYBRIDGE_IVY:
>> +	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);
>> +	}
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

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..ae970d3 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -608,6 +608,25 @@  struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
 }
 EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry);
 
+u8 kvm_cpuid_get_intel_model(struct kvm_vcpu *vcpu)
+{
+	struct kvm_cpuid_entry2 *best;
+	u8 cpuid_model, cpuid_extmodel;
+
+	best = kvm_find_cpuid_entry(vcpu, 0, 0);
+	if (!vendor_intel(best->ebx, best->ecx, best->edx))
+		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..081461d 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_cpuid_get_intel_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 094b5d9..f9b2830 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -239,6 +239,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_cpuid_get_intel_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_SANDY:
+	case MODEL_SANDYBRIDGE_E:
+	case MODEL_IVYBRIDGE_IVY:
+	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();
@@ -1974,6 +2017,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;
@@ -2339,6 +2384,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;