xref: /kvm-unit-tests/lib/x86/pmu.c (revision f3f338619e4938c2509f5c691adc1f331b07c203)
1 #include "pmu.h"
2 
3 struct pmu_caps pmu;
4 
pmu_init(void)5 void pmu_init(void)
6 {
7 	pmu.is_intel = is_intel();
8 
9 	if (pmu.is_intel) {
10 		pmu.version = this_cpu_property(X86_PROPERTY_PMU_VERSION);
11 
12 		if (pmu.version > 1) {
13 			pmu.nr_fixed_counters = this_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS);
14 			pmu.fixed_counter_width = this_cpu_property(X86_PROPERTY_PMU_FIXED_COUNTERS_BIT_WIDTH);
15 		}
16 
17 		pmu.nr_gp_counters = this_cpu_property(X86_PROPERTY_PMU_NR_GP_COUNTERS);
18 		pmu.gp_counter_width = this_cpu_property(X86_PROPERTY_PMU_GP_COUNTERS_BIT_WIDTH);
19 		pmu.arch_event_mask_length = this_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH);
20 
21 		/* CPUID.0xA.EBX bit is '1' if an arch event is NOT available. */
22 		pmu.arch_event_available = ~this_cpu_property(X86_PROPERTY_PMU_EVENTS_MASK) &
23 					   (BIT(pmu.arch_event_mask_length) - 1);
24 
25 		if (this_cpu_has(X86_FEATURE_PDCM))
26 			pmu.perf_cap = rdmsr(MSR_IA32_PERF_CAPABILITIES);
27 		pmu.msr_gp_counter_base = MSR_IA32_PERFCTR0;
28 		pmu.msr_gp_event_select_base = MSR_P6_EVNTSEL0;
29 
30 		if (this_cpu_has_perf_global_status()) {
31 			pmu.msr_global_status = MSR_CORE_PERF_GLOBAL_STATUS;
32 			pmu.msr_global_ctl = MSR_CORE_PERF_GLOBAL_CTRL;
33 			pmu.msr_global_status_clr = MSR_CORE_PERF_GLOBAL_OVF_CTRL;
34 		}
35 	} else {
36 		if (this_cpu_has(X86_FEATURE_PERFCTR_CORE)) {
37 			/* Performance Monitoring Version 2 Supported */
38 			if (this_cpu_has(X86_FEATURE_AMD_PMU_V2)) {
39 				pmu.version = 2;
40 				pmu.nr_gp_counters = this_cpu_property(X86_PROPERTY_NR_PERFCTR_CORE);
41 			} else {
42 				pmu.nr_gp_counters = AMD64_NUM_COUNTERS_CORE;
43 			}
44 			pmu.msr_gp_counter_base = MSR_F15H_PERF_CTR0;
45 			pmu.msr_gp_event_select_base = MSR_F15H_PERF_CTL0;
46 		} else {
47 			pmu.nr_gp_counters = AMD64_NUM_COUNTERS;
48 			pmu.msr_gp_counter_base = MSR_K7_PERFCTR0;
49 			pmu.msr_gp_event_select_base = MSR_K7_EVNTSEL0;
50 		}
51 		pmu.gp_counter_width = PMC_DEFAULT_WIDTH;
52 		pmu.arch_event_mask_length = 32;
53 		pmu.arch_event_available = -1u;
54 
55 		if (this_cpu_has_perf_global_status()) {
56 			pmu.msr_global_status = MSR_AMD64_PERF_CNTR_GLOBAL_STATUS;
57 			pmu.msr_global_ctl = MSR_AMD64_PERF_CNTR_GLOBAL_CTL;
58 			pmu.msr_global_status_clr = MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR;
59 		}
60 	}
61 
62 	pmu_reset_all_counters();
63 }
64