645 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2023, Tencent, Inc.4 */5#include <x86intrin.h>6 7#include "pmu.h"8#include "processor.h"9 10/* Number of iterations of the loop for the guest measurement payload. */11#define NUM_LOOPS 1012 13/* Each iteration of the loop retires one branch instruction. */14#define NUM_BRANCH_INSNS_RETIRED (NUM_LOOPS)15 16/*17 * Number of instructions in each loop. 1 CLFLUSH/CLFLUSHOPT/NOP, 1 MFENCE,18 * 1 LOOP.19 */20#define NUM_INSNS_PER_LOOP 321 22/*23 * Number of "extra" instructions that will be counted, i.e. the number of24 * instructions that are needed to set up the loop and then disable the25 * counter. 2 MOV, 2 XOR, 1 WRMSR.26 */27#define NUM_EXTRA_INSNS 528 29/* Total number of instructions retired within the measured section. */30#define NUM_INSNS_RETIRED (NUM_LOOPS * NUM_INSNS_PER_LOOP + NUM_EXTRA_INSNS)31 32 33static uint8_t kvm_pmu_version;34static bool kvm_has_perf_caps;35 36static struct kvm_vm *pmu_vm_create_with_one_vcpu(struct kvm_vcpu **vcpu,37 void *guest_code,38 uint8_t pmu_version,39 uint64_t perf_capabilities)40{41 struct kvm_vm *vm;42 43 vm = vm_create_with_one_vcpu(vcpu, guest_code);44 sync_global_to_guest(vm, kvm_pmu_version);45 46 /*47 * Set PERF_CAPABILITIES before PMU version as KVM disallows enabling48 * features via PERF_CAPABILITIES if the guest doesn't have a vPMU.49 */50 if (kvm_has_perf_caps)51 vcpu_set_msr(*vcpu, MSR_IA32_PERF_CAPABILITIES, perf_capabilities);52 53 vcpu_set_cpuid_property(*vcpu, X86_PROPERTY_PMU_VERSION, pmu_version);54 return vm;55}56 57static void run_vcpu(struct kvm_vcpu *vcpu)58{59 struct ucall uc;60 61 do {62 vcpu_run(vcpu);63 switch (get_ucall(vcpu, &uc)) {64 case UCALL_SYNC:65 break;66 case UCALL_ABORT:67 REPORT_GUEST_ASSERT(uc);68 break;69 case UCALL_PRINTF:70 pr_info("%s", uc.buffer);71 break;72 case UCALL_DONE:73 break;74 default:75 TEST_FAIL("Unexpected ucall: %lu", uc.cmd);76 }77 } while (uc.cmd != UCALL_DONE);78}79 80static uint8_t guest_get_pmu_version(void)81{82 /*83 * Return the effective PMU version, i.e. the minimum between what KVM84 * supports and what is enumerated to the guest. The host deliberately85 * advertises a PMU version to the guest beyond what is actually86 * supported by KVM to verify KVM doesn't freak out and do something87 * bizarre with an architecturally valid, but unsupported, version.88 */89 return min_t(uint8_t, kvm_pmu_version, this_cpu_property(X86_PROPERTY_PMU_VERSION));90}91 92/*93 * If an architectural event is supported and guaranteed to generate at least94 * one "hit, assert that its count is non-zero. If an event isn't supported or95 * the test can't guarantee the associated action will occur, then all bets are96 * off regarding the count, i.e. no checks can be done.97 *98 * Sanity check that in all cases, the event doesn't count when it's disabled,99 * and that KVM correctly emulates the write of an arbitrary value.100 */101static void guest_assert_event_count(uint8_t idx,102 struct kvm_x86_pmu_feature event,103 uint32_t pmc, uint32_t pmc_msr)104{105 uint64_t count;106 107 count = _rdpmc(pmc);108 if (!this_pmu_has(event))109 goto sanity_checks;110 111 switch (idx) {112 case INTEL_ARCH_INSTRUCTIONS_RETIRED_INDEX:113 GUEST_ASSERT_EQ(count, NUM_INSNS_RETIRED);114 break;115 case INTEL_ARCH_BRANCHES_RETIRED_INDEX:116 GUEST_ASSERT_EQ(count, NUM_BRANCH_INSNS_RETIRED);117 break;118 case INTEL_ARCH_LLC_REFERENCES_INDEX:119 case INTEL_ARCH_LLC_MISSES_INDEX:120 if (!this_cpu_has(X86_FEATURE_CLFLUSHOPT) &&121 !this_cpu_has(X86_FEATURE_CLFLUSH))122 break;123 fallthrough;124 case INTEL_ARCH_CPU_CYCLES_INDEX:125 case INTEL_ARCH_REFERENCE_CYCLES_INDEX:126 GUEST_ASSERT_NE(count, 0);127 break;128 case INTEL_ARCH_TOPDOWN_SLOTS_INDEX:129 GUEST_ASSERT(count >= NUM_INSNS_RETIRED);130 break;131 default:132 break;133 }134 135sanity_checks:136 __asm__ __volatile__("loop ." : "+c"((int){NUM_LOOPS}));137 GUEST_ASSERT_EQ(_rdpmc(pmc), count);138 139 wrmsr(pmc_msr, 0xdead);140 GUEST_ASSERT_EQ(_rdpmc(pmc), 0xdead);141}142 143/*144 * Enable and disable the PMC in a monolithic asm blob to ensure that the145 * compiler can't insert _any_ code into the measured sequence. Note, ECX146 * doesn't need to be clobbered as the input value, @pmc_msr, is restored147 * before the end of the sequence.148 *149 * If CLFUSH{,OPT} is supported, flush the cacheline containing (at least) the150 * CLFUSH{,OPT} instruction on each loop iteration to force LLC references and151 * misses, i.e. to allow testing that those events actually count.152 *153 * If forced emulation is enabled (and specified), force emulation on a subset154 * of the measured code to verify that KVM correctly emulates instructions and155 * branches retired events in conjunction with hardware also counting said156 * events.157 */158#define GUEST_MEASURE_EVENT(_msr, _value, clflush, FEP) \159do { \160 __asm__ __volatile__("wrmsr\n\t" \161 " mov $" __stringify(NUM_LOOPS) ", %%ecx\n\t" \162 "1:\n\t" \163 clflush "\n\t" \164 "mfence\n\t" \165 FEP "loop 1b\n\t" \166 FEP "mov %%edi, %%ecx\n\t" \167 FEP "xor %%eax, %%eax\n\t" \168 FEP "xor %%edx, %%edx\n\t" \169 "wrmsr\n\t" \170 :: "a"((uint32_t)_value), "d"(_value >> 32), \171 "c"(_msr), "D"(_msr) \172 ); \173} while (0)174 175#define GUEST_TEST_EVENT(_idx, _event, _pmc, _pmc_msr, _ctrl_msr, _value, FEP) \176do { \177 wrmsr(pmc_msr, 0); \178 \179 if (this_cpu_has(X86_FEATURE_CLFLUSHOPT)) \180 GUEST_MEASURE_EVENT(_ctrl_msr, _value, "clflushopt .", FEP); \181 else if (this_cpu_has(X86_FEATURE_CLFLUSH)) \182 GUEST_MEASURE_EVENT(_ctrl_msr, _value, "clflush .", FEP); \183 else \184 GUEST_MEASURE_EVENT(_ctrl_msr, _value, "nop", FEP); \185 \186 guest_assert_event_count(_idx, _event, _pmc, _pmc_msr); \187} while (0)188 189static void __guest_test_arch_event(uint8_t idx, struct kvm_x86_pmu_feature event,190 uint32_t pmc, uint32_t pmc_msr,191 uint32_t ctrl_msr, uint64_t ctrl_msr_value)192{193 GUEST_TEST_EVENT(idx, event, pmc, pmc_msr, ctrl_msr, ctrl_msr_value, "");194 195 if (is_forced_emulation_enabled)196 GUEST_TEST_EVENT(idx, event, pmc, pmc_msr, ctrl_msr, ctrl_msr_value, KVM_FEP);197}198 199#define X86_PMU_FEATURE_NULL \200({ \201 struct kvm_x86_pmu_feature feature = {}; \202 \203 feature; \204})205 206static bool pmu_is_null_feature(struct kvm_x86_pmu_feature event)207{208 return !(*(u64 *)&event);209}210 211static void guest_test_arch_event(uint8_t idx)212{213 const struct {214 struct kvm_x86_pmu_feature gp_event;215 struct kvm_x86_pmu_feature fixed_event;216 } intel_event_to_feature[] = {217 [INTEL_ARCH_CPU_CYCLES_INDEX] = { X86_PMU_FEATURE_CPU_CYCLES, X86_PMU_FEATURE_CPU_CYCLES_FIXED },218 [INTEL_ARCH_INSTRUCTIONS_RETIRED_INDEX] = { X86_PMU_FEATURE_INSNS_RETIRED, X86_PMU_FEATURE_INSNS_RETIRED_FIXED },219 /*220 * Note, the fixed counter for reference cycles is NOT the same221 * as the general purpose architectural event. The fixed counter222 * explicitly counts at the same frequency as the TSC, whereas223 * the GP event counts at a fixed, but uarch specific, frequency.224 * Bundle them here for simplicity.225 */226 [INTEL_ARCH_REFERENCE_CYCLES_INDEX] = { X86_PMU_FEATURE_REFERENCE_CYCLES, X86_PMU_FEATURE_REFERENCE_TSC_CYCLES_FIXED },227 [INTEL_ARCH_LLC_REFERENCES_INDEX] = { X86_PMU_FEATURE_LLC_REFERENCES, X86_PMU_FEATURE_NULL },228 [INTEL_ARCH_LLC_MISSES_INDEX] = { X86_PMU_FEATURE_LLC_MISSES, X86_PMU_FEATURE_NULL },229 [INTEL_ARCH_BRANCHES_RETIRED_INDEX] = { X86_PMU_FEATURE_BRANCH_INSNS_RETIRED, X86_PMU_FEATURE_NULL },230 [INTEL_ARCH_BRANCHES_MISPREDICTED_INDEX] = { X86_PMU_FEATURE_BRANCHES_MISPREDICTED, X86_PMU_FEATURE_NULL },231 [INTEL_ARCH_TOPDOWN_SLOTS_INDEX] = { X86_PMU_FEATURE_TOPDOWN_SLOTS, X86_PMU_FEATURE_TOPDOWN_SLOTS_FIXED },232 };233 234 uint32_t nr_gp_counters = this_cpu_property(X86_PROPERTY_PMU_NR_GP_COUNTERS);235 uint32_t pmu_version = guest_get_pmu_version();236 /* PERF_GLOBAL_CTRL exists only for Architectural PMU Version 2+. */237 bool guest_has_perf_global_ctrl = pmu_version >= 2;238 struct kvm_x86_pmu_feature gp_event, fixed_event;239 uint32_t base_pmc_msr;240 unsigned int i;241 242 /* The host side shouldn't invoke this without a guest PMU. */243 GUEST_ASSERT(pmu_version);244 245 if (this_cpu_has(X86_FEATURE_PDCM) &&246 rdmsr(MSR_IA32_PERF_CAPABILITIES) & PMU_CAP_FW_WRITES)247 base_pmc_msr = MSR_IA32_PMC0;248 else249 base_pmc_msr = MSR_IA32_PERFCTR0;250 251 gp_event = intel_event_to_feature[idx].gp_event;252 GUEST_ASSERT_EQ(idx, gp_event.f.bit);253 254 GUEST_ASSERT(nr_gp_counters);255 256 for (i = 0; i < nr_gp_counters; i++) {257 uint64_t eventsel = ARCH_PERFMON_EVENTSEL_OS |258 ARCH_PERFMON_EVENTSEL_ENABLE |259 intel_pmu_arch_events[idx];260 261 wrmsr(MSR_P6_EVNTSEL0 + i, 0);262 if (guest_has_perf_global_ctrl)263 wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, BIT_ULL(i));264 265 __guest_test_arch_event(idx, gp_event, i, base_pmc_msr + i,266 MSR_P6_EVNTSEL0 + i, eventsel);267 }268 269 if (!guest_has_perf_global_ctrl)270 return;271 272 fixed_event = intel_event_to_feature[idx].fixed_event;273 if (pmu_is_null_feature(fixed_event) || !this_pmu_has(fixed_event))274 return;275 276 i = fixed_event.f.bit;277 278 wrmsr(MSR_CORE_PERF_FIXED_CTR_CTRL, FIXED_PMC_CTRL(i, FIXED_PMC_KERNEL));279 280 __guest_test_arch_event(idx, fixed_event, i | INTEL_RDPMC_FIXED,281 MSR_CORE_PERF_FIXED_CTR0 + i,282 MSR_CORE_PERF_GLOBAL_CTRL,283 FIXED_PMC_GLOBAL_CTRL_ENABLE(i));284}285 286static void guest_test_arch_events(void)287{288 uint8_t i;289 290 for (i = 0; i < NR_INTEL_ARCH_EVENTS; i++)291 guest_test_arch_event(i);292 293 GUEST_DONE();294}295 296static void test_arch_events(uint8_t pmu_version, uint64_t perf_capabilities,297 uint8_t length, uint8_t unavailable_mask)298{299 struct kvm_vcpu *vcpu;300 struct kvm_vm *vm;301 302 /* Testing arch events requires a vPMU (there are no negative tests). */303 if (!pmu_version)304 return;305 306 vm = pmu_vm_create_with_one_vcpu(&vcpu, guest_test_arch_events,307 pmu_version, perf_capabilities);308 309 vcpu_set_cpuid_property(vcpu, X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH,310 length);311 vcpu_set_cpuid_property(vcpu, X86_PROPERTY_PMU_EVENTS_MASK,312 unavailable_mask);313 314 run_vcpu(vcpu);315 316 kvm_vm_free(vm);317}318 319/*320 * Limit testing to MSRs that are actually defined by Intel (in the SDM). MSRs321 * that aren't defined counter MSRs *probably* don't exist, but there's no322 * guarantee that currently undefined MSR indices won't be used for something323 * other than PMCs in the future.324 */325#define MAX_NR_GP_COUNTERS 8326#define MAX_NR_FIXED_COUNTERS 3327 328#define GUEST_ASSERT_PMC_MSR_ACCESS(insn, msr, expect_gp, vector) \329__GUEST_ASSERT(expect_gp ? vector == GP_VECTOR : !vector, \330 "Expected %s on " #insn "(0x%x), got vector %u", \331 expect_gp ? "#GP" : "no fault", msr, vector) \332 333#define GUEST_ASSERT_PMC_VALUE(insn, msr, val, expected) \334 __GUEST_ASSERT(val == expected_val, \335 "Expected " #insn "(0x%x) to yield 0x%lx, got 0x%lx", \336 msr, expected_val, val);337 338static void guest_test_rdpmc(uint32_t rdpmc_idx, bool expect_success,339 uint64_t expected_val)340{341 uint8_t vector;342 uint64_t val;343 344 vector = rdpmc_safe(rdpmc_idx, &val);345 GUEST_ASSERT_PMC_MSR_ACCESS(RDPMC, rdpmc_idx, !expect_success, vector);346 if (expect_success)347 GUEST_ASSERT_PMC_VALUE(RDPMC, rdpmc_idx, val, expected_val);348 349 if (!is_forced_emulation_enabled)350 return;351 352 vector = rdpmc_safe_fep(rdpmc_idx, &val);353 GUEST_ASSERT_PMC_MSR_ACCESS(RDPMC, rdpmc_idx, !expect_success, vector);354 if (expect_success)355 GUEST_ASSERT_PMC_VALUE(RDPMC, rdpmc_idx, val, expected_val);356}357 358static void guest_rd_wr_counters(uint32_t base_msr, uint8_t nr_possible_counters,359 uint8_t nr_counters, uint32_t or_mask)360{361 const bool pmu_has_fast_mode = !guest_get_pmu_version();362 uint8_t i;363 364 for (i = 0; i < nr_possible_counters; i++) {365 /*366 * TODO: Test a value that validates full-width writes and the367 * width of the counters.368 */369 const uint64_t test_val = 0xffff;370 const uint32_t msr = base_msr + i;371 372 /*373 * Fixed counters are supported if the counter is less than the374 * number of enumerated contiguous counters *or* the counter is375 * explicitly enumerated in the supported counters mask.376 */377 const bool expect_success = i < nr_counters || (or_mask & BIT(i));378 379 /*380 * KVM drops writes to MSR_P6_PERFCTR[0|1] if the counters are381 * unsupported, i.e. doesn't #GP and reads back '0'.382 */383 const uint64_t expected_val = expect_success ? test_val : 0;384 const bool expect_gp = !expect_success && msr != MSR_P6_PERFCTR0 &&385 msr != MSR_P6_PERFCTR1;386 uint32_t rdpmc_idx;387 uint8_t vector;388 uint64_t val;389 390 vector = wrmsr_safe(msr, test_val);391 GUEST_ASSERT_PMC_MSR_ACCESS(WRMSR, msr, expect_gp, vector);392 393 vector = rdmsr_safe(msr, &val);394 GUEST_ASSERT_PMC_MSR_ACCESS(RDMSR, msr, expect_gp, vector);395 396 /* On #GP, the result of RDMSR is undefined. */397 if (!expect_gp)398 GUEST_ASSERT_PMC_VALUE(RDMSR, msr, val, expected_val);399 400 /*401 * Redo the read tests with RDPMC, which has different indexing402 * semantics and additional capabilities.403 */404 rdpmc_idx = i;405 if (base_msr == MSR_CORE_PERF_FIXED_CTR0)406 rdpmc_idx |= INTEL_RDPMC_FIXED;407 408 guest_test_rdpmc(rdpmc_idx, expect_success, expected_val);409 410 /*411 * KVM doesn't support non-architectural PMUs, i.e. it should412 * impossible to have fast mode RDPMC. Verify that attempting413 * to use fast RDPMC always #GPs.414 */415 GUEST_ASSERT(!expect_success || !pmu_has_fast_mode);416 rdpmc_idx |= INTEL_RDPMC_FAST;417 guest_test_rdpmc(rdpmc_idx, false, -1ull);418 419 vector = wrmsr_safe(msr, 0);420 GUEST_ASSERT_PMC_MSR_ACCESS(WRMSR, msr, expect_gp, vector);421 }422}423 424static void guest_test_gp_counters(void)425{426 uint8_t pmu_version = guest_get_pmu_version();427 uint8_t nr_gp_counters = 0;428 uint32_t base_msr;429 430 if (pmu_version)431 nr_gp_counters = this_cpu_property(X86_PROPERTY_PMU_NR_GP_COUNTERS);432 433 /*434 * For v2+ PMUs, PERF_GLOBAL_CTRL's architectural post-RESET value is435 * "Sets bits n-1:0 and clears the upper bits", where 'n' is the number436 * of GP counters. If there are no GP counters, require KVM to leave437 * PERF_GLOBAL_CTRL '0'. This edge case isn't covered by the SDM, but438 * follow the spirit of the architecture and only globally enable GP439 * counters, of which there are none.440 */441 if (pmu_version > 1) {442 uint64_t global_ctrl = rdmsr(MSR_CORE_PERF_GLOBAL_CTRL);443 444 if (nr_gp_counters)445 GUEST_ASSERT_EQ(global_ctrl, GENMASK_ULL(nr_gp_counters - 1, 0));446 else447 GUEST_ASSERT_EQ(global_ctrl, 0);448 }449 450 if (this_cpu_has(X86_FEATURE_PDCM) &&451 rdmsr(MSR_IA32_PERF_CAPABILITIES) & PMU_CAP_FW_WRITES)452 base_msr = MSR_IA32_PMC0;453 else454 base_msr = MSR_IA32_PERFCTR0;455 456 guest_rd_wr_counters(base_msr, MAX_NR_GP_COUNTERS, nr_gp_counters, 0);457 GUEST_DONE();458}459 460static void test_gp_counters(uint8_t pmu_version, uint64_t perf_capabilities,461 uint8_t nr_gp_counters)462{463 struct kvm_vcpu *vcpu;464 struct kvm_vm *vm;465 466 vm = pmu_vm_create_with_one_vcpu(&vcpu, guest_test_gp_counters,467 pmu_version, perf_capabilities);468 469 vcpu_set_cpuid_property(vcpu, X86_PROPERTY_PMU_NR_GP_COUNTERS,470 nr_gp_counters);471 472 run_vcpu(vcpu);473 474 kvm_vm_free(vm);475}476 477static void guest_test_fixed_counters(void)478{479 uint64_t supported_bitmask = 0;480 uint8_t nr_fixed_counters = 0;481 uint8_t i;482 483 /* Fixed counters require Architectural vPMU Version 2+. */484 if (guest_get_pmu_version() >= 2)485 nr_fixed_counters = this_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS);486 487 /*488 * The supported bitmask for fixed counters was introduced in PMU489 * version 5.490 */491 if (guest_get_pmu_version() >= 5)492 supported_bitmask = this_cpu_property(X86_PROPERTY_PMU_FIXED_COUNTERS_BITMASK);493 494 guest_rd_wr_counters(MSR_CORE_PERF_FIXED_CTR0, MAX_NR_FIXED_COUNTERS,495 nr_fixed_counters, supported_bitmask);496 497 for (i = 0; i < MAX_NR_FIXED_COUNTERS; i++) {498 uint8_t vector;499 uint64_t val;500 501 if (i >= nr_fixed_counters && !(supported_bitmask & BIT_ULL(i))) {502 vector = wrmsr_safe(MSR_CORE_PERF_FIXED_CTR_CTRL,503 FIXED_PMC_CTRL(i, FIXED_PMC_KERNEL));504 __GUEST_ASSERT(vector == GP_VECTOR,505 "Expected #GP for counter %u in FIXED_CTR_CTRL", i);506 507 vector = wrmsr_safe(MSR_CORE_PERF_GLOBAL_CTRL,508 FIXED_PMC_GLOBAL_CTRL_ENABLE(i));509 __GUEST_ASSERT(vector == GP_VECTOR,510 "Expected #GP for counter %u in PERF_GLOBAL_CTRL", i);511 continue;512 }513 514 wrmsr(MSR_CORE_PERF_FIXED_CTR0 + i, 0);515 wrmsr(MSR_CORE_PERF_FIXED_CTR_CTRL, FIXED_PMC_CTRL(i, FIXED_PMC_KERNEL));516 wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, FIXED_PMC_GLOBAL_CTRL_ENABLE(i));517 __asm__ __volatile__("loop ." : "+c"((int){NUM_LOOPS}));518 wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0);519 val = rdmsr(MSR_CORE_PERF_FIXED_CTR0 + i);520 521 GUEST_ASSERT_NE(val, 0);522 }523 GUEST_DONE();524}525 526static void test_fixed_counters(uint8_t pmu_version, uint64_t perf_capabilities,527 uint8_t nr_fixed_counters,528 uint32_t supported_bitmask)529{530 struct kvm_vcpu *vcpu;531 struct kvm_vm *vm;532 533 vm = pmu_vm_create_with_one_vcpu(&vcpu, guest_test_fixed_counters,534 pmu_version, perf_capabilities);535 536 vcpu_set_cpuid_property(vcpu, X86_PROPERTY_PMU_FIXED_COUNTERS_BITMASK,537 supported_bitmask);538 vcpu_set_cpuid_property(vcpu, X86_PROPERTY_PMU_NR_FIXED_COUNTERS,539 nr_fixed_counters);540 541 run_vcpu(vcpu);542 543 kvm_vm_free(vm);544}545 546static void test_intel_counters(void)547{548 uint8_t nr_arch_events = kvm_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH);549 uint8_t nr_fixed_counters = kvm_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS);550 uint8_t nr_gp_counters = kvm_cpu_property(X86_PROPERTY_PMU_NR_GP_COUNTERS);551 uint8_t pmu_version = kvm_cpu_property(X86_PROPERTY_PMU_VERSION);552 unsigned int i;553 uint8_t v, j;554 uint32_t k;555 556 const uint64_t perf_caps[] = {557 0,558 PMU_CAP_FW_WRITES,559 };560 561 /*562 * Test up to PMU v5, which is the current maximum version defined by563 * Intel, i.e. is the last version that is guaranteed to be backwards564 * compatible with KVM's existing behavior.565 */566 uint8_t max_pmu_version = max_t(typeof(pmu_version), pmu_version, 5);567 568 /*569 * Detect the existence of events that aren't supported by selftests.570 * This will (obviously) fail any time the kernel adds support for a571 * new event, but it's worth paying that price to keep the test fresh.572 */573 TEST_ASSERT(nr_arch_events <= NR_INTEL_ARCH_EVENTS,574 "New architectural event(s) detected; please update this test (length = %u, mask = %x)",575 nr_arch_events, kvm_cpu_property(X86_PROPERTY_PMU_EVENTS_MASK));576 577 /*578 * Force iterating over known arch events regardless of whether or not579 * KVM/hardware supports a given event.580 */581 nr_arch_events = max_t(typeof(nr_arch_events), nr_arch_events, NR_INTEL_ARCH_EVENTS);582 583 for (v = 0; v <= max_pmu_version; v++) {584 for (i = 0; i < ARRAY_SIZE(perf_caps); i++) {585 if (!kvm_has_perf_caps && perf_caps[i])586 continue;587 588 pr_info("Testing arch events, PMU version %u, perf_caps = %lx\n",589 v, perf_caps[i]);590 /*591 * To keep the total runtime reasonable, test every592 * possible non-zero, non-reserved bitmap combination593 * only with the native PMU version and the full bit594 * vector length.595 */596 if (v == pmu_version) {597 for (k = 1; k < (BIT(nr_arch_events) - 1); k++)598 test_arch_events(v, perf_caps[i], nr_arch_events, k);599 }600 /*601 * Test single bits for all PMU version and lengths up602 * the number of events +1 (to verify KVM doesn't do603 * weird things if the guest length is greater than the604 * host length). Explicitly test a mask of '0' and all605 * ones i.e. all events being available and unavailable.606 */607 for (j = 0; j <= nr_arch_events + 1; j++) {608 test_arch_events(v, perf_caps[i], j, 0);609 test_arch_events(v, perf_caps[i], j, 0xff);610 611 for (k = 0; k < nr_arch_events; k++)612 test_arch_events(v, perf_caps[i], j, BIT(k));613 }614 615 pr_info("Testing GP counters, PMU version %u, perf_caps = %lx\n",616 v, perf_caps[i]);617 for (j = 0; j <= nr_gp_counters; j++)618 test_gp_counters(v, perf_caps[i], j);619 620 pr_info("Testing fixed counters, PMU version %u, perf_caps = %lx\n",621 v, perf_caps[i]);622 for (j = 0; j <= nr_fixed_counters; j++) {623 for (k = 0; k <= (BIT(nr_fixed_counters) - 1); k++)624 test_fixed_counters(v, perf_caps[i], j, k);625 }626 }627 }628}629 630int main(int argc, char *argv[])631{632 TEST_REQUIRE(kvm_is_pmu_enabled());633 634 TEST_REQUIRE(host_cpu_is_intel);635 TEST_REQUIRE(kvm_cpu_has_p(X86_PROPERTY_PMU_VERSION));636 TEST_REQUIRE(kvm_cpu_property(X86_PROPERTY_PMU_VERSION) > 0);637 638 kvm_pmu_version = kvm_cpu_property(X86_PROPERTY_PMU_VERSION);639 kvm_has_perf_caps = kvm_cpu_has(X86_FEATURE_PDCM);640 641 test_intel_counters();642 643 return 0;644}645