Lines Matching +full:pmu +full:- +full:event +full:- +full:counter +full:- +full:config
4 #include "x86/pmu.h"
5 #include "x86/apic-defs.h"
27 "add $(2f-1b), %%eax\n\t" \
38 "add $(2f-1b), %%rax\n\t" \
106 uint64_t config; member
195 u32 global_ctl = pmu.msr_global_ctl; in __precise_loop()
196 u32 eax = cntrs & (BIT_ULL(32) - 1); in __precise_loop()
228 * as the counts will vary depending on how many asynchronous VM-Exits in adjust_events_range()
231 if (pmu.is_intel && this_cpu_has_perf_global_ctrl()) { in adjust_events_range()
241 * overwrite the lower boundary of branch misses event to 0 to avoid in adjust_events_range()
270 if (!pmu.is_intel) in is_gp()
273 return evt->ctr < MSR_CORE_PERF_FIXED_CTR0 || in is_gp()
274 evt->ctr >= MSR_IA32_PMC0; in is_gp()
279 if (pmu.is_intel) in event_to_global_idx()
280 return cnt->ctr - (is_gp(cnt) ? pmu.msr_gp_counter_base : in event_to_global_idx()
281 (MSR_CORE_PERF_FIXED_CTR0 - FIXED_CNT_INDEX)); in event_to_global_idx()
283 if (pmu.msr_gp_counter_base == MSR_F15H_PERF_CTR0) in event_to_global_idx()
284 return (cnt->ctr - pmu.msr_gp_counter_base) / 2; in event_to_global_idx()
286 return cnt->ctr - pmu.msr_gp_counter_base; in event_to_global_idx()
295 if (gp_events[i].unit_sel == (cnt->config & 0xffff)) in get_counter_event()
298 unsigned int idx = cnt->ctr - MSR_CORE_PERF_FIXED_CTR0; in get_counter_event()
312 cnt->idx = event_to_global_idx(cnt); in global_enable()
313 wrmsr(pmu.msr_global_ctl, rdmsr(pmu.msr_global_ctl) | BIT_ULL(cnt->idx)); in global_enable()
321 wrmsr(pmu.msr_global_ctl, rdmsr(pmu.msr_global_ctl) & ~BIT_ULL(cnt->idx)); in global_disable()
326 evt->count = count; in __start_event()
327 wrmsr(evt->ctr, evt->count); in __start_event()
330 evt->config | EVNTSEL_EN); in __start_event()
333 int shift = (evt->ctr - MSR_CORE_PERF_FIXED_CTR0) * 4; in __start_event()
336 if (evt->config & EVNTSEL_OS) in __start_event()
338 if (evt->config & EVNTSEL_USR) in __start_event()
340 if (evt->config & EVNTSEL_INT) in __start_event()
358 evt->config & ~EVNTSEL_EN); in __stop_event()
361 int shift = (evt->ctr - MSR_CORE_PERF_FIXED_CTR0) * 4; in __stop_event()
364 evt->count = rdmsr(evt->ctr); in __stop_event()
408 pass = count >= e->min && count <= e->max; in verify_event()
410 printf("FAIL: %d <= %"PRId64" <= %d\n", e->min, count, e->max); in verify_event()
417 return verify_event(cnt->count, get_counter_event(cnt)); in verify_counter()
423 .config = EVNTSEL_OS | EVNTSEL_USR | evt->unit_sel, in check_gp_counter()
427 for (i = 0; i < pmu.nr_gp_counters; i++) { in check_gp_counter()
430 report(verify_event(cnt.count, evt), "%s-%d", evt->name, i); in check_gp_counter()
442 printf("GP event '%s' is disabled\n", in check_gp_counters()
449 .config = EVNTSEL_OS | EVNTSEL_USR, in check_fixed_counters()
456 report(verify_event(cnt.count, &fixed_events[i]), "fixed-%d", i); in check_fixed_counters()
465 for (i = 0, n = 0; n < pmu.nr_gp_counters; i++) { in check_counters_many()
470 cnt[n].config = EVNTSEL_OS | EVNTSEL_USR | in check_counters_many()
476 cnt[n].config = EVNTSEL_OS | EVNTSEL_USR; in check_counters_many()
498 * waiting for the overflow to propagate through the counter. in measure_for_overflow()
500 assert(cnt->count > 1); in measure_for_overflow()
501 return 1 - cnt->count; in measure_for_overflow()
508 int instruction_idx = pmu.is_intel ? in check_counter_overflow()
514 .config = EVNTSEL_OS | EVNTSEL_USR | in check_counter_overflow()
525 for (i = 0; i < pmu.nr_gp_counters + 1; i++) { in check_counter_overflow()
531 cnt.count &= (1ull << pmu.gp_counter_width) - 1; in check_counter_overflow()
533 if (i == pmu.nr_gp_counters) { in check_counter_overflow()
534 if (!pmu.is_intel) in check_counter_overflow()
539 cnt.count &= (1ull << pmu.gp_counter_width) - 1; in check_counter_overflow()
545 cnt.config |= EVNTSEL_INT; in check_counter_overflow()
547 cnt.config &= ~EVNTSEL_INT; in check_counter_overflow()
550 if (pmu.is_intel) in check_counter_overflow()
551 report(cnt.count == 1, "cntr-%d", i); in check_counter_overflow()
553 report(cnt.count == 0xffffffffffff || cnt.count < 7, "cntr-%d", i); in check_counter_overflow()
558 status = rdmsr(pmu.msr_global_status); in check_counter_overflow()
559 report(status & (1ull << idx), "status-%d", i); in check_counter_overflow()
560 wrmsr(pmu.msr_global_status_clr, status); in check_counter_overflow()
561 status = rdmsr(pmu.msr_global_status); in check_counter_overflow()
562 report(!(status & (1ull << idx)), "status clear-%d", i); in check_counter_overflow()
563 report(check_irq() == (i % 2), "irq-%d", i); in check_counter_overflow()
571 int instruction_idx = pmu.is_intel ? in check_gp_counter_cmask()
577 .config = EVNTSEL_OS | EVNTSEL_USR | in check_gp_counter_cmask()
580 cnt.config |= (0x2 << EVNTSEL_CMASK_SHIFT); in check_gp_counter_cmask()
588 uint32_t idx = (uint32_t)cnt->idx | (1u << 31); in do_rdpmc_fast()
593 cnt->count = rdpmc(idx); in do_rdpmc_fast()
605 for (i = 0; i < pmu.nr_gp_counters; i++) { in check_rdpmc()
613 * Without full-width writes, only the low 32 bits are writable, in check_rdpmc()
614 * and the value is sign-extended. in check_rdpmc()
616 if (pmu.msr_gp_counter_base == MSR_IA32_PERFCTR0) in check_rdpmc()
622 x &= (1ull << pmu.gp_counter_width) - 1; in check_rdpmc()
625 report(rdpmc(i) == x, "cntr-%d", i); in check_rdpmc()
629 report_skip("fast-%d", i); in check_rdpmc()
631 report(cnt.count == (u32)val, "fast-%d", i); in check_rdpmc()
634 uint64_t x = val & ((1ull << pmu.fixed_counter_width) - 1); in check_rdpmc()
641 report(rdpmc(i | (1 << 30)) == x, "fixed cntr-%d", i); in check_rdpmc()
645 report_skip("fixed fast-%d", i); in check_rdpmc()
647 report(cnt.count == (u32)x, "fixed fast-%d", i); in check_rdpmc()
657 unsigned int instruction_idx = pmu.is_intel ? in check_running_counter_wrmsr()
663 .config = EVNTSEL_OS | EVNTSEL_USR | in check_running_counter_wrmsr()
667 report_prefix_push("running counter wrmsr"); in check_running_counter_wrmsr()
681 count = -1; in check_running_counter_wrmsr()
683 count &= (1ull << pmu.gp_counter_width) - 1; in check_running_counter_wrmsr()
691 status = rdmsr(pmu.msr_global_status); in check_running_counter_wrmsr()
702 uint64_t gp_counter_width = (1ull << pmu.gp_counter_width) - 1; in check_emulated_instr()
703 unsigned int branch_idx = pmu.is_intel ? in check_emulated_instr()
705 unsigned int instruction_idx = pmu.is_intel ? in check_emulated_instr()
712 .config = EVNTSEL_OS | EVNTSEL_USR | gp_events[branch_idx].unit_sel, in check_emulated_instr()
717 .config = EVNTSEL_OS | EVNTSEL_USR | gp_events[instruction_idx].unit_sel, in check_emulated_instr()
727 brnch_start = -KVM_FEP_BRANCHES; in check_emulated_instr()
728 instr_start = -KVM_FEP_INSNS; in check_emulated_instr()
734 ecx = pmu.msr_global_ctl; in check_emulated_instr()
745 // Check that the end count - start count is at least the expected in check_emulated_instr()
748 report(instr_cnt.count - instr_start == KVM_FEP_INSNS, in check_emulated_instr()
750 report(brnch_cnt.count - brnch_start == KVM_FEP_BRANCHES, in check_emulated_instr()
753 report(instr_cnt.count - instr_start >= KVM_FEP_INSNS, in check_emulated_instr()
755 report(brnch_cnt.count - brnch_start >= KVM_FEP_BRANCHES, in check_emulated_instr()
761 status = rdmsr(pmu.msr_global_status); in check_emulated_instr()
762 report(status & BIT_ULL(0), "branch counter overflow"); in check_emulated_instr()
763 report(status & BIT_ULL(1), "instruction counter overflow"); in check_emulated_instr()
780 for (i = 0; i < pmu.nr_gp_counters; i++) { in check_tsx_cycles()
784 /* Transactional cycles committed only on gp counter 2 */ in check_tsx_cycles()
785 cnt.config = EVNTSEL_OS | EVNTSEL_USR | 0x30000003c; in check_tsx_cycles()
788 cnt.config = EVNTSEL_OS | EVNTSEL_USR | 0x10000003c; in check_tsx_cycles()
797 /* Generate a non-canonical #GP to trigger ABORT. */ in check_tsx_cycles()
803 report(cnt.count > 0, "gp cntr-%d with a value of %" PRId64 "", i, cnt.count); in check_tsx_cycles()
814 * Since cycles event is always run as the first event, there would be in warm_up()
815 * a warm-up state to warm up the cache, it leads to the measured cycles in warm_up()
816 * value may exceed the pre-defined cycles upper boundary and cause in warm_up()
817 * false positive. To avoid this, introduce an warm-up state before in warm_up()
848 u64 val_32 = val_64 & ((1ull << 32) - 1); in check_gp_counters_write_width()
849 u64 val_max_width = val_64 & ((1ull << pmu.gp_counter_width) - 1); in check_gp_counters_write_width()
853 * MSR_IA32_PERFCTRn supports 64-bit writes, in check_gp_counters_write_width()
856 for (i = 0; i < pmu.nr_gp_counters; i++) { in check_gp_counters_write_width()
871 * MSR_IA32_PMCn supports writing values up to GP counter width, in check_gp_counters_write_width()
872 * and only the lowest bits of GP counter width are valid. in check_gp_counters_write_width()
874 for (i = 0; i < pmu.nr_gp_counters; i++) { in check_gp_counters_write_width()
898 .config = EVNTSEL_OS | EVNTSEL_USR | in set_ref_cycle_expectations()
905 if (!pmu.nr_gp_counters || !pmu_gp_counter_is_available(2)) in set_ref_cycle_expectations()
909 wrmsr(pmu.msr_global_ctl, 0); in set_ref_cycle_expectations()
916 * This loop has to run long enough to dominate the VM-exit in set_ref_cycle_expectations()
917 * costs for playing with the PMU MSRs on start and stop. in set_ref_cycle_expectations()
930 tsc_delta = ((t2 - t1) + (t3 - t0)) / 2; in set_ref_cycle_expectations()
961 if (pmu.is_intel) { in main()
962 if (!pmu.version) { in main()
963 report_skip("No Intel Arch PMU is detected!"); in main()
992 printf("PMU version: %d\n", pmu.version); in main()
993 printf("GP counters: %d\n", pmu.nr_gp_counters); in main()
994 printf("GP counter width: %d\n", pmu.gp_counter_width); in main()
995 printf("Mask length: %d\n", pmu.gp_counter_mask_length); in main()
996 printf("Fixed counters: %d\n", pmu.nr_fixed_counters); in main()
997 printf("Fixed counter width: %d\n", pmu.fixed_counter_width); in main()
999 fixed_counters_num = MIN(pmu.nr_fixed_counters, ARRAY_SIZE(fixed_events)); in main()
1000 if (pmu.nr_fixed_counters > ARRAY_SIZE(fixed_events)) in main()
1002 "Please update test case.", pmu.nr_fixed_counters, in main()
1010 pmu.msr_gp_counter_base = MSR_IA32_PMC0; in main()
1012 report_prefix_push("full-width writes"); in main()
1018 if (!pmu.is_intel) { in main()
1020 pmu.nr_gp_counters = AMD64_NUM_COUNTERS; in main()
1021 pmu.msr_gp_counter_base = MSR_K7_PERFCTR0; in main()
1022 pmu.msr_gp_event_select_base = MSR_K7_EVNTSEL0; in main()