All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] KVM: x86: Enabling PMU v3 on non-SMT VMs
@ 2014-08-20 10:25 Nadav Amit
  2014-08-20 10:25 ` [PATCH 1/2] KVM: x86: Clarify PMU related features bit manipulation Nadav Amit
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Nadav Amit @ 2014-08-20 10:25 UTC (permalink / raw)
  To: pbonzini; +Cc: gleb, hpa, joro, mingo, kvm, Nadav Amit

This patch-set enables PMU v3 on non-SMT VMs. All the PMU v3 features are
already in KVM except the AnyThread support.  However, AnyThread is only
important on SMT machines, and can be ignored otherwise. Reporting PMU v3 can
be useful for OSes that rely on the version, and not on other CPUID fields.

Thanks for reviewing the code. Note that it was not tested on AMD machine.

Nadav Amit (2):
  KVM: x86: Clarify PMU related features bit manipulation
  KVM: x86: pmu: Enabling PMU v3

 arch/x86/include/asm/kvm_host.h |  1 +
 arch/x86/kvm/cpuid.c            |  2 +-
 arch/x86/kvm/pmu.c              | 35 +++++++++++++++++++++++------------
 arch/x86/kvm/svm.c              | 15 +++++++++++++++
 arch/x86/kvm/vmx.c              | 16 ++++++++++++++++
 5 files changed, 56 insertions(+), 13 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] KVM: x86: Clarify PMU related features bit manipulation
  2014-08-20 10:25 [PATCH 0/2] KVM: x86: Enabling PMU v3 on non-SMT VMs Nadav Amit
@ 2014-08-20 10:25 ` Nadav Amit
  2014-08-20 10:25 ` [PATCH 2/2] KVM: x86: pmu: Enabling PMU v3 Nadav Amit
  2014-08-20 11:01 ` [PATCH 0/2] KVM: x86: Enabling PMU v3 on non-SMT VMs Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Nadav Amit @ 2014-08-20 10:25 UTC (permalink / raw)
  To: pbonzini; +Cc: gleb, hpa, joro, mingo, kvm, Nadav Amit

kvm_pmu_cpuid_update makes a lot of bit manuiplation operations, when in fact
there are already unions that can be used instead. Changing the bit
manipulation to the union for clarity. This patch does not change the
functionality.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/kvm/pmu.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 3dd6acc..8e6b7d8 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/kvm_host.h>
 #include <linux/perf_event.h>
+#include <asm/perf_event.h>
 #include "x86.h"
 #include "cpuid.h"
 #include "lapic.h"
@@ -463,7 +464,8 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu)
 {
 	struct kvm_pmu *pmu = &vcpu->arch.pmu;
 	struct kvm_cpuid_entry2 *entry;
-	unsigned bitmap_len;
+	union cpuid10_eax eax;
+	union cpuid10_edx edx;
 
 	pmu->nr_arch_gp_counters = 0;
 	pmu->nr_arch_fixed_counters = 0;
@@ -475,25 +477,27 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu)
 	entry = kvm_find_cpuid_entry(vcpu, 0xa, 0);
 	if (!entry)
 		return;
+	eax.full = entry->eax;
+	edx.full = entry->edx;
 
-	pmu->version = entry->eax & 0xff;
+	pmu->version = eax.split.version_id;
 	if (!pmu->version)
 		return;
 
-	pmu->nr_arch_gp_counters = min((int)(entry->eax >> 8) & 0xff,
-			INTEL_PMC_MAX_GENERIC);
-	pmu->counter_bitmask[KVM_PMC_GP] =
-		((u64)1 << ((entry->eax >> 16) & 0xff)) - 1;
-	bitmap_len = (entry->eax >> 24) & 0xff;
-	pmu->available_event_types = ~entry->ebx & ((1ull << bitmap_len) - 1);
+	pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters,
+					INTEL_PMC_MAX_GENERIC);
+	pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << eax.split.bit_width) - 1;
+	pmu->available_event_types = ~entry->ebx &
+					((1ull << eax.split.mask_length) - 1);
 
 	if (pmu->version == 1) {
 		pmu->nr_arch_fixed_counters = 0;
 	} else {
-		pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f),
+		pmu->nr_arch_fixed_counters =
+			min_t(int, edx.split.num_counters_fixed,
 				INTEL_PMC_MAX_FIXED);
 		pmu->counter_bitmask[KVM_PMC_FIXED] =
-			((u64)1 << ((entry->edx >> 5) & 0xff)) - 1;
+			((u64)1 << edx.split.bit_width_fixed) - 1;
 	}
 
 	pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) |
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] KVM: x86: pmu: Enabling PMU v3
  2014-08-20 10:25 [PATCH 0/2] KVM: x86: Enabling PMU v3 on non-SMT VMs Nadav Amit
  2014-08-20 10:25 ` [PATCH 1/2] KVM: x86: Clarify PMU related features bit manipulation Nadav Amit
@ 2014-08-20 10:25 ` Nadav Amit
  2014-08-20 11:01 ` [PATCH 0/2] KVM: x86: Enabling PMU v3 on non-SMT VMs Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Nadav Amit @ 2014-08-20 10:25 UTC (permalink / raw)
  To: pbonzini; +Cc: gleb, hpa, joro, mingo, kvm, Nadav Amit

Currently the guest PMU version number 3 is not supported (versions up to 2 are
reported).  The features PMU v3 presents are: AnyThread, extend reporting of
capabilities in CPUID leaf 0AH and varible number of perfomrance counters.
While most of the support is already present, the version reported is still 2,
since dealing with AnyThread is complicated. Nonetheless, OSes may assume other
features than AnyThread are not supported since the version report is 2.

This patch checks if the guest vCPU uses SMT. If not, it reports PMU v3.  When
PMU v3 is used, the AnyThread bit is ignored, but does not trigger faults.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/include/asm/kvm_host.h |  1 +
 arch/x86/kvm/cpuid.c            |  2 +-
 arch/x86/kvm/pmu.c              | 11 +++++++++--
 arch/x86/kvm/svm.c              | 15 +++++++++++++++
 arch/x86/kvm/vmx.c              | 16 ++++++++++++++++
 5 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4bda61b..8c8401b 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -327,6 +327,7 @@ struct kvm_pmu {
 	u64 counter_bitmask[2];
 	u64 global_ctrl_mask;
 	u64 reserved_bits;
+	u64 fixed_ctrl_reserved_bits;
 	u8 version;
 	struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC];
 	struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED];
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 38a0afe..0d7b729 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -406,7 +406,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
 		if (!cap.version)
 			memset(&cap, 0, sizeof(cap));
 
-		eax.split.version_id = min(cap.version, 2);
+		eax.split.version_id = min(cap.version, 3);
 		eax.split.num_counters = cap.num_counters_gp;
 		eax.split.bit_width = cap.bit_width_gp;
 		eax.split.mask_length = cap.events_mask_len;
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 8e6b7d8..2ad7101 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -383,7 +383,7 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	case MSR_CORE_PERF_FIXED_CTR_CTRL:
 		if (pmu->fixed_ctr_ctrl == data)
 			return 0;
-		if (!(data & 0xfffffffffffff444ull)) {
+		if (!(data & pmu->fixed_ctrl_reserved_bits)) {
 			reprogram_fixed_counters(pmu, data);
 			return 0;
 		}
@@ -472,7 +472,7 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu)
 	pmu->counter_bitmask[KVM_PMC_GP] = 0;
 	pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
 	pmu->version = 0;
-	pmu->reserved_bits = 0xffffffff00200000ull;
+	pmu->reserved_bits = 0xffffffff00000000ull;
 
 	entry = kvm_find_cpuid_entry(vcpu, 0xa, 0);
 	if (!entry)
@@ -504,6 +504,13 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu)
 		(((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED);
 	pmu->global_ctrl_mask = ~pmu->global_ctrl;
 
+	pmu->fixed_ctrl_reserved_bits =
+		~((1ull << pmu->nr_arch_fixed_counters * 4) - 1);
+	if (pmu->version == 2) {
+		/* No support for anythread */
+		pmu->reserved_bits |= 0x200000;
+		pmu->fixed_ctrl_reserved_bits |= 0x4444444444444444ull;
+	}
 	entry = kvm_find_cpuid_entry(vcpu, 7, 0);
 	if (entry &&
 	    (boot_cpu_has(X86_FEATURE_HLE) || boot_cpu_has(X86_FEATURE_RTM)) &&
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 1f49c86..963a9c0 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -4057,6 +4057,21 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
 
 static void svm_cpuid_update(struct kvm_vcpu *vcpu)
 {
+	struct kvm_cpuid_entry2 *best;
+
+	/* If SMT, then PMU v3 is unsupported because of the anythread bit */
+	best = kvm_find_cpuid_entry(vcpu, 0x8000001e, 0);
+	if (best && ((best->ebx >> 8) & 3) > 0) {
+		best = kvm_find_cpuid_entry(vcpu, 0xa, 0);
+		if (best) {
+			union cpuid10_eax eax;
+
+			eax.full = best->eax;
+			eax.split.version_id =
+				min_t(int, eax.split.version_id, 2);
+			best->eax = eax.full;
+		}
+	}
 }
 
 static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index cad37d5..437b131 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -7726,6 +7726,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
 	struct kvm_cpuid_entry2 *best;
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	u32 exec_control;
+	bool smt = false;
 
 	vmx->rdtscp_enabled = false;
 	if (vmx_rdtscp_supported()) {
@@ -7761,6 +7762,21 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
 		if (best)
 			best->ebx &= ~bit(X86_FEATURE_INVPCID);
 	}
+
+	/* If SMT, then PMU v3 is unsupported because of the anythread bit */
+	best = kvm_find_cpuid_entry(vcpu, 0xb, 0);
+	smt = best && ((best->ecx >> 8) & 0xff) == 1 &&
+		((best->ebx & 0xffff) > 1);
+	best = kvm_find_cpuid_entry(vcpu, 0x1, 0);
+	smt |= best && (best->edx & bit(X86_FEATURE_HT));
+	best = kvm_find_cpuid_entry(vcpu, 0xa, 0);
+	if (smt && best) {
+		union cpuid10_eax eax;
+
+		eax.full = best->eax;
+		eax.split.version_id = min_t(int, eax.split.version_id, 2);
+		best->eax = eax.full;
+	}
 }
 
 static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] KVM: x86: Enabling PMU v3 on non-SMT VMs
  2014-08-20 10:25 [PATCH 0/2] KVM: x86: Enabling PMU v3 on non-SMT VMs Nadav Amit
  2014-08-20 10:25 ` [PATCH 1/2] KVM: x86: Clarify PMU related features bit manipulation Nadav Amit
  2014-08-20 10:25 ` [PATCH 2/2] KVM: x86: pmu: Enabling PMU v3 Nadav Amit
@ 2014-08-20 11:01 ` Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2014-08-20 11:01 UTC (permalink / raw)
  To: Nadav Amit; +Cc: gleb, hpa, joro, mingo, kvm

Il 20/08/2014 12:25, Nadav Amit ha scritto:
> This patch-set enables PMU v3 on non-SMT VMs. All the PMU v3 features are
> already in KVM except the AnyThread support.  However, AnyThread is only
> important on SMT machines, and can be ignored otherwise. Reporting PMU v3 can
> be useful for OSes that rely on the version, and not on other CPUID fields.
> 
> Thanks for reviewing the code. Note that it was not tested on AMD machine.
> 
> Nadav Amit (2):
>   KVM: x86: Clarify PMU related features bit manipulation
>   KVM: x86: pmu: Enabling PMU v3
> 
>  arch/x86/include/asm/kvm_host.h |  1 +
>  arch/x86/kvm/cpuid.c            |  2 +-
>  arch/x86/kvm/pmu.c              | 35 +++++++++++++++++++++++------------
>  arch/x86/kvm/svm.c              | 15 +++++++++++++++
>  arch/x86/kvm/vmx.c              | 16 ++++++++++++++++
>  5 files changed, 56 insertions(+), 13 deletions(-)
> 

For now I've reviewed patch 1 and will apply that to kvm/queue.

Paolo

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-08-20 11:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-20 10:25 [PATCH 0/2] KVM: x86: Enabling PMU v3 on non-SMT VMs Nadav Amit
2014-08-20 10:25 ` [PATCH 1/2] KVM: x86: Clarify PMU related features bit manipulation Nadav Amit
2014-08-20 10:25 ` [PATCH 2/2] KVM: x86: pmu: Enabling PMU v3 Nadav Amit
2014-08-20 11:01 ` [PATCH 0/2] KVM: x86: Enabling PMU v3 on non-SMT VMs Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.