[kvm-unit-tests PATCH v5 27/27] x86/pmu: Add AMD Guest PerfMonV2 testcases

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Like Xu <likexu@xxxxxxxxxxx>

Updated test cases to cover KVM enabling code for AMD Guest PerfMonV2.

The Intel-specific PMU helpers were added to check for AMD cpuid, and
some of the same semantics of MSRs were assigned during the initialization
phase. The vast majority of pmu test cases are reused seamlessly.

On some x86 machines (AMD only), even with retired events, the same
workload is measured repeatedly and the number of events collected is
erratic, which essentially reflects the details of hardware implementation,
and from a software perspective, the type of event is an unprecise event,
which brings a tolerance check in the counter overflow testcases.

Signed-off-by: Like Xu <likexu@xxxxxxxxxxx>
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
 lib/x86/msr.h       |  5 +++++
 lib/x86/pmu.c       | 14 +++++++++++++-
 lib/x86/processor.h |  2 +-
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/lib/x86/msr.h b/lib/x86/msr.h
index 6cf8f336..c9869be5 100644
--- a/lib/x86/msr.h
+++ b/lib/x86/msr.h
@@ -426,6 +426,11 @@
 #define MSR_CORE_PERF_GLOBAL_CTRL	0x0000038f
 #define MSR_CORE_PERF_GLOBAL_OVF_CTRL	0x00000390
 
+/* AMD Performance Counter Global Status and Control MSRs */
+#define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS	0xc0000300
+#define MSR_AMD64_PERF_CNTR_GLOBAL_CTL		0xc0000301
+#define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR	0xc0000302
+
 /* Geode defined MSRs */
 #define MSR_GEODE_BUSCONT_CONF0		0x00001900
 
diff --git a/lib/x86/pmu.c b/lib/x86/pmu.c
index 090e1115..af68f3a8 100644
--- a/lib/x86/pmu.c
+++ b/lib/x86/pmu.c
@@ -39,9 +39,15 @@ void pmu_init(void)
 			pmu.msr_global_status_clr = MSR_CORE_PERF_GLOBAL_OVF_CTRL;
 		}
 	} else {
+		/* Performance Monitoring Version 2 Supported */
+		if (this_cpu_has(X86_FEATURE_AMD_PMU_V2))
+			pmu.version = 2;
+
 		pmu.msr_gp_counter_base = MSR_F15H_PERF_CTR0;
 		pmu.msr_gp_event_select_base = MSR_F15H_PERF_CTL0;
-		if (!this_cpu_has(X86_FEATURE_PERFCTR_CORE))
+		if (this_cpu_has(X86_FEATURE_AMD_PMU_V2))
+			pmu.nr_gp_counters = cpuid(0x80000022).b & 0xf;
+		else if (!this_cpu_has(X86_FEATURE_PERFCTR_CORE))
 			pmu.nr_gp_counters = AMD64_NUM_COUNTERS;
 		else
 			pmu.nr_gp_counters = AMD64_NUM_COUNTERS_CORE;
@@ -49,6 +55,12 @@ void pmu_init(void)
 		pmu.gp_counter_width = PMC_DEFAULT_WIDTH;
 		pmu.gp_counter_mask_length = pmu.nr_gp_counters;
 		pmu.gp_counter_available = (1u << pmu.nr_gp_counters) - 1;
+
+		if (this_cpu_has_perf_global_status()) {
+			pmu.msr_global_status = MSR_AMD64_PERF_CNTR_GLOBAL_STATUS;
+			pmu.msr_global_ctl = MSR_AMD64_PERF_CNTR_GLOBAL_CTL;
+			pmu.msr_global_status_clr = MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR;
+		}
 	}
 
 	pmu_reset_all_counters();
diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index 681e1675..72bdc833 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -266,7 +266,7 @@ static inline bool is_intel(void)
 #define X86_FEATURE_PAUSEFILTER		(CPUID(0x8000000A, 0, EDX, 10))
 #define X86_FEATURE_PFTHRESHOLD		(CPUID(0x8000000A, 0, EDX, 12))
 #define	X86_FEATURE_VGIF		(CPUID(0x8000000A, 0, EDX, 16))
-
+#define	X86_FEATURE_AMD_PMU_V2		(CPUID(0x80000022, 0, EAX, 0))
 
 static inline bool this_cpu_has(u64 feature)
 {
-- 
2.38.1.431.g37b22c650d-goog




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux