From: Jinrong Liang <ljr.kernel@gmail.com>
To: Sean Christopherson <seanjc@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>, Like Xu <likexu@tencent.com>,
David Matlack <dmatlack@google.com>,
Aaron Lewis <aaronlewis@google.com>,
Vitaly Kuznetsov <vkuznets@redhat.com>,
Wanpeng Li <wanpengli@tencent.com>,
Jinrong Liang <cloudliang@tencent.com>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v3 03/11] KVM: selftests: Test Intel PMU architectural events on gp counters
Date: Mon, 14 Aug 2023 19:51:00 +0800 [thread overview]
Message-ID: <20230814115108.45741-4-cloudliang@tencent.com> (raw)
In-Reply-To: <20230814115108.45741-1-cloudliang@tencent.com>
From: Jinrong Liang <cloudliang@tencent.com>
Add test cases to check if different Architectural events are available
after it's marked as unavailable via CPUID. It covers vPMU event filtering
logic based on Intel CPUID, which is a complement to pmu_event_filter.
According to Intel SDM, the number of architectural events is reported
through CPUID.0AH:EAX[31:24] and the architectural event x is supported
if EBX[x]=0 && EAX[31:24]>x.
Co-developed-by: Like Xu <likexu@tencent.com>
Signed-off-by: Like Xu <likexu@tencent.com>
Signed-off-by: Jinrong Liang <cloudliang@tencent.com>
---
tools/testing/selftests/kvm/Makefile | 1 +
.../kvm/x86_64/pmu_basic_functionality_test.c | 158 ++++++++++++++++++
2 files changed, 159 insertions(+)
create mode 100644 tools/testing/selftests/kvm/x86_64/pmu_basic_functionality_test.c
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 77026907968f..965a36562ef8 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -80,6 +80,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/mmio_warning_test
TEST_GEN_PROGS_x86_64 += x86_64/monitor_mwait_test
TEST_GEN_PROGS_x86_64 += x86_64/nested_exceptions_test
TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test
+TEST_GEN_PROGS_x86_64 += x86_64/pmu_basic_functionality_test
TEST_GEN_PROGS_x86_64 += x86_64/pmu_event_filter_test
TEST_GEN_PROGS_x86_64 += x86_64/set_boot_cpu_id
TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test
diff --git a/tools/testing/selftests/kvm/x86_64/pmu_basic_functionality_test.c b/tools/testing/selftests/kvm/x86_64/pmu_basic_functionality_test.c
new file mode 100644
index 000000000000..c04eb0bdf69f
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86_64/pmu_basic_functionality_test.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test the consistency of the PMU's CPUID and its features
+ *
+ * Copyright (C) 2023, Tencent, Inc.
+ *
+ * Check that the VM's PMU behaviour is consistent with the
+ * VM CPUID definition.
+ */
+
+#define _GNU_SOURCE /* for program_invocation_short_name */
+#include <x86intrin.h>
+
+#include "pmu.h"
+
+/* Guest payload for any performance counter counting */
+#define NUM_BRANCHES 10
+
+static struct kvm_vm *pmu_vm_create_with_one_vcpu(struct kvm_vcpu **vcpu,
+ void *guest_code)
+{
+ struct kvm_vm *vm;
+
+ vm = vm_create_with_one_vcpu(vcpu, guest_code);
+ vm_init_descriptor_tables(vm);
+ vcpu_init_descriptor_tables(*vcpu);
+
+ return vm;
+}
+
+static uint64_t run_vcpu(struct kvm_vcpu *vcpu, uint64_t *ucall_arg)
+{
+ struct ucall uc;
+
+ vcpu_run(vcpu);
+ switch (get_ucall(vcpu, &uc)) {
+ case UCALL_SYNC:
+ *ucall_arg = uc.args[1];
+ break;
+ case UCALL_DONE:
+ break;
+ default:
+ TEST_FAIL("Unexpected ucall: %lu", uc.cmd);
+ }
+ return uc.cmd;
+}
+
+static void guest_measure_loop(uint64_t event_code)
+{
+ uint32_t nr_gp_counters = this_cpu_property(X86_PROPERTY_PMU_NR_GP_COUNTERS);
+ uint32_t pmu_version = this_cpu_property(X86_PROPERTY_PMU_VERSION);
+ uint32_t counter_msr;
+ unsigned int i;
+
+ if (rdmsr(MSR_IA32_PERF_CAPABILITIES) & PMU_CAP_FW_WRITES)
+ counter_msr = MSR_IA32_PMC0;
+ else
+ counter_msr = MSR_IA32_PERFCTR0;
+
+ for (i = 0; i < nr_gp_counters; i++) {
+ wrmsr(counter_msr + i, 0);
+ wrmsr(MSR_P6_EVNTSEL0 + i, ARCH_PERFMON_EVENTSEL_OS |
+ ARCH_PERFMON_EVENTSEL_ENABLE | event_code);
+
+ if (pmu_version > 1) {
+ wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, BIT_ULL(i));
+ __asm__ __volatile__("loop ." : "+c"((int){NUM_BRANCHES}));
+ wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+ GUEST_SYNC(_rdpmc(i));
+ } else {
+ __asm__ __volatile__("loop ." : "+c"((int){NUM_BRANCHES}));
+ GUEST_SYNC(_rdpmc(i));
+ }
+ }
+
+ GUEST_DONE();
+}
+
+static void test_arch_events_cpuid(struct kvm_vcpu *vcpu,
+ uint8_t arch_events_bitmap_size,
+ uint8_t arch_events_unavailable_mask,
+ uint8_t idx)
+{
+ uint64_t counter_val = 0;
+ bool is_supported;
+
+ vcpu_set_cpuid_property(vcpu, X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH,
+ arch_events_bitmap_size);
+ vcpu_set_cpuid_property(vcpu, X86_PROPERTY_PMU_EVENTS_MASK,
+ arch_events_unavailable_mask);
+
+ is_supported = arch_event_is_supported(vcpu, idx);
+ vcpu_args_set(vcpu, 1, intel_arch_events[idx]);
+
+ while (run_vcpu(vcpu, &counter_val) != UCALL_DONE)
+ TEST_ASSERT_EQ(is_supported, !!counter_val);
+}
+
+static void intel_check_arch_event_is_unavl(uint8_t idx)
+{
+ uint8_t eax_evt_vec, ebx_unavl_mask, i, j;
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm;
+
+ /*
+ * A brute force iteration of all combinations of values is likely to
+ * exhaust the limit of the single-threaded thread fd nums, so it's
+ * tested here by iterating through all valid values on a single bit.
+ */
+ for (i = 0; i < ARRAY_SIZE(intel_arch_events); i++) {
+ eax_evt_vec = BIT_ULL(i);
+ for (j = 0; j < ARRAY_SIZE(intel_arch_events); j++) {
+ ebx_unavl_mask = BIT_ULL(j);
+ vm = pmu_vm_create_with_one_vcpu(&vcpu,
+ guest_measure_loop);
+ test_arch_events_cpuid(vcpu, eax_evt_vec,
+ ebx_unavl_mask, idx);
+
+ kvm_vm_free(vm);
+ }
+ }
+}
+
+static void intel_test_arch_events(void)
+{
+ uint8_t idx;
+
+ for (idx = 0; idx < ARRAY_SIZE(intel_arch_events); idx++) {
+ /*
+ * Given the stability of performance event recurrence,
+ * only these arch events are currently being tested:
+ *
+ * - Core cycle event (idx = 0)
+ * - Instruction retired event (idx = 1)
+ * - Reference cycles event (idx = 2)
+ * - Branch instruction retired event (idx = 5)
+ */
+ if (idx > INTEL_ARCH_INSTRUCTIONS_RETIRED &&
+ idx != INTEL_ARCH_BRANCHES_RETIRED)
+ continue;
+
+ intel_check_arch_event_is_unavl(idx);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ TEST_REQUIRE(get_kvm_param_bool("enable_pmu"));
+
+ TEST_REQUIRE(host_cpu_is_intel);
+ TEST_REQUIRE(kvm_cpu_has_p(X86_PROPERTY_PMU_VERSION));
+ TEST_REQUIRE(kvm_cpu_property(X86_PROPERTY_PMU_VERSION) > 0);
+ TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_PDCM));
+
+ intel_test_arch_events();
+
+ return 0;
+}
--
2.39.3
next prev parent reply other threads:[~2023-08-14 11:52 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-14 11:50 [PATCH v3 00/11] KVM: selftests: Test the consistency of the PMU's CPUID and its features Jinrong Liang
2023-08-14 11:50 ` [PATCH v3 01/11] KVM: selftests: Add vcpu_set_cpuid_property() to set properties Jinrong Liang
2023-08-14 11:50 ` [PATCH v3 02/11] KVM: selftests: Add pmu.h for PMU events and common masks Jinrong Liang
2023-08-17 22:32 ` Sean Christopherson
2023-08-21 8:56 ` Like Xu
2023-08-21 9:07 ` Jinrong Liang
2023-08-14 11:51 ` Jinrong Liang [this message]
2023-08-17 22:46 ` [PATCH v3 03/11] KVM: selftests: Test Intel PMU architectural events on gp counters Sean Christopherson
2023-08-17 22:54 ` Sean Christopherson
2023-08-21 11:45 ` Jinrong Liang
2023-08-14 11:51 ` [PATCH v3 04/11] KVM: selftests: Test Intel PMU architectural events on fixed counters Jinrong Liang
2023-08-17 22:56 ` Sean Christopherson
2023-08-14 11:51 ` [PATCH v3 05/11] KVM: selftests: Test consistency of CPUID with num of gp counters Jinrong Liang
2023-08-17 23:00 ` Sean Christopherson
2023-08-17 23:18 ` Sean Christopherson
2023-08-14 11:51 ` [PATCH v3 06/11] KVM: selftests: Test consistency of CPUID with num of fixed counters Jinrong Liang
2023-08-17 23:04 ` Sean Christopherson
2023-08-14 11:51 ` [PATCH v3 07/11] KVM: selftests: Test Intel supported fixed counters bit mask Jinrong Liang
2023-08-17 23:19 ` Sean Christopherson
2023-08-14 11:51 ` [PATCH v3 08/11] KVM: selftests: Test consistency of PMU MSRs with Intel PMU version Jinrong Liang
2023-08-17 23:21 ` Sean Christopherson
2023-08-14 11:51 ` [PATCH v3 09/11] KVM: selftests: Add x86 feature and properties for AMD PMU in processor.h Jinrong Liang
2023-08-17 23:26 ` Sean Christopherson
2023-08-14 11:51 ` [PATCH v3 10/11] KVM: selftests: Test AMD PMU events on legacy four performance counters Jinrong Liang
2023-08-14 11:51 ` [PATCH v3 11/11] KVM: selftests: Test AMD Guest PerfMonV2 Jinrong Liang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230814115108.45741-4-cloudliang@tencent.com \
--to=ljr.kernel@gmail.com \
--cc=aaronlewis@google.com \
--cc=cloudliang@tencent.com \
--cc=dmatlack@google.com \
--cc=kvm@vger.kernel.org \
--cc=likexu@tencent.com \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=vkuznets@redhat.com \
--cc=wanpengli@tencent.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.