Mention branches and keyring.
[releases.git] / x86 / kvm / svm / pmu.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * KVM PMU support for AMD
4  *
5  * Copyright 2015, Red Hat, Inc. and/or its affiliates.
6  *
7  * Author:
8  *   Wei Huang <wei@redhat.com>
9  *
10  * Implementation is based on pmu_intel.c file
11  */
12 #include <linux/types.h>
13 #include <linux/kvm_host.h>
14 #include <linux/perf_event.h>
15 #include "x86.h"
16 #include "cpuid.h"
17 #include "lapic.h"
18 #include "pmu.h"
19 #include "svm.h"
20
21 enum pmu_type {
22         PMU_TYPE_COUNTER = 0,
23         PMU_TYPE_EVNTSEL,
24 };
25
26 static struct kvm_pmc *amd_pmc_idx_to_pmc(struct kvm_pmu *pmu, int pmc_idx)
27 {
28         unsigned int num_counters = pmu->nr_arch_gp_counters;
29
30         if (pmc_idx >= num_counters)
31                 return NULL;
32
33         return &pmu->gp_counters[array_index_nospec(pmc_idx, num_counters)];
34 }
35
36 static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr,
37                                              enum pmu_type type)
38 {
39         struct kvm_vcpu *vcpu = pmu_to_vcpu(pmu);
40         unsigned int idx;
41
42         if (!vcpu->kvm->arch.enable_pmu)
43                 return NULL;
44
45         switch (msr) {
46         case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5:
47                 if (!guest_cpuid_has(vcpu, X86_FEATURE_PERFCTR_CORE))
48                         return NULL;
49                 /*
50                  * Each PMU counter has a pair of CTL and CTR MSRs. CTLn
51                  * MSRs (accessed via EVNTSEL) are even, CTRn MSRs are odd.
52                  */
53                 idx = (unsigned int)((msr - MSR_F15H_PERF_CTL0) / 2);
54                 if (!(msr & 0x1) != (type == PMU_TYPE_EVNTSEL))
55                         return NULL;
56                 break;
57         case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3:
58                 if (type != PMU_TYPE_EVNTSEL)
59                         return NULL;
60                 idx = msr - MSR_K7_EVNTSEL0;
61                 break;
62         case MSR_K7_PERFCTR0 ... MSR_K7_PERFCTR3:
63                 if (type != PMU_TYPE_COUNTER)
64                         return NULL;
65                 idx = msr - MSR_K7_PERFCTR0;
66                 break;
67         default:
68                 return NULL;
69         }
70
71         return amd_pmc_idx_to_pmc(pmu, idx);
72 }
73
74 static bool amd_hw_event_available(struct kvm_pmc *pmc)
75 {
76         return true;
77 }
78
79 /* check if a PMC is enabled by comparing it against global_ctrl bits. Because
80  * AMD CPU doesn't have global_ctrl MSR, all PMCs are enabled (return TRUE).
81  */
82 static bool amd_pmc_is_enabled(struct kvm_pmc *pmc)
83 {
84         return true;
85 }
86
87 static bool amd_is_valid_rdpmc_ecx(struct kvm_vcpu *vcpu, unsigned int idx)
88 {
89         struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
90
91         idx &= ~(3u << 30);
92
93         return idx < pmu->nr_arch_gp_counters;
94 }
95
96 /* idx is the ECX register of RDPMC instruction */
97 static struct kvm_pmc *amd_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu,
98         unsigned int idx, u64 *mask)
99 {
100         return amd_pmc_idx_to_pmc(vcpu_to_pmu(vcpu), idx & ~(3u << 30));
101 }
102
103 static bool amd_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
104 {
105         /* All MSRs refer to exactly one PMC, so msr_idx_to_pmc is enough.  */
106         return false;
107 }
108
109 static struct kvm_pmc *amd_msr_idx_to_pmc(struct kvm_vcpu *vcpu, u32 msr)
110 {
111         struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
112         struct kvm_pmc *pmc;
113
114         pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_COUNTER);
115         pmc = pmc ? pmc : get_gp_pmc_amd(pmu, msr, PMU_TYPE_EVNTSEL);
116
117         return pmc;
118 }
119
120 static int amd_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
121 {
122         struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
123         struct kvm_pmc *pmc;
124         u32 msr = msr_info->index;
125
126         /* MSR_PERFCTRn */
127         pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_COUNTER);
128         if (pmc) {
129                 msr_info->data = pmc_read_counter(pmc);
130                 return 0;
131         }
132         /* MSR_EVNTSELn */
133         pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_EVNTSEL);
134         if (pmc) {
135                 msr_info->data = pmc->eventsel;
136                 return 0;
137         }
138
139         return 1;
140 }
141
142 static int amd_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
143 {
144         struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
145         struct kvm_pmc *pmc;
146         u32 msr = msr_info->index;
147         u64 data = msr_info->data;
148
149         /* MSR_PERFCTRn */
150         pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_COUNTER);
151         if (pmc) {
152                 pmc_write_counter(pmc, data);
153                 pmc_update_sample_period(pmc);
154                 return 0;
155         }
156         /* MSR_EVNTSELn */
157         pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_EVNTSEL);
158         if (pmc) {
159                 data &= ~pmu->reserved_bits;
160                 if (data != pmc->eventsel) {
161                         pmc->eventsel = data;
162                         reprogram_counter(pmc);
163                 }
164                 return 0;
165         }
166
167         return 1;
168 }
169
170 static void amd_pmu_refresh(struct kvm_vcpu *vcpu)
171 {
172         struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
173
174         if (guest_cpuid_has(vcpu, X86_FEATURE_PERFCTR_CORE))
175                 pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS_CORE;
176         else
177                 pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS;
178
179         pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1;
180         pmu->reserved_bits = 0xfffffff000280000ull;
181         pmu->raw_event_mask = AMD64_RAW_EVENT_MASK;
182         pmu->version = 1;
183         /* not applicable to AMD; but clean them to prevent any fall out */
184         pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
185         pmu->nr_arch_fixed_counters = 0;
186         pmu->global_status = 0;
187         bitmap_set(pmu->all_valid_pmc_idx, 0, pmu->nr_arch_gp_counters);
188 }
189
190 static void amd_pmu_init(struct kvm_vcpu *vcpu)
191 {
192         struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
193         int i;
194
195         BUILD_BUG_ON(KVM_AMD_PMC_MAX_GENERIC > AMD64_NUM_COUNTERS_CORE);
196         BUILD_BUG_ON(KVM_AMD_PMC_MAX_GENERIC > INTEL_PMC_MAX_GENERIC);
197
198         for (i = 0; i < KVM_AMD_PMC_MAX_GENERIC ; i++) {
199                 pmu->gp_counters[i].type = KVM_PMC_GP;
200                 pmu->gp_counters[i].vcpu = vcpu;
201                 pmu->gp_counters[i].idx = i;
202                 pmu->gp_counters[i].current_config = 0;
203         }
204 }
205
206 static void amd_pmu_reset(struct kvm_vcpu *vcpu)
207 {
208         struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
209         int i;
210
211         for (i = 0; i < KVM_AMD_PMC_MAX_GENERIC; i++) {
212                 struct kvm_pmc *pmc = &pmu->gp_counters[i];
213
214                 pmc_stop_counter(pmc);
215                 pmc->counter = pmc->eventsel = 0;
216         }
217 }
218
219 struct kvm_pmu_ops amd_pmu_ops __initdata = {
220         .hw_event_available = amd_hw_event_available,
221         .pmc_is_enabled = amd_pmc_is_enabled,
222         .pmc_idx_to_pmc = amd_pmc_idx_to_pmc,
223         .rdpmc_ecx_to_pmc = amd_rdpmc_ecx_to_pmc,
224         .msr_idx_to_pmc = amd_msr_idx_to_pmc,
225         .is_valid_rdpmc_ecx = amd_is_valid_rdpmc_ecx,
226         .is_valid_msr = amd_is_valid_msr,
227         .get_msr = amd_pmu_get_msr,
228         .set_msr = amd_pmu_set_msr,
229         .refresh = amd_pmu_refresh,
230         .init = amd_pmu_init,
231         .reset = amd_pmu_reset,
232 };