[kvm-unit-tests PATCH 2/4] x86: Use helpers to fetch supported perf capabilities

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

 



Platform pmu fixed counter and GP events info is enumerated
in CPUID(0xA). Add helpers to fetch the data, other apps can
also rely them to check underneath pmu capabilities.

No functional change intended.

Signed-off-by: Yang Weijiang <weijiang.yang@xxxxxxxxx>
---
 lib/x86/processor.h | 54 +++++++++++++++++++++++++++++++++++++++++++++
 x86/pmu.c           | 28 +++++++++++------------
 2 files changed, 67 insertions(+), 15 deletions(-)

diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index 9a0dad6..d071aba 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -690,4 +690,58 @@ static inline bool cpuid_osxsave(void)
 	return cpuid(1).c & (1 << (X86_FEATURE_OSXSAVE % 32));
 }
 
+static inline u8 pmu_version(void)
+{
+	return cpuid(10).a & 0xff;
+}
+
+static inline u32 pmu_arch_info(void)
+{
+	return cpuid(10).a;
+}
+
+static inline u32 pmu_gp_events(void)
+{
+	return cpuid(10).b;
+}
+
+static inline u32 pmu_fixed_counters(void)
+{
+	return cpuid(10).d;
+}
+
+static inline u8 pmu_gp_counter_number(void)
+{
+	return (cpuid(10).a >> 8) & 0xff;
+}
+
+static inline u8 pmu_gp_counter_width(void)
+{
+	return (cpuid(10).a >> 16) & 0xff;
+}
+
+static inline u8 pmu_gp_counter_mask_length(void)
+{
+	return (cpuid(10).a >> 24) & 0xff;
+}
+
+static inline u8 pmu_fixed_counter_number(void)
+{
+	struct cpuid id = cpuid(10);
+
+	if ((id.a & 0xff) > 1)
+		return id.d & 0x1f;
+	else
+		return 0;
+}
+
+static inline u8 pmu_fixed_counter_width(void)
+{
+	struct cpuid id = cpuid(10);
+
+	if ((id.a & 0xff) > 1)
+		return (id.d >> 5) & 0xff;
+	else
+		return 0;
+}
 #endif
diff --git a/x86/pmu.c b/x86/pmu.c
index a46bdbf..0d72e5b 100644
--- a/x86/pmu.c
+++ b/x86/pmu.c
@@ -655,34 +655,32 @@ static void set_ref_cycle_expectations(void)
 
 int main(int ac, char **av)
 {
-	struct cpuid id = cpuid(10);
-
 	setup_vm();
 	handle_irq(PC_VECTOR, cnt_overflow);
 	buf = malloc(N*64);
 
-	eax.full = id.a;
-	ebx.full = id.b;
-	edx.full = id.d;
+	eax.full = pmu_arch_info();
+	ebx.full = pmu_gp_events();
+	edx.full = pmu_fixed_counters();
 
-	if (!eax.split.version_id) {
-		printf("No pmu is detected!\n");
+	if (!pmu_version()) {
+		report_skip("No pmu is detected!");
 		return report_summary();
 	}
 
-	if (eax.split.version_id == 1) {
-		printf("PMU version 1 is not supported\n");
+	if (pmu_version() == 1) {
+		report_skip("PMU version 1 is not supported.");
 		return report_summary();
 	}
 
 	set_ref_cycle_expectations();
 
-	printf("PMU version:         %d\n", eax.split.version_id);
-	printf("GP counters:         %d\n", eax.split.num_counters);
-	printf("GP counter width:    %d\n", eax.split.bit_width);
-	printf("Mask length:         %d\n", eax.split.mask_length);
-	printf("Fixed counters:      %d\n", edx.split.num_counters_fixed);
-	printf("Fixed counter width: %d\n", edx.split.bit_width_fixed);
+	printf("PMU version:         %d\n", pmu_version());
+	printf("GP counters:         %d\n", pmu_gp_counter_number());
+	printf("GP counter width:    %d\n", pmu_gp_counter_width());
+	printf("Mask length:         %d\n", pmu_gp_counter_mask_length());
+	printf("Fixed counters:      %d\n", pmu_fixed_counter_number());
+	printf("Fixed counter width: %d\n", pmu_fixed_counter_width());
 
 	num_counters = eax.split.num_counters;
 
-- 
2.31.1




[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