diff mbox series

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

Message ID 20220711041841.126648-3-weijiang.yang@intel.com (mailing list archive)
State New, archived
Headers show
Series Fixup and cleanup to pmu test applications | expand

Commit Message

Yang, Weijiang July 11, 2022, 4:18 a.m. UTC
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@intel.com>
---
 lib/x86/processor.h | 54 +++++++++++++++++++++++++++++++++++++++++++++
 x86/pmu.c           | 28 +++++++++++------------
 2 files changed, 67 insertions(+), 15 deletions(-)

Comments

Sean Christopherson July 21, 2022, 9:21 p.m. UTC | #1
On Mon, Jul 11, 2022, Yang Weijiang wrote:
> -	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();

Adding helpers for individual fields but then caching the full fields and
ignoring the helpers is silly.  It doesn't require much more work to get rid of
the unions entirely (see the pull request I sent to Paolo).
Yang, Weijiang July 22, 2022, 12:58 a.m. UTC | #2
On 7/22/2022 5:21 AM, Sean Christopherson wrote:
> On Mon, Jul 11, 2022, Yang Weijiang wrote:
>> -	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();
> Adding helpers for individual fields but then caching the full fields and
> ignoring the helpers is silly.  It doesn't require much more work to get rid of
> the unions entirely (see the pull request I sent to Paolo).

Thank you Sean!

I was not sure if it's suitable to do so, then got this half-done patch :-D.
diff mbox series

Patch

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;