xref: /kvm-unit-tests/lib/x86/pmu.c (revision f33d39468cb29053f552aef2c0017d970680a239)
1 #include "pmu.h"
2 
3 struct pmu_caps pmu;
4 
5 void pmu_init(void)
6 {
7 	struct cpuid cpuid_10 = cpuid(10);
8 
9 	pmu.version = cpuid_10.a & 0xff;
10 
11 	if (pmu.version > 1) {
12 		pmu.nr_fixed_counters = cpuid_10.d & 0x1f;
13 		pmu.fixed_counter_width = (cpuid_10.d >> 5) & 0xff;
14 	}
15 
16 	pmu.nr_gp_counters = (cpuid_10.a >> 8) & 0xff;
17 	pmu.gp_counter_width = (cpuid_10.a >> 16) & 0xff;
18 	pmu.gp_counter_mask_length = (cpuid_10.a >> 24) & 0xff;
19 
20 	/* CPUID.0xA.EBX bit is '1' if a counter is NOT available. */
21 	pmu.gp_counter_available = ~cpuid_10.b;
22 
23 	if (this_cpu_has(X86_FEATURE_PDCM))
24 		pmu.perf_cap = rdmsr(MSR_IA32_PERF_CAPABILITIES);
25 	pmu.msr_gp_counter_base = MSR_IA32_PERFCTR0;
26 	pmu.msr_gp_event_select_base = MSR_P6_EVNTSEL0;
27 
28 	pmu_reset_all_counters();
29 }
30