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