Skip to content

Commit 8752e2b

Browse files
committed
KVM: selftests: Only validate counts for hardware-supported arch events
In the Intel PMU counters test, only validate the counts for architectural events that are supported in hardware. If an arch event isn't supported, the event selector may enable a completely different event, and thus the logic for the expected count is bogus. This fixes test failures on pre-Icelake systems due to the encoding for the architectural Top-Down Slots event corresponding to something else (at least on the Skylake family of CPUs). Note, validation relies on *hardware* support, not KVM support and not guest support. Architectural events are all about enumerating the event selector encoding; lack of enumeration for an architectural event doesn't mean the event itself is unsupported, i.e. the event should still count as expected even if KVM and/or guest CPUID doesn't enumerate the event as being "architectural". Note #2, it's desirable to _program_ the architectural event encoding even if hardware doesn't support the event. The count can't be validated when the event is fully enabled, but KVM should still let the guest program the event selector, and the PMC shouldn't count if the event is disabled. Fixes: 4f1bd6b ("KVM: selftests: Test Intel PMU architectural events on gp counters") Reported-by: kernel test robot <oliver.sang@intel.com> Closes: https://lore.kernel.org/oe-lkp/202501141009.30c629b4-lkp@intel.com Debugged-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Link: https://lore.kernel.org/r/20250117234204.2600624-3-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 933178d commit 8752e2b

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

tools/testing/selftests/kvm/x86/pmu_counters_test.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
/* Total number of instructions retired within the measured section. */
3030
#define NUM_INSNS_RETIRED (NUM_LOOPS * NUM_INSNS_PER_LOOP + NUM_EXTRA_INSNS)
3131

32+
/* Track which architectural events are supported by hardware. */
33+
static uint32_t hardware_pmu_arch_events;
3234

3335
static uint8_t kvm_pmu_version;
3436
static bool kvm_has_perf_caps;
@@ -89,6 +91,7 @@ static struct kvm_vm *pmu_vm_create_with_one_vcpu(struct kvm_vcpu **vcpu,
8991

9092
vm = vm_create_with_one_vcpu(vcpu, guest_code);
9193
sync_global_to_guest(vm, kvm_pmu_version);
94+
sync_global_to_guest(vm, hardware_pmu_arch_events);
9295

9396
/*
9497
* Set PERF_CAPABILITIES before PMU version as KVM disallows enabling
@@ -152,7 +155,7 @@ static void guest_assert_event_count(uint8_t idx,
152155
uint64_t count;
153156

154157
count = _rdpmc(pmc);
155-
if (!this_pmu_has(event))
158+
if (!(hardware_pmu_arch_events & BIT(idx)))
156159
goto sanity_checks;
157160

158161
switch (idx) {
@@ -560,7 +563,7 @@ static void test_fixed_counters(uint8_t pmu_version, uint64_t perf_capabilities,
560563

561564
static void test_intel_counters(void)
562565
{
563-
uint8_t nr_arch_events = kvm_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH);
566+
uint8_t nr_arch_events = this_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH);
564567
uint8_t nr_fixed_counters = kvm_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS);
565568
uint8_t nr_gp_counters = kvm_cpu_property(X86_PROPERTY_PMU_NR_GP_COUNTERS);
566569
uint8_t pmu_version = kvm_cpu_property(X86_PROPERTY_PMU_VERSION);
@@ -582,18 +585,26 @@ static void test_intel_counters(void)
582585

583586
/*
584587
* Detect the existence of events that aren't supported by selftests.
585-
* This will (obviously) fail any time the kernel adds support for a
586-
* new event, but it's worth paying that price to keep the test fresh.
588+
* This will (obviously) fail any time hardware adds support for a new
589+
* event, but it's worth paying that price to keep the test fresh.
587590
*/
588591
TEST_ASSERT(nr_arch_events <= NR_INTEL_ARCH_EVENTS,
589592
"New architectural event(s) detected; please update this test (length = %u, mask = %x)",
590-
nr_arch_events, kvm_cpu_property(X86_PROPERTY_PMU_EVENTS_MASK));
593+
nr_arch_events, this_cpu_property(X86_PROPERTY_PMU_EVENTS_MASK));
591594

592595
/*
593-
* Force iterating over known arch events regardless of whether or not
594-
* KVM/hardware supports a given event.
596+
* Iterate over known arch events irrespective of KVM/hardware support
597+
* to verify that KVM doesn't reject programming of events just because
598+
* the *architectural* encoding is unsupported. Track which events are
599+
* supported in hardware; the guest side will validate supported events
600+
* count correctly, even if *enumeration* of the event is unsupported
601+
* by KVM and/or isn't exposed to the guest.
595602
*/
596603
nr_arch_events = max_t(typeof(nr_arch_events), nr_arch_events, NR_INTEL_ARCH_EVENTS);
604+
for (i = 0; i < nr_arch_events; i++) {
605+
if (this_pmu_has(intel_event_to_feature(i).gp_event))
606+
hardware_pmu_arch_events |= BIT(i);
607+
}
597608

598609
for (v = 0; v <= max_pmu_version; v++) {
599610
for (i = 0; i < ARRAY_SIZE(perf_caps); i++) {

0 commit comments

Comments
 (0)