All of lore.kernel.org
 help / color / mirror / Atom feed
* [kvm-unit-tests PATCH 0/4] Fixup and cleanup to pmu test applications
@ 2022-07-11  4:18 Yang Weijiang
  2022-07-11  4:18 ` [kvm-unit-tests PATCH 1/4] x86: Use report_skip to print messages when tests are skipped Yang Weijiang
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Yang Weijiang @ 2022-07-11  4:18 UTC (permalink / raw)
  To: seanjc, pbonzini, kvm; +Cc: Yang Weijiang

I Found a few pmu test failures when ran againt KVM/queue branch with pmu
disabled(enable_pmu=0), and posted a few fixup patches for the issues.
Maintainers reviewed and commented actively, which makes the fixup patches
evolved into this series. Besides two fixup patches, there're another two
cleanup patches included.

patch 1: Cleanup patch. Use report_skip() instead of printf() to make
output logs clean.
patch 2: Cleanup patch. Add helpers to check platform supported pmu
capabilities.
patch 3~4: Fixup patches. Fix test failures seen when pmu_enable=0.


Yang Weijiang (4):
  x86: Use report_skip to print messages when tests are skipped
  x86: Use helpers to fetch supported perf capabilities
  x86: Skip perf related tests when platform cannot support
  x86: Check platform pmu capabilities before run lbr tests

 lib/x86/processor.h |  70 ++++++++++++++++++++++++++++
 x86/pmu.c           |  28 ++++++------
 x86/pmu_lbr.c       |  33 ++++++--------
 x86/vmx_tests.c     | 109 +++++++++++++++++++++++---------------------
 4 files changed, 153 insertions(+), 87 deletions(-)


base-commit: ca85dda2671e88d34acfbca6de48a9ab32b1810d
-- 
2.31.1


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

* [kvm-unit-tests PATCH 1/4] x86: Use report_skip to print messages when tests are skipped
  2022-07-11  4:18 [kvm-unit-tests PATCH 0/4] Fixup and cleanup to pmu test applications Yang Weijiang
@ 2022-07-11  4:18 ` Yang Weijiang
  2022-07-11  4:18 ` [kvm-unit-tests PATCH 2/4] x86: Use helpers to fetch supported perf capabilities Yang Weijiang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Yang Weijiang @ 2022-07-11  4:18 UTC (permalink / raw)
  To: seanjc, pbonzini, kvm; +Cc: Yang Weijiang

report_skip() prints message with "SKIP:" prefix to explictly
tell which test is skipped, use it to make test report clean.

Opportunistically unify the message format for report_skip().

Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 x86/vmx_tests.c | 88 ++++++++++++++++++++++++-------------------------
 1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 4d581e7..d5868a3 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -1766,7 +1766,7 @@ static void nmi_hlt_main(void)
     long long start;
 
     if (cpu_count() < 2) {
-        report_skip(__func__);
+        report_skip("%s :CPU count < 2", __func__);
         vmx_set_test_stage(-1);
         return;
     }
@@ -4107,7 +4107,7 @@ static void test_vpid(void)
 	int i;
 
 	if (!is_vpid_supported()) {
-		printf("Secondary controls and/or VPID not supported\n");
+		report_skip("%s :Secondary controls and/or VPID not supported", __func__);
 		return;
 	}
 
@@ -4614,7 +4614,7 @@ static void test_nmi_ctrls(void)
 
 	if ((ctrl_pin_rev.clr & (PIN_NMI | PIN_VIRT_NMI)) !=
 	    (PIN_NMI | PIN_VIRT_NMI)) {
-		printf("NMI exiting and Virtual NMIs are not supported !\n");
+		report_skip("%s :NMI exiting and/or Virtual NMIs not supported", __func__);
 		return;
 	}
 
@@ -4724,7 +4724,7 @@ static void test_ept_eptp(void)
 
 	if (!((ctrl_cpu_rev[0].clr & CPU_SECONDARY) &&
 	    (ctrl_cpu_rev[1].clr & CPU_EPT))) {
-		printf("\"CPU secondary\" and/or \"enable EPT\" execution controls are not supported !\n");
+		report_skip("%s :\"CPU secondary\" and/or \"enable EPT\" exec control not supported", __func__);
 		return;
 	}
 
@@ -4884,7 +4884,7 @@ static void test_pml(void)
 
 	if (!((ctrl_cpu_rev[0].clr & CPU_SECONDARY) &&
 	    (ctrl_cpu_rev[1].clr & CPU_EPT) && (ctrl_cpu_rev[1].clr & CPU_PML))) {
-		printf("\"Secondary execution\" control or \"enable EPT\" control or \"enable PML\" control is not supported !\n");
+		report_skip("%s :\"Secondary execution\" or \"enable EPT\" or \"enable PML\" control not supported", __func__);
 		return;
 	}
 
@@ -4936,7 +4936,7 @@ static void test_vmx_preemption_timer(void)
 
 	if (!((ctrl_exit_rev.clr & EXI_SAVE_PREEMPT) ||
 	    (ctrl_pin_rev.clr & PIN_PREEMPT))) {
-		printf("\"Save-VMX-preemption-timer\" control and/or \"Enable-VMX-preemption-timer\" control is not supported\n");
+		report_skip("%s :\"Save-VMX-preemption-timer\" and/or \"Enable-VMX-preemption-timer\" control not supported", __func__);
 		return;
 	}
 
@@ -5060,7 +5060,7 @@ static void vmx_mtf_test(void)
 	handler old_gp, old_db;
 
 	if (!(ctrl_cpu_rev[0].clr & CPU_MTF)) {
-		printf("CPU does not support the 'monitor trap flag' processor-based VM-execution control.\n");
+		report_skip("%s :\"Monitor trap flag\" exec control not supported", __func__);
 		return;
 	}
 
@@ -5163,12 +5163,12 @@ static void vmx_mtf_pdpte_test(void)
 		return;
 
 	if (!(ctrl_cpu_rev[0].clr & CPU_MTF)) {
-		printf("CPU does not support 'monitor trap flag.'\n");
+		report_skip("%s :\"Monitor trap flag\" exec control not supported", __func__);
 		return;
 	}
 
 	if (!(ctrl_cpu_rev[1].clr & CPU_URG)) {
-		printf("CPU does not support 'unrestricted guest.'\n");
+		report_skip("%s :\"Unrestricted guest\" exec control not supported", __func__);
 		return;
 	}
 
@@ -6142,7 +6142,7 @@ static void apic_reg_virt_test(void)
 	struct apic_reg_virt_guest_args *args = &apic_reg_virt_guest_args;
 
 	if (!cpu_has_apicv()) {
-		report_skip(__func__);
+		report_skip("%s :Not all required APICv bits supported", __func__);
 		return;
 	}
 
@@ -6879,7 +6879,7 @@ static enum Config_type configure_virt_x2apic_mode_test(
 
 	if (virt_x2apic_mode_config->virtual_interrupt_delivery) {
 		if (!(ctrl_cpu_rev[1].clr & CPU_VINTD)) {
-			report_skip("VM-execution control \"virtual-interrupt delivery\" NOT supported.\n");
+			report_skip("%s :\"virtual-interrupt delivery\" exec control not supported", __func__);
 			return CONFIG_TYPE_UNSUPPORTED;
 		}
 		cpu_exec_ctrl1 |= CPU_VINTD;
@@ -6920,7 +6920,7 @@ static void virt_x2apic_mode_test(void)
 	struct virt_x2apic_mode_guest_args *args = &virt_x2apic_mode_guest_args;
 
 	if (!cpu_has_apicv()) {
-		report_skip(__func__);
+		report_skip("%s :Not all required APICv bits supported", __func__);
 		return;
 	}
 
@@ -6940,10 +6940,10 @@ static void virt_x2apic_mode_test(void)
 	 *   - "MSR-bitmap address", indicated by "use MSR bitmaps"
 	 */
 	if (!(ctrl_cpu_rev[0].clr & CPU_TPR_SHADOW)) {
-		report_skip("VM-execution control \"use TPR shadow\" NOT supported.\n");
+		report_skip("%s :\"Use TPR shadow\" exec control not supported", __func__);
 		return;
 	} else if (!(ctrl_cpu_rev[0].clr & CPU_MSR_BITMAP)) {
-		report_skip("VM-execution control \"use MSR bitmaps\" NOT supported.\n");
+		report_skip("%s :\"Use MSR bitmaps\" exec control not supported", __func__);
 		return;
 	}
 
@@ -6969,7 +6969,7 @@ static void virt_x2apic_mode_test(void)
 			configure_virt_x2apic_mode_test(virt_x2apic_mode_config,
 							msr_bitmap_page);
 		if (config_type == CONFIG_TYPE_UNSUPPORTED) {
-			report_skip("Skip because of missing features.\n");
+			report_skip("Skip because of missing features.");
 			continue;
 		} else if (config_type == CONFIG_TYPE_VMENTRY_FAILS_EARLY) {
 			enter_guest_with_bad_controls();
@@ -7175,7 +7175,7 @@ static void test_efer(u32 fld, const char * fld_name, u32 ctrl_fld,
 		efer_reserved_bits &= ~EFER_NX;
 
 	if (!ctrl_bit1) {
-		printf("\"Load-IA32-EFER\" exit control not supported\n");
+		report_skip("%s :\"Load-IA32-EFER\" exit control not supported", __func__);
 		goto test_entry_exit_mode;
 	}
 
@@ -7258,7 +7258,7 @@ static void test_host_efer(void)
 static void test_guest_efer(void)
 {
 	if (!(ctrl_enter_rev.clr & ENT_LOAD_EFER)) {
-		printf("\"Load-IA32-EFER\" entry control not supported\n");
+		report_skip("%s :\"Load-IA32-EFER\" entry control not supported", __func__);
 		return;
 	}
 
@@ -7349,7 +7349,7 @@ static void test_load_host_pat(void)
 	 * "load IA32_PAT" VM-exit control
 	 */
 	if (!(ctrl_exit_rev.clr & EXI_LOAD_PAT)) {
-		printf("\"Load-IA32-PAT\" exit control not supported\n");
+		report_skip("%s :\"Load-IA32-PAT\" exit control not supported", __func__);
 		return;
 	}
 
@@ -7491,7 +7491,7 @@ static void test_perf_global_ctrl(u32 nr, const char *name, u32 ctrl_nr,
 static void test_load_host_perf_global_ctrl(void)
 {
 	if (!(ctrl_exit_rev.clr & EXI_LOAD_PERF)) {
-		printf("\"load IA32_PERF_GLOBAL_CTRL\" exit control not supported\n");
+		report_skip("%s :\"Load IA32_PERF_GLOBAL_CTRL\" exit control not supported", __func__);
 		return;
 	}
 
@@ -7503,7 +7503,7 @@ static void test_load_host_perf_global_ctrl(void)
 static void test_load_guest_perf_global_ctrl(void)
 {
 	if (!(ctrl_enter_rev.clr & ENT_LOAD_PERF)) {
-		printf("\"load IA32_PERF_GLOBAL_CTRL\" entry control not supported\n");
+		report_skip("%s :\"Load IA32_PERF_GLOBAL_CTRL\" entry control not supported", __func__);
 		return;
 	}
 
@@ -7809,7 +7809,7 @@ static void test_load_guest_pat(void)
 	 * "load IA32_PAT" VM-entry control
 	 */
 	if (!(ctrl_enter_rev.clr & ENT_LOAD_PAT)) {
-		printf("\"Load-IA32-PAT\" entry control not supported\n");
+		report_skip("%s :\"Load-IA32-PAT\" entry control not supported", __func__);
 		return;
 	}
 
@@ -7833,7 +7833,7 @@ static void test_load_guest_bndcfgs(void)
 	u64 bndcfgs;
 
 	if (!(ctrl_enter_rev.clr & ENT_LOAD_BNDCFGS)) {
-		printf("\"Load-IA32-BNDCFGS\" entry control not supported\n");
+		report_skip("%s :\"Load-IA32-BNDCFGS\" entry control not supported", __func__);
 		return;
 	}
 
@@ -8134,7 +8134,7 @@ static void unsetup_unrestricted_guest(void)
 static void vmentry_unrestricted_guest_test(void)
 {
 	if (enable_unrestricted_guest(true)) {
-		report_skip("Unrestricted guest not supported");
+		report_skip("%s: \"Unrestricted guest\" exec control not supported", __func__);
 		return;
 	}
 
@@ -8298,11 +8298,11 @@ static void vmx_cr_load_test(void)
 	orig_cr3 = read_cr3();
 
 	if (!this_cpu_has(X86_FEATURE_PCID)) {
-		report_skip("PCID not detected");
+		report_skip("%s :PCID not detected", __func__);
 		return;
 	}
 	if (!this_cpu_has(X86_FEATURE_MCE)) {
-		report_skip("MCE not detected");
+		report_skip("%s :MCE not detected", __func__);
 		return;
 	}
 
@@ -8407,7 +8407,7 @@ static void vmx_cr4_osxsave_test_guest(void)
 static void vmx_cr4_osxsave_test(void)
 {
 	if (!this_cpu_has(X86_FEATURE_XSAVE)) {
-		report_skip("XSAVE not detected");
+		report_skip("%s :XSAVE not detected", __func__);
 		return;
 	}
 
@@ -8592,12 +8592,12 @@ static void vmx_nmi_window_test(void)
 	void *db_fault_addr = get_idt_addr(&boot_idt[DB_VECTOR]);
 
 	if (!(ctrl_pin_rev.clr & PIN_VIRT_NMI)) {
-		report_skip("CPU does not support the \"Virtual NMIs\" VM-execution control.");
+		report_skip("%s :\"Virtual NMIs\" exec control not supported", __func__);
 		return;
 	}
 
 	if (!(ctrl_cpu_rev[0].clr & CPU_NMI_WINDOW)) {
-		report_skip("CPU does not support the \"NMI-window exiting\" VM-execution control.");
+		report_skip("%s :\"NMI-window exiting\" exec control not supported", __func__);
 		return;
 	}
 
@@ -8728,7 +8728,7 @@ static void vmx_intr_window_test(void)
 	void *db_fault_addr = get_idt_addr(&boot_idt[DB_VECTOR]);
 
 	if (!(ctrl_cpu_rev[0].clr & CPU_INTR_WINDOW)) {
-		report_skip("CPU does not support the \"interrupt-window exiting\" VM-execution control.");
+		report_skip("%s :\"Interrupt-window exiting\" exec control not supported", __func__);
 		return;
 	}
 
@@ -8880,7 +8880,7 @@ static void vmx_store_tsc_test(void)
 	u64 low, high;
 
 	if (!(ctrl_cpu_rev[0].clr & CPU_USE_TSC_OFFSET)) {
-		report_skip("'Use TSC offsetting' not supported");
+		report_skip("%s :\"Use TSC offsetting\" exec control not supported", __func__);
 		return;
 	}
 
@@ -8967,7 +8967,7 @@ static void vmx_preemption_timer_zero_test(void)
 	u32 reason;
 
 	if (!(ctrl_pin_rev.clr & PIN_PREEMPT)) {
-		report_skip("'Activate VMX-preemption timer' not supported");
+		report_skip("%s :\"Activate VMX-preemption timer\" pin control not supported", __func__);
 		return;
 	}
 
@@ -9082,7 +9082,7 @@ static void vmx_preemption_timer_tf_test(void)
 	int i;
 
 	if (!(ctrl_pin_rev.clr & PIN_PREEMPT)) {
-		report_skip("'Activate VMX-preemption timer' not supported");
+		report_skip("%s :\"Activate VMX-preemption timer\" pin control not supported", __func__);
 		return;
 	}
 
@@ -9173,7 +9173,7 @@ static void vmx_preemption_timer_expiry_test(void)
 	u32 reason;
 
 	if (!(ctrl_pin_rev.clr & PIN_PREEMPT)) {
-		report_skip("'Activate VMX-preemption timer' not supported");
+		report_skip("%s :\"Activate VMX-preemption timer\" pin control not supported", __func__);
 		return;
 	}
 
@@ -9481,7 +9481,7 @@ static void vmx_eoi_bitmap_ioapic_scan_test_guest(void)
 static void vmx_eoi_bitmap_ioapic_scan_test(void)
 {
 	if (!cpu_has_apicv() || (cpu_count() < 2)) {
-		report_skip(__func__);
+		report_skip("%s :Not all required APICv bits supported or CPU count < 2", __func__);
 		return;
 	}
 
@@ -9526,7 +9526,7 @@ static void vmx_hlt_with_rvi_guest(void)
 static void vmx_hlt_with_rvi_test(void)
 {
 	if (!cpu_has_apicv()) {
-		report_skip(__func__);
+		report_skip("%s :Not all required APICv bits supported", __func__);
 		return;
 	}
 
@@ -9584,13 +9584,13 @@ static void vmx_apic_passthrough_guest(void)
 static void vmx_apic_passthrough(bool set_irq_line_from_thread)
 {
 	if (set_irq_line_from_thread && (cpu_count() < 2)) {
-		report_skip(__func__);
+		report_skip("%s :CPU count < 2", __func__);
 		return;
 	}
 
 	/* Test device is required for generating IRQs */
 	if (!test_device_enabled()) {
-		report_skip(__func__);
+		report_skip("%s :No test device enabled", __func__);
 		return;
 	}
 	u64 cpu_ctrl_0 = CPU_SECONDARY;
@@ -9771,7 +9771,7 @@ static void vmx_init_signal_test(void)
 	struct vmcs *test_vmcs;
 
 	if (cpu_count() < 2) {
-		report_skip(__func__);
+		report_skip("%s :CPU count < 2", __func__);
 		return;
 	}
 
@@ -9970,12 +9970,12 @@ static void sipi_test_ap_thread(void *data)
 static void vmx_sipi_signal_test(void)
 {
 	if (!(rdmsr(MSR_IA32_VMX_MISC) & MSR_IA32_VMX_MISC_ACTIVITY_WAIT_SIPI)) {
-		printf("\tACTIVITY_WAIT_SIPI state is not supported.\n");
+		report_skip("\t\"ACTIVITY_WAIT_SIPI state\" not supported");
 		return;
 	}
 
 	if (cpu_count() < 2) {
-		report_skip(__func__);
+		report_skip("%s :CPU count < 2", __func__);
 		return;
 	}
 
@@ -10271,18 +10271,18 @@ static void vmx_vmcs_shadow_test(void)
 	struct vmcs *shadow;
 
 	if (!(ctrl_cpu_rev[0].clr & CPU_SECONDARY)) {
-		printf("\t'Activate secondary controls' not supported.\n");
+		report_skip("\t\"Activate secondary controls\" not supported");
 		return;
 	}
 
 	if (!(ctrl_cpu_rev[1].clr & CPU_SHADOW_VMCS)) {
-		printf("\t'VMCS shadowing' not supported.\n");
+		report_skip("\t\"VMCS shadowing\" not supported");
 		return;
 	}
 
 	if (!(rdmsr(MSR_IA32_VMX_MISC) &
 	      MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS)) {
-		printf("\tVMWRITE can't modify VM-exit information fields.\n");
+		report_skip("\tVMWRITE can't modify VM-exit information fields.");
 		return;
 	}
 
@@ -10509,7 +10509,7 @@ static void atomic_switch_msrs_test(int count)
 	 * available with the "TSC flag" and used to populate the MSR lists.
 	 */
 	if (!(cpuid(1).d & (1 << 4))) {
-		report_skip(__func__);
+		report_skip("%s :\"Time Stamp Counter\" not supported", __func__);
 		return;
 	}
 
-- 
2.31.1


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

* [kvm-unit-tests PATCH 2/4] x86: Use helpers to fetch supported perf capabilities
  2022-07-11  4:18 [kvm-unit-tests PATCH 0/4] Fixup and cleanup to pmu test applications Yang Weijiang
  2022-07-11  4:18 ` [kvm-unit-tests PATCH 1/4] x86: Use report_skip to print messages when tests are skipped Yang Weijiang
@ 2022-07-11  4:18 ` Yang Weijiang
  2022-07-21 21:21   ` Sean Christopherson
  2022-07-11  4:18 ` [kvm-unit-tests PATCH 3/4] x86: Skip perf related tests when platform cannot support Yang Weijiang
  2022-07-11  4:18 ` [kvm-unit-tests PATCH 4/4] x86: Check platform pmu capabilities before run lbr tests Yang Weijiang
  3 siblings, 1 reply; 7+ messages in thread
From: Yang Weijiang @ 2022-07-11  4:18 UTC (permalink / raw)
  To: seanjc, pbonzini, kvm; +Cc: Yang Weijiang

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(-)

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


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

* [kvm-unit-tests PATCH 3/4] x86: Skip perf related tests when platform cannot support
  2022-07-11  4:18 [kvm-unit-tests PATCH 0/4] Fixup and cleanup to pmu test applications Yang Weijiang
  2022-07-11  4:18 ` [kvm-unit-tests PATCH 1/4] x86: Use report_skip to print messages when tests are skipped Yang Weijiang
  2022-07-11  4:18 ` [kvm-unit-tests PATCH 2/4] x86: Use helpers to fetch supported perf capabilities Yang Weijiang
@ 2022-07-11  4:18 ` Yang Weijiang
  2022-07-11  4:18 ` [kvm-unit-tests PATCH 4/4] x86: Check platform pmu capabilities before run lbr tests Yang Weijiang
  3 siblings, 0 replies; 7+ messages in thread
From: Yang Weijiang @ 2022-07-11  4:18 UTC (permalink / raw)
  To: seanjc, pbonzini, kvm; +Cc: Yang Weijiang

Add helpers to check whether MSR_CORE_PERF_GLOBAL_CTRL and rdpmc are
supported in KVM. When pmu is disabled with enable_pmu=0, reading
MSR_CORE_PERF_GLOBAL_CTRL or executing rdpmc leads to #GP, so skip
related tests in this case to avoid test failure.

Opportunistically hoist mwait support check function as helper and
change related code.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 lib/x86/processor.h | 15 +++++++++++++++
 x86/vmx_tests.c     | 21 +++++++++++++--------
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index d071aba..b772cf3 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -744,4 +744,19 @@ static inline u8 pmu_fixed_counter_width(void)
 	else
 		return 0;
 }
+
+static inline bool cpu_has_perf_global_ctrl(void)
+{
+	return pmu_version() > 1;
+}
+
+static inline bool cpu_has_pmu(void)
+{
+	return !!pmu_version();
+}
+
+static inline bool cpu_has_mwait(void)
+{
+	return this_cpu_has(X86_FEATURE_MWAIT);
+}
 #endif
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index d5868a3..3afc8b8 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -847,11 +847,6 @@ u64 cr3;
 
 typedef bool (*supported_fn)(void);
 
-static bool monitor_supported(void)
-{
-	return this_cpu_has(X86_FEATURE_MWAIT);
-}
-
 struct insn_table {
 	const char *name;
 	u32 flag;
@@ -880,8 +875,8 @@ static struct insn_table insn_table[] = {
 	{"HLT",  CPU_HLT, insn_hlt, INSN_CPU0, 12, 0, 0, 0},
 	{"INVLPG", CPU_INVLPG, insn_invlpg, INSN_CPU0, 14,
 		0x12345678, 0, FIELD_EXIT_QUAL},
-	{"MWAIT", CPU_MWAIT, insn_mwait, INSN_CPU0, 36, 0, 0, 0, &monitor_supported},
-	{"RDPMC", CPU_RDPMC, insn_rdpmc, INSN_CPU0, 15, 0, 0, 0},
+	{"MWAIT", CPU_MWAIT, insn_mwait, INSN_CPU0, 36, 0, 0, 0, &cpu_has_mwait},
+	{"RDPMC", CPU_RDPMC, insn_rdpmc, INSN_CPU0, 15, 0, 0, 0, &cpu_has_pmu},
 	{"RDTSC", CPU_RDTSC, insn_rdtsc, INSN_CPU0, 16, 0, 0, 0},
 	{"CR3 load", CPU_CR3_LOAD, insn_cr3_load, INSN_CPU0, 28, 0x3, 0,
 		FIELD_EXIT_QUAL},
@@ -891,7 +886,7 @@ static struct insn_table insn_table[] = {
 		FIELD_EXIT_QUAL},
 	{"CR8 store", CPU_CR8_STORE, insn_cr8_store, INSN_CPU0, 28, 0x18, 0,
 		FIELD_EXIT_QUAL},
-	{"MONITOR", CPU_MONITOR, insn_monitor, INSN_CPU0, 39, 0, 0, 0, &monitor_supported},
+	{"MONITOR", CPU_MONITOR, insn_monitor, INSN_CPU0, 39, 0, 0, 0, &cpu_has_mwait},
 	{"PAUSE", CPU_PAUSE, insn_pause, INSN_CPU0, 40, 0, 0, 0},
 	// Flags for Secondary Processor-Based VM-Execution Controls
 	{"WBINVD", CPU_WBINVD, insn_wbinvd, INSN_CPU1, 54, 0, 0, 0},
@@ -7490,6 +7485,11 @@ static void test_perf_global_ctrl(u32 nr, const char *name, u32 ctrl_nr,
 
 static void test_load_host_perf_global_ctrl(void)
 {
+	if (!cpu_has_perf_global_ctrl()) {
+		report_skip("%s :IA32_PERF_GLOBAL_CTRL MSR not supported", __func__);
+		return;
+	}
+
 	if (!(ctrl_exit_rev.clr & EXI_LOAD_PERF)) {
 		report_skip("%s :\"Load IA32_PERF_GLOBAL_CTRL\" exit control not supported", __func__);
 		return;
@@ -7502,6 +7502,11 @@ static void test_load_host_perf_global_ctrl(void)
 
 static void test_load_guest_perf_global_ctrl(void)
 {
+	if (!cpu_has_perf_global_ctrl()) {
+		report_skip("%s :IA32_PERF_GLOBAL_CTRL MSR not supported", __func__);
+		return;
+	}
+
 	if (!(ctrl_enter_rev.clr & ENT_LOAD_PERF)) {
 		report_skip("%s :\"Load IA32_PERF_GLOBAL_CTRL\" entry control not supported", __func__);
 		return;
-- 
2.31.1


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

* [kvm-unit-tests PATCH 4/4] x86: Check platform pmu capabilities before run lbr tests
  2022-07-11  4:18 [kvm-unit-tests PATCH 0/4] Fixup and cleanup to pmu test applications Yang Weijiang
                   ` (2 preceding siblings ...)
  2022-07-11  4:18 ` [kvm-unit-tests PATCH 3/4] x86: Skip perf related tests when platform cannot support Yang Weijiang
@ 2022-07-11  4:18 ` Yang Weijiang
  3 siblings, 0 replies; 7+ messages in thread
From: Yang Weijiang @ 2022-07-11  4:18 UTC (permalink / raw)
  To: seanjc, pbonzini, kvm; +Cc: Yang Weijiang

Use new helper to check whether pmu is available and Perfmon/Debug
capbilities are supported before read MSR_IA32_PERF_CAPABILITIES to
avoid test failure. The issue can be captured when enable_pmu=0.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 lib/x86/processor.h |  1 +
 x86/pmu_lbr.c       | 33 +++++++++++++--------------------
 2 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index b772cf3..c192a25 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -146,6 +146,7 @@ static inline bool is_intel(void)
  */
 #define	X86_FEATURE_MWAIT		(CPUID(0x1, 0, ECX, 3))
 #define	X86_FEATURE_VMX			(CPUID(0x1, 0, ECX, 5))
+#define	X86_FEATURE_PDCM		(CPUID(0x1, 0, ECX, 15))
 #define	X86_FEATURE_PCID		(CPUID(0x1, 0, ECX, 17))
 #define	X86_FEATURE_MOVBE		(CPUID(0x1, 0, ECX, 22))
 #define	X86_FEATURE_TSC_DEADLINE_TIMER	(CPUID(0x1, 0, ECX, 24))
diff --git a/x86/pmu_lbr.c b/x86/pmu_lbr.c
index 688634d..22c8c69 100644
--- a/x86/pmu_lbr.c
+++ b/x86/pmu_lbr.c
@@ -15,6 +15,7 @@
 #define MSR_LBR_SELECT		0x000001c8
 
 volatile int count;
+u32 lbr_from, lbr_to;
 
 static noinline int compute_flag(int i)
 {
@@ -38,18 +39,6 @@ static noinline int lbr_test(void)
 	return 0;
 }
 
-union cpuid10_eax {
-	struct {
-		unsigned int version_id:8;
-		unsigned int num_counters:8;
-		unsigned int bit_width:8;
-		unsigned int mask_length:8;
-	} split;
-	unsigned int full;
-} eax;
-
-u32 lbr_from, lbr_to;
-
 static void init_lbr(void *index)
 {
 	wrmsr(lbr_from + *(int *) index, 0);
@@ -63,7 +52,6 @@ static bool test_init_lbr_from_exception(u64 index)
 
 int main(int ac, char **av)
 {
-	struct cpuid id = cpuid(10);
 	u64 perf_cap;
 	int max, i;
 
@@ -74,19 +62,24 @@ int main(int ac, char **av)
 		return 0;
 	}
 
-	perf_cap = rdmsr(MSR_IA32_PERF_CAPABILITIES);
-	eax.full = id.a;
+	if (!cpu_has_pmu()) {
+		report_skip("No pmu is detected!");
+		return report_summary();
+	}
 
-	if (!eax.split.version_id) {
-		printf("No pmu is detected!\n");
+	if (!this_cpu_has(X86_FEATURE_PDCM)) {
+		report_skip("Perfmon/Debug Capabilities MSR isn't supported.");
 		return report_summary();
 	}
+
+	perf_cap = rdmsr(MSR_IA32_PERF_CAPABILITIES);
+
 	if (!(perf_cap & PMU_CAP_LBR_FMT)) {
-		printf("No LBR is detected!\n");
+		report_skip("(Architectural) LBR is not supported.");
 		return report_summary();
 	}
 
-	printf("PMU version:		 %d\n", eax.split.version_id);
+	printf("PMU version:		 %d\n", pmu_version());
 	printf("LBR version:		 %ld\n", perf_cap & PMU_CAP_LBR_FMT);
 
 	/* Look for LBR from and to MSRs */
@@ -98,7 +91,7 @@ int main(int ac, char **av)
 	}
 
 	if (test_init_lbr_from_exception(0)) {
-		printf("LBR on this platform is not supported!\n");
+		report_skip("LBR on this platform is not supported!");
 		return report_summary();
 	}
 
-- 
2.31.1


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

* Re: [kvm-unit-tests PATCH 2/4] x86: Use helpers to fetch supported perf capabilities
  2022-07-11  4:18 ` [kvm-unit-tests PATCH 2/4] x86: Use helpers to fetch supported perf capabilities Yang Weijiang
@ 2022-07-21 21:21   ` Sean Christopherson
  2022-07-22  0:58     ` Yang, Weijiang
  0 siblings, 1 reply; 7+ messages in thread
From: Sean Christopherson @ 2022-07-21 21:21 UTC (permalink / raw)
  To: Yang Weijiang; +Cc: pbonzini, kvm

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).

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

* Re: [kvm-unit-tests PATCH 2/4] x86: Use helpers to fetch supported perf capabilities
  2022-07-21 21:21   ` Sean Christopherson
@ 2022-07-22  0:58     ` Yang, Weijiang
  0 siblings, 0 replies; 7+ messages in thread
From: Yang, Weijiang @ 2022-07-22  0:58 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: pbonzini, kvm


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.


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

end of thread, other threads:[~2022-07-22  0:58 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-11  4:18 [kvm-unit-tests PATCH 0/4] Fixup and cleanup to pmu test applications Yang Weijiang
2022-07-11  4:18 ` [kvm-unit-tests PATCH 1/4] x86: Use report_skip to print messages when tests are skipped Yang Weijiang
2022-07-11  4:18 ` [kvm-unit-tests PATCH 2/4] x86: Use helpers to fetch supported perf capabilities Yang Weijiang
2022-07-21 21:21   ` Sean Christopherson
2022-07-22  0:58     ` Yang, Weijiang
2022-07-11  4:18 ` [kvm-unit-tests PATCH 3/4] x86: Skip perf related tests when platform cannot support Yang Weijiang
2022-07-11  4:18 ` [kvm-unit-tests PATCH 4/4] x86: Check platform pmu capabilities before run lbr tests Yang Weijiang

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.