[kvm-unit-tests PATCH v5 15/27] x86/pmu: Snapshot PMU perf_capabilities during BSP initialization

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

 



From: Like Xu <likexu@xxxxxxxxxxx>

Add a global "struct pmu_caps pmu" to snapshot PMU capabilities
during the final stages of BSP initialization.  Use the new hooks to
snapshot PERF_CAPABILITIES instead of re-reading the MSR every time a
test wants to query capabilities.  A software-defined struct will also
simplify extending support to AMD CPUs, as many of the differences
between AMD and Intel can be handled during pmu_init().

Init the PMU caps for all tests so that tests don't need to remember to
call pmu_init() before using any of the PMU helpers, e.g. the nVMX test
uses this_cpu_has_pmu(), which will be converted to rely on the global
struct in a future patch.

Suggested-by: Sean Christopherson <seanjc@xxxxxxxxxx>
Signed-off-by: Like Xu <likexu@xxxxxxxxxxx>
[sean: reword changelog]
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
 lib/x86/pmu.c   |  8 ++++++++
 lib/x86/pmu.h   | 21 ++++++++++++++++++---
 lib/x86/setup.c |  2 ++
 x86/pmu.c       |  2 +-
 x86/pmu_lbr.c   |  7 ++-----
 5 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/lib/x86/pmu.c b/lib/x86/pmu.c
index 9d048abc..bb272ab7 100644
--- a/lib/x86/pmu.c
+++ b/lib/x86/pmu.c
@@ -1 +1,9 @@
 #include "pmu.h"
+
+struct pmu_caps pmu;
+
+void pmu_init(void)
+{
+	if (this_cpu_has(X86_FEATURE_PDCM))
+		pmu.perf_cap = rdmsr(MSR_IA32_PERF_CAPABILITIES);
+}
diff --git a/lib/x86/pmu.h b/lib/x86/pmu.h
index 078a9747..4780237c 100644
--- a/lib/x86/pmu.h
+++ b/lib/x86/pmu.h
@@ -33,6 +33,14 @@
 #define EVNTSEL_INT	(1 << EVNTSEL_INT_SHIFT)
 #define EVNTSEL_INV	(1 << EVNTSEL_INV_SHIF)
 
+struct pmu_caps {
+	u64 perf_cap;
+};
+
+extern struct pmu_caps pmu;
+
+void pmu_init(void);
+
 static inline u8 pmu_version(void)
 {
 	return cpuid(10).a & 0xff;
@@ -91,10 +99,17 @@ static inline bool pmu_gp_counter_is_available(int i)
 
 static inline u64 this_cpu_perf_capabilities(void)
 {
-	if (!this_cpu_has(X86_FEATURE_PDCM))
-		return 0;
+	return pmu.perf_cap;
+}
 
-	return rdmsr(MSR_IA32_PERF_CAPABILITIES);
+static inline u64 pmu_lbr_version(void)
+{
+	return this_cpu_perf_capabilities() & PMU_CAP_LBR_FMT;
+}
+
+static inline bool pmu_has_full_writes(void)
+{
+	return this_cpu_perf_capabilities() & PMU_CAP_FW_WRITES;
 }
 
 #endif /* _X86_PMU_H_ */
diff --git a/lib/x86/setup.c b/lib/x86/setup.c
index a7b3edbe..1ebbf58a 100644
--- a/lib/x86/setup.c
+++ b/lib/x86/setup.c
@@ -15,6 +15,7 @@
 #include "apic-defs.h"
 #include "asm/setup.h"
 #include "atomic.h"
+#include "pmu.h"
 #include "processor.h"
 #include "smp.h"
 
@@ -398,4 +399,5 @@ void bsp_rest_init(void)
 	bringup_aps();
 	enable_x2apic();
 	smp_init();
+	pmu_init();
 }
diff --git a/x86/pmu.c b/x86/pmu.c
index 7d67746e..627fd394 100644
--- a/x86/pmu.c
+++ b/x86/pmu.c
@@ -669,7 +669,7 @@ int main(int ac, char **av)
 
 	check_counters();
 
-	if (this_cpu_perf_capabilities() & PMU_CAP_FW_WRITES) {
+	if (pmu_has_full_writes()) {
 		gp_counter_base = MSR_IA32_PMC0;
 		report_prefix_push("full-width writes");
 		check_counters();
diff --git a/x86/pmu_lbr.c b/x86/pmu_lbr.c
index e6d98236..d0135520 100644
--- a/x86/pmu_lbr.c
+++ b/x86/pmu_lbr.c
@@ -43,7 +43,6 @@ static bool test_init_lbr_from_exception(u64 index)
 
 int main(int ac, char **av)
 {
-	u64 perf_cap;
 	int max, i;
 
 	setup_vm();
@@ -63,15 +62,13 @@ int main(int ac, char **av)
 		return report_summary();
 	}
 
-	perf_cap = this_cpu_perf_capabilities();
-
-	if (!(perf_cap & PMU_CAP_LBR_FMT)) {
+	if (!pmu_lbr_version()) {
 		report_skip("(Architectural) LBR is not supported.");
 		return report_summary();
 	}
 
 	printf("PMU version:		 %d\n", pmu_version());
-	printf("LBR version:		 %ld\n", perf_cap & PMU_CAP_LBR_FMT);
+	printf("LBR version:		 %ld\n", pmu_lbr_version());
 
 	/* Look for LBR from and to MSRs */
 	lbr_from = MSR_LBR_CORE_FROM;
-- 
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