blob: 38819bc923cf50505b1fbd9266df4a8fb9e3278f [file] [log] [blame]
Gleb Natapovf5132b02011-11-10 14:57:22 +02001/*
Guo Chaoc7a70622012-06-28 15:23:08 +08002 * Kernel-based Virtual Machine -- Performance Monitoring Unit support
Gleb Natapovf5132b02011-11-10 14:57:22 +02003 *
4 * Copyright 2011 Red Hat, Inc. and/or its affiliates.
5 *
6 * Authors:
7 * Avi Kivity <avi@redhat.com>
8 * Gleb Natapov <gleb@redhat.com>
9 *
10 * This work is licensed under the terms of the GNU GPL, version 2. See
11 * the COPYING file in the top-level directory.
12 *
13 */
14
15#include <linux/types.h>
16#include <linux/kvm_host.h>
17#include <linux/perf_event.h>
Nadav Amitd27aa7f2014-08-20 13:25:52 +030018#include <asm/perf_event.h>
Gleb Natapovf5132b02011-11-10 14:57:22 +020019#include "x86.h"
20#include "cpuid.h"
21#include "lapic.h"
Wei Huang474a5bb2015-06-19 13:54:23 +020022#include "pmu.h"
Gleb Natapovf5132b02011-11-10 14:57:22 +020023
Wei Huang474a5bb2015-06-19 13:54:23 +020024static struct kvm_event_hw_type_mapping arch_events[] = {
Gleb Natapovf5132b02011-11-10 14:57:22 +020025 /* Index must match CPUID 0x0A.EBX bit vector */
26 [0] = { 0x3c, 0x00, PERF_COUNT_HW_CPU_CYCLES },
27 [1] = { 0xc0, 0x00, PERF_COUNT_HW_INSTRUCTIONS },
28 [2] = { 0x3c, 0x01, PERF_COUNT_HW_BUS_CYCLES },
29 [3] = { 0x2e, 0x4f, PERF_COUNT_HW_CACHE_REFERENCES },
30 [4] = { 0x2e, 0x41, PERF_COUNT_HW_CACHE_MISSES },
31 [5] = { 0xc4, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
32 [6] = { 0xc5, 0x00, PERF_COUNT_HW_BRANCH_MISSES },
Gleb Natapov62079d82012-02-26 16:55:42 +020033 [7] = { 0x00, 0x30, PERF_COUNT_HW_REF_CPU_CYCLES },
Gleb Natapovf5132b02011-11-10 14:57:22 +020034};
35
36/* mapping between fixed pmc index and arch_events array */
Xiubo Li52eb5a62015-03-13 17:39:45 +080037static int fixed_pmc_events[] = {1, 0, 7};
Gleb Natapovf5132b02011-11-10 14:57:22 +020038
39static bool pmc_is_gp(struct kvm_pmc *pmc)
40{
41 return pmc->type == KVM_PMC_GP;
42}
43
44static inline u64 pmc_bitmask(struct kvm_pmc *pmc)
45{
Wei Huang212dba12015-06-19 14:00:33 +020046 struct kvm_pmu *pmu = pmc_to_pmu(pmc);
Gleb Natapovf5132b02011-11-10 14:57:22 +020047
48 return pmu->counter_bitmask[pmc->type];
49}
50
Wei Huangc6702c92015-06-19 13:44:45 +020051static inline bool pmc_is_enabled(struct kvm_pmc *pmc)
Gleb Natapovf5132b02011-11-10 14:57:22 +020052{
Wei Huang212dba12015-06-19 14:00:33 +020053 struct kvm_pmu *pmu = pmc_to_pmu(pmc);
Gleb Natapovf5132b02011-11-10 14:57:22 +020054 return test_bit(pmc->idx, (unsigned long *)&pmu->global_ctrl);
55}
56
57static inline struct kvm_pmc *get_gp_pmc(struct kvm_pmu *pmu, u32 msr,
58 u32 base)
59{
60 if (msr >= base && msr < base + pmu->nr_arch_gp_counters)
61 return &pmu->gp_counters[msr - base];
62 return NULL;
63}
64
65static inline struct kvm_pmc *get_fixed_pmc(struct kvm_pmu *pmu, u32 msr)
66{
67 int base = MSR_CORE_PERF_FIXED_CTR0;
68 if (msr >= base && msr < base + pmu->nr_arch_fixed_counters)
69 return &pmu->fixed_counters[msr - base];
70 return NULL;
71}
72
73static inline struct kvm_pmc *get_fixed_pmc_idx(struct kvm_pmu *pmu, int idx)
74{
75 return get_fixed_pmc(pmu, MSR_CORE_PERF_FIXED_CTR0 + idx);
76}
77
78static struct kvm_pmc *global_idx_to_pmc(struct kvm_pmu *pmu, int idx)
79{
Robert Richter15c7ad52012-06-20 20:46:33 +020080 if (idx < INTEL_PMC_IDX_FIXED)
Gleb Natapovf5132b02011-11-10 14:57:22 +020081 return get_gp_pmc(pmu, MSR_P6_EVNTSEL0 + idx, MSR_P6_EVNTSEL0);
82 else
Robert Richter15c7ad52012-06-20 20:46:33 +020083 return get_fixed_pmc_idx(pmu, idx - INTEL_PMC_IDX_FIXED);
Gleb Natapovf5132b02011-11-10 14:57:22 +020084}
85
Wei Huangc6702c92015-06-19 13:44:45 +020086void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu)
Gleb Natapovf5132b02011-11-10 14:57:22 +020087{
88 if (vcpu->arch.apic)
89 kvm_apic_local_deliver(vcpu->arch.apic, APIC_LVTPC);
90}
91
Wei Huangc6702c92015-06-19 13:44:45 +020092static void kvm_pmi_trigger_fn(struct irq_work *irq_work)
Gleb Natapovf5132b02011-11-10 14:57:22 +020093{
Wei Huang212dba12015-06-19 14:00:33 +020094 struct kvm_pmu *pmu = container_of(irq_work, struct kvm_pmu, irq_work);
95 struct kvm_vcpu *vcpu = pmu_to_vcpu(pmu);
Gleb Natapovf5132b02011-11-10 14:57:22 +020096
Wei Huangc6702c92015-06-19 13:44:45 +020097 kvm_pmu_deliver_pmi(vcpu);
Gleb Natapovf5132b02011-11-10 14:57:22 +020098}
99
100static void kvm_perf_overflow(struct perf_event *perf_event,
101 struct perf_sample_data *data,
102 struct pt_regs *regs)
103{
104 struct kvm_pmc *pmc = perf_event->overflow_handler_context;
Wei Huang212dba12015-06-19 14:00:33 +0200105 struct kvm_pmu *pmu = pmc_to_pmu(pmc);
Nadav Amit671bd992014-04-18 03:35:08 +0300106 if (!test_and_set_bit(pmc->idx, (unsigned long *)&pmu->reprogram_pmi)) {
107 __set_bit(pmc->idx, (unsigned long *)&pmu->global_status);
108 kvm_make_request(KVM_REQ_PMU, pmc->vcpu);
109 }
Gleb Natapovf5132b02011-11-10 14:57:22 +0200110}
111
112static void kvm_perf_overflow_intr(struct perf_event *perf_event,
113 struct perf_sample_data *data, struct pt_regs *regs)
114{
115 struct kvm_pmc *pmc = perf_event->overflow_handler_context;
Wei Huang212dba12015-06-19 14:00:33 +0200116 struct kvm_pmu *pmu = pmc_to_pmu(pmc);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200117 if (!test_and_set_bit(pmc->idx, (unsigned long *)&pmu->reprogram_pmi)) {
Nadav Amit671bd992014-04-18 03:35:08 +0300118 __set_bit(pmc->idx, (unsigned long *)&pmu->global_status);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200119 kvm_make_request(KVM_REQ_PMU, pmc->vcpu);
120 /*
121 * Inject PMI. If vcpu was in a guest mode during NMI PMI
122 * can be ejected on a guest mode re-entry. Otherwise we can't
123 * be sure that vcpu wasn't executing hlt instruction at the
124 * time of vmexit and is not going to re-enter guest mode until,
125 * woken up. So we should wake it, but this is impossible from
126 * NMI context. Do it from irq work instead.
127 */
128 if (!kvm_is_in_guest())
Wei Huang212dba12015-06-19 14:00:33 +0200129 irq_work_queue(&pmc_to_pmu(pmc)->irq_work);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200130 else
131 kvm_make_request(KVM_REQ_PMI, pmc->vcpu);
132 }
133}
134
Wei Huangc6702c92015-06-19 13:44:45 +0200135static u64 pmc_read_counter(struct kvm_pmc *pmc)
Gleb Natapovf5132b02011-11-10 14:57:22 +0200136{
137 u64 counter, enabled, running;
138
139 counter = pmc->counter;
140
141 if (pmc->perf_event)
142 counter += perf_event_read_value(pmc->perf_event,
143 &enabled, &running);
144
145 /* FIXME: Scaling needed? */
146
147 return counter & pmc_bitmask(pmc);
148}
149
Wei Huangc6702c92015-06-19 13:44:45 +0200150static void pmc_stop_counter(struct kvm_pmc *pmc)
Gleb Natapovf5132b02011-11-10 14:57:22 +0200151{
152 if (pmc->perf_event) {
Wei Huangc6702c92015-06-19 13:44:45 +0200153 pmc->counter = pmc_read_counter(pmc);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200154 perf_event_release_kernel(pmc->perf_event);
155 pmc->perf_event = NULL;
156 }
157}
158
Wei Huangc6702c92015-06-19 13:44:45 +0200159static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type,
Gleb Natapovf5132b02011-11-10 14:57:22 +0200160 unsigned config, bool exclude_user, bool exclude_kernel,
Andi Kleen103af0a2013-07-18 15:57:02 -0700161 bool intr, bool in_tx, bool in_tx_cp)
Gleb Natapovf5132b02011-11-10 14:57:22 +0200162{
163 struct perf_event *event;
164 struct perf_event_attr attr = {
165 .type = type,
166 .size = sizeof(attr),
167 .pinned = true,
168 .exclude_idle = true,
169 .exclude_host = 1,
170 .exclude_user = exclude_user,
171 .exclude_kernel = exclude_kernel,
172 .config = config,
173 };
Andi Kleen103af0a2013-07-18 15:57:02 -0700174 if (in_tx)
175 attr.config |= HSW_IN_TX;
176 if (in_tx_cp)
177 attr.config |= HSW_IN_TX_CHECKPOINTED;
Gleb Natapovf5132b02011-11-10 14:57:22 +0200178
179 attr.sample_period = (-pmc->counter) & pmc_bitmask(pmc);
180
181 event = perf_event_create_kernel_counter(&attr, -1, current,
182 intr ? kvm_perf_overflow_intr :
183 kvm_perf_overflow, pmc);
184 if (IS_ERR(event)) {
185 printk_once("kvm: pmu event creation failed %ld\n",
186 PTR_ERR(event));
187 return;
188 }
189
190 pmc->perf_event = event;
Wei Huang212dba12015-06-19 14:00:33 +0200191 clear_bit(pmc->idx, (unsigned long*)&pmc_to_pmu(pmc)->reprogram_pmi);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200192}
193
194static unsigned find_arch_event(struct kvm_pmu *pmu, u8 event_select,
195 u8 unit_mask)
196{
197 int i;
198
199 for (i = 0; i < ARRAY_SIZE(arch_events); i++)
200 if (arch_events[i].eventsel == event_select
201 && arch_events[i].unit_mask == unit_mask
202 && (pmu->available_event_types & (1 << i)))
203 break;
204
205 if (i == ARRAY_SIZE(arch_events))
206 return PERF_COUNT_HW_MAX;
207
208 return arch_events[i].event_type;
209}
210
211static void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
212{
213 unsigned config, type = PERF_TYPE_RAW;
214 u8 event_select, unit_mask;
215
Gleb Natapova7b9d2c2012-02-26 16:55:40 +0200216 if (eventsel & ARCH_PERFMON_EVENTSEL_PIN_CONTROL)
217 printk_once("kvm pmu: pin control bit is ignored\n");
218
Gleb Natapovf5132b02011-11-10 14:57:22 +0200219 pmc->eventsel = eventsel;
220
Wei Huangc6702c92015-06-19 13:44:45 +0200221 pmc_stop_counter(pmc);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200222
Wei Huangc6702c92015-06-19 13:44:45 +0200223 if (!(eventsel & ARCH_PERFMON_EVENTSEL_ENABLE) || !pmc_is_enabled(pmc))
Gleb Natapovf5132b02011-11-10 14:57:22 +0200224 return;
225
226 event_select = eventsel & ARCH_PERFMON_EVENTSEL_EVENT;
227 unit_mask = (eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
228
Gleb Natapovfac33682012-02-26 16:55:41 +0200229 if (!(eventsel & (ARCH_PERFMON_EVENTSEL_EDGE |
Gleb Natapovf5132b02011-11-10 14:57:22 +0200230 ARCH_PERFMON_EVENTSEL_INV |
Andi Kleen103af0a2013-07-18 15:57:02 -0700231 ARCH_PERFMON_EVENTSEL_CMASK |
232 HSW_IN_TX |
233 HSW_IN_TX_CHECKPOINTED))) {
Wei Huang212dba12015-06-19 14:00:33 +0200234 config = find_arch_event(pmc_to_pmu(pmc), event_select,
Gleb Natapovf5132b02011-11-10 14:57:22 +0200235 unit_mask);
236 if (config != PERF_COUNT_HW_MAX)
237 type = PERF_TYPE_HARDWARE;
238 }
239
240 if (type == PERF_TYPE_RAW)
241 config = eventsel & X86_RAW_EVENT_MASK;
242
Wei Huangc6702c92015-06-19 13:44:45 +0200243 pmc_reprogram_counter(pmc, type, config,
Gleb Natapovf5132b02011-11-10 14:57:22 +0200244 !(eventsel & ARCH_PERFMON_EVENTSEL_USR),
245 !(eventsel & ARCH_PERFMON_EVENTSEL_OS),
Andi Kleen103af0a2013-07-18 15:57:02 -0700246 eventsel & ARCH_PERFMON_EVENTSEL_INT,
247 (eventsel & HSW_IN_TX),
248 (eventsel & HSW_IN_TX_CHECKPOINTED));
Gleb Natapovf5132b02011-11-10 14:57:22 +0200249}
250
251static void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 en_pmi, int idx)
252{
253 unsigned en = en_pmi & 0x3;
254 bool pmi = en_pmi & 0x8;
255
Wei Huangc6702c92015-06-19 13:44:45 +0200256 pmc_stop_counter(pmc);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200257
Wei Huangc6702c92015-06-19 13:44:45 +0200258 if (!en || !pmc_is_enabled(pmc))
Gleb Natapovf5132b02011-11-10 14:57:22 +0200259 return;
260
Wei Huangc6702c92015-06-19 13:44:45 +0200261 pmc_reprogram_counter(pmc, PERF_TYPE_HARDWARE,
Gleb Natapovf5132b02011-11-10 14:57:22 +0200262 arch_events[fixed_pmc_events[idx]].event_type,
263 !(en & 0x2), /* exclude user */
264 !(en & 0x1), /* exclude kernel */
Andi Kleen103af0a2013-07-18 15:57:02 -0700265 pmi, false, false);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200266}
267
Wei Huangc6702c92015-06-19 13:44:45 +0200268static inline u8 fixed_ctrl_field(u64 ctrl, int idx)
Gleb Natapovf5132b02011-11-10 14:57:22 +0200269{
270 return (ctrl >> (idx * 4)) & 0xf;
271}
272
273static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
274{
275 int i;
276
277 for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
Wei Huangc6702c92015-06-19 13:44:45 +0200278 u8 en_pmi = fixed_ctrl_field(data, i);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200279 struct kvm_pmc *pmc = get_fixed_pmc_idx(pmu, i);
280
Wei Huangc6702c92015-06-19 13:44:45 +0200281 if (fixed_ctrl_field(pmu->fixed_ctr_ctrl, i) == en_pmi)
Gleb Natapovf5132b02011-11-10 14:57:22 +0200282 continue;
283
284 reprogram_fixed_counter(pmc, en_pmi, i);
285 }
286
287 pmu->fixed_ctr_ctrl = data;
288}
289
Wei Huangc6702c92015-06-19 13:44:45 +0200290static void reprogram_counter(struct kvm_pmu *pmu, int idx)
Gleb Natapovf5132b02011-11-10 14:57:22 +0200291{
292 struct kvm_pmc *pmc = global_idx_to_pmc(pmu, idx);
293
294 if (!pmc)
295 return;
296
297 if (pmc_is_gp(pmc))
298 reprogram_gp_counter(pmc, pmc->eventsel);
299 else {
Robert Richter15c7ad52012-06-20 20:46:33 +0200300 int fidx = idx - INTEL_PMC_IDX_FIXED;
Gleb Natapovf5132b02011-11-10 14:57:22 +0200301 reprogram_fixed_counter(pmc,
Wei Huangc6702c92015-06-19 13:44:45 +0200302 fixed_ctrl_field(pmu->fixed_ctr_ctrl, fidx), fidx);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200303 }
304}
305
306static void global_ctrl_changed(struct kvm_pmu *pmu, u64 data)
307{
308 int bit;
309 u64 diff = pmu->global_ctrl ^ data;
310
311 pmu->global_ctrl = data;
312
313 for_each_set_bit(bit, (unsigned long *)&diff, X86_PMC_IDX_MAX)
Wei Huangc6702c92015-06-19 13:44:45 +0200314 reprogram_counter(pmu, bit);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200315}
316
Wei Huangc6702c92015-06-19 13:44:45 +0200317bool kvm_pmu_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
Gleb Natapovf5132b02011-11-10 14:57:22 +0200318{
Wei Huang212dba12015-06-19 14:00:33 +0200319 struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200320 int ret;
321
322 switch (msr) {
323 case MSR_CORE_PERF_FIXED_CTR_CTRL:
324 case MSR_CORE_PERF_GLOBAL_STATUS:
325 case MSR_CORE_PERF_GLOBAL_CTRL:
326 case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
327 ret = pmu->version > 1;
328 break;
329 default:
330 ret = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)
331 || get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0)
332 || get_fixed_pmc(pmu, msr);
333 break;
334 }
335 return ret;
336}
337
338int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data)
339{
Wei Huang212dba12015-06-19 14:00:33 +0200340 struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200341 struct kvm_pmc *pmc;
342
343 switch (index) {
344 case MSR_CORE_PERF_FIXED_CTR_CTRL:
345 *data = pmu->fixed_ctr_ctrl;
346 return 0;
347 case MSR_CORE_PERF_GLOBAL_STATUS:
348 *data = pmu->global_status;
349 return 0;
350 case MSR_CORE_PERF_GLOBAL_CTRL:
351 *data = pmu->global_ctrl;
352 return 0;
353 case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
354 *data = pmu->global_ovf_ctrl;
355 return 0;
356 default:
357 if ((pmc = get_gp_pmc(pmu, index, MSR_IA32_PERFCTR0)) ||
358 (pmc = get_fixed_pmc(pmu, index))) {
Wei Huangc6702c92015-06-19 13:44:45 +0200359 *data = pmc_read_counter(pmc);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200360 return 0;
361 } else if ((pmc = get_gp_pmc(pmu, index, MSR_P6_EVNTSEL0))) {
362 *data = pmc->eventsel;
363 return 0;
364 }
365 }
366 return 1;
367}
368
Paolo Bonziniafd80d82013-03-28 17:18:35 +0100369int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
Gleb Natapovf5132b02011-11-10 14:57:22 +0200370{
Wei Huang212dba12015-06-19 14:00:33 +0200371 struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200372 struct kvm_pmc *pmc;
Paolo Bonziniafd80d82013-03-28 17:18:35 +0100373 u32 index = msr_info->index;
374 u64 data = msr_info->data;
Gleb Natapovf5132b02011-11-10 14:57:22 +0200375
376 switch (index) {
377 case MSR_CORE_PERF_FIXED_CTR_CTRL:
378 if (pmu->fixed_ctr_ctrl == data)
379 return 0;
Sasikantha babufea52952012-03-21 18:49:00 +0530380 if (!(data & 0xfffffffffffff444ull)) {
Gleb Natapovf5132b02011-11-10 14:57:22 +0200381 reprogram_fixed_counters(pmu, data);
382 return 0;
383 }
384 break;
385 case MSR_CORE_PERF_GLOBAL_STATUS:
Paolo Bonziniafd80d82013-03-28 17:18:35 +0100386 if (msr_info->host_initiated) {
387 pmu->global_status = data;
388 return 0;
389 }
Gleb Natapovf5132b02011-11-10 14:57:22 +0200390 break; /* RO MSR */
391 case MSR_CORE_PERF_GLOBAL_CTRL:
392 if (pmu->global_ctrl == data)
393 return 0;
394 if (!(data & pmu->global_ctrl_mask)) {
395 global_ctrl_changed(pmu, data);
396 return 0;
397 }
398 break;
399 case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
400 if (!(data & (pmu->global_ctrl_mask & ~(3ull<<62)))) {
Paolo Bonziniafd80d82013-03-28 17:18:35 +0100401 if (!msr_info->host_initiated)
402 pmu->global_status &= ~data;
Gleb Natapovf5132b02011-11-10 14:57:22 +0200403 pmu->global_ovf_ctrl = data;
404 return 0;
405 }
406 break;
407 default:
408 if ((pmc = get_gp_pmc(pmu, index, MSR_IA32_PERFCTR0)) ||
409 (pmc = get_fixed_pmc(pmu, index))) {
Paolo Bonziniafd80d82013-03-28 17:18:35 +0100410 if (!msr_info->host_initiated)
411 data = (s64)(s32)data;
Wei Huangc6702c92015-06-19 13:44:45 +0200412 pmc->counter += data - pmc_read_counter(pmc);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200413 return 0;
414 } else if ((pmc = get_gp_pmc(pmu, index, MSR_P6_EVNTSEL0))) {
415 if (data == pmc->eventsel)
416 return 0;
Andi Kleen103af0a2013-07-18 15:57:02 -0700417 if (!(data & pmu->reserved_bits)) {
Gleb Natapovf5132b02011-11-10 14:57:22 +0200418 reprogram_gp_counter(pmc, data);
419 return 0;
420 }
421 }
422 }
423 return 1;
424}
425
Wei Huangc6702c92015-06-19 13:44:45 +0200426int kvm_pmu_is_valid_msr_idx(struct kvm_vcpu *vcpu, unsigned pmc)
Nadav Amit67f4d422014-06-02 18:34:09 +0300427{
Wei Huang212dba12015-06-19 14:00:33 +0200428 struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
Nadav Amit67f4d422014-06-02 18:34:09 +0300429 bool fixed = pmc & (1u << 30);
430 pmc &= ~(3u << 30);
431 return (!fixed && pmc >= pmu->nr_arch_gp_counters) ||
432 (fixed && pmc >= pmu->nr_arch_fixed_counters);
433}
434
Wei Huangc6702c92015-06-19 13:44:45 +0200435int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data)
Gleb Natapovf5132b02011-11-10 14:57:22 +0200436{
Wei Huang212dba12015-06-19 14:00:33 +0200437 struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200438 bool fast_mode = pmc & (1u << 31);
439 bool fixed = pmc & (1u << 30);
440 struct kvm_pmc *counters;
441 u64 ctr;
442
Gleb Natapov270c6c72012-02-16 14:44:11 +0200443 pmc &= ~(3u << 30);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200444 if (!fixed && pmc >= pmu->nr_arch_gp_counters)
445 return 1;
446 if (fixed && pmc >= pmu->nr_arch_fixed_counters)
447 return 1;
448 counters = fixed ? pmu->fixed_counters : pmu->gp_counters;
Wei Huangc6702c92015-06-19 13:44:45 +0200449 ctr = pmc_read_counter(&counters[pmc]);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200450 if (fast_mode)
451 ctr = (u32)ctr;
452 *data = ctr;
453
454 return 0;
455}
456
Wei Huangc6702c92015-06-19 13:44:45 +0200457void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
Gleb Natapovf5132b02011-11-10 14:57:22 +0200458{
Wei Huang212dba12015-06-19 14:00:33 +0200459 struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200460 struct kvm_cpuid_entry2 *entry;
Nadav Amitd27aa7f2014-08-20 13:25:52 +0300461 union cpuid10_eax eax;
462 union cpuid10_edx edx;
Gleb Natapovf5132b02011-11-10 14:57:22 +0200463
464 pmu->nr_arch_gp_counters = 0;
465 pmu->nr_arch_fixed_counters = 0;
466 pmu->counter_bitmask[KVM_PMC_GP] = 0;
467 pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
468 pmu->version = 0;
Andi Kleen103af0a2013-07-18 15:57:02 -0700469 pmu->reserved_bits = 0xffffffff00200000ull;
Gleb Natapovf5132b02011-11-10 14:57:22 +0200470
471 entry = kvm_find_cpuid_entry(vcpu, 0xa, 0);
472 if (!entry)
473 return;
Nadav Amitd27aa7f2014-08-20 13:25:52 +0300474 eax.full = entry->eax;
475 edx.full = entry->edx;
Gleb Natapovf5132b02011-11-10 14:57:22 +0200476
Nadav Amitd27aa7f2014-08-20 13:25:52 +0300477 pmu->version = eax.split.version_id;
Gleb Natapovf5132b02011-11-10 14:57:22 +0200478 if (!pmu->version)
479 return;
480
Nadav Amitd27aa7f2014-08-20 13:25:52 +0300481 pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters,
482 INTEL_PMC_MAX_GENERIC);
483 pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << eax.split.bit_width) - 1;
484 pmu->available_event_types = ~entry->ebx &
485 ((1ull << eax.split.mask_length) - 1);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200486
487 if (pmu->version == 1) {
Gleb Natapovf19a0c22012-04-09 17:38:35 +0300488 pmu->nr_arch_fixed_counters = 0;
489 } else {
Nadav Amitd27aa7f2014-08-20 13:25:52 +0300490 pmu->nr_arch_fixed_counters =
491 min_t(int, edx.split.num_counters_fixed,
Robert Richter15c7ad52012-06-20 20:46:33 +0200492 INTEL_PMC_MAX_FIXED);
Gleb Natapovf19a0c22012-04-09 17:38:35 +0300493 pmu->counter_bitmask[KVM_PMC_FIXED] =
Nadav Amitd27aa7f2014-08-20 13:25:52 +0300494 ((u64)1 << edx.split.bit_width_fixed) - 1;
Gleb Natapovf5132b02011-11-10 14:57:22 +0200495 }
496
Gleb Natapovf19a0c22012-04-09 17:38:35 +0300497 pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) |
Robert Richter15c7ad52012-06-20 20:46:33 +0200498 (((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED);
Gleb Natapovf19a0c22012-04-09 17:38:35 +0300499 pmu->global_ctrl_mask = ~pmu->global_ctrl;
Andi Kleen103af0a2013-07-18 15:57:02 -0700500
501 entry = kvm_find_cpuid_entry(vcpu, 7, 0);
502 if (entry &&
503 (boot_cpu_has(X86_FEATURE_HLE) || boot_cpu_has(X86_FEATURE_RTM)) &&
504 (entry->ebx & (X86_FEATURE_HLE|X86_FEATURE_RTM)))
505 pmu->reserved_bits ^= HSW_IN_TX|HSW_IN_TX_CHECKPOINTED;
Gleb Natapovf5132b02011-11-10 14:57:22 +0200506}
507
508void kvm_pmu_init(struct kvm_vcpu *vcpu)
509{
510 int i;
Wei Huang212dba12015-06-19 14:00:33 +0200511 struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200512
513 memset(pmu, 0, sizeof(*pmu));
Robert Richter15c7ad52012-06-20 20:46:33 +0200514 for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) {
Gleb Natapovf5132b02011-11-10 14:57:22 +0200515 pmu->gp_counters[i].type = KVM_PMC_GP;
516 pmu->gp_counters[i].vcpu = vcpu;
517 pmu->gp_counters[i].idx = i;
518 }
Robert Richter15c7ad52012-06-20 20:46:33 +0200519 for (i = 0; i < INTEL_PMC_MAX_FIXED; i++) {
Gleb Natapovf5132b02011-11-10 14:57:22 +0200520 pmu->fixed_counters[i].type = KVM_PMC_FIXED;
521 pmu->fixed_counters[i].vcpu = vcpu;
Robert Richter15c7ad52012-06-20 20:46:33 +0200522 pmu->fixed_counters[i].idx = i + INTEL_PMC_IDX_FIXED;
Gleb Natapovf5132b02011-11-10 14:57:22 +0200523 }
Wei Huangc6702c92015-06-19 13:44:45 +0200524 init_irq_work(&pmu->irq_work, kvm_pmi_trigger_fn);
525 kvm_pmu_refresh(vcpu);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200526}
527
528void kvm_pmu_reset(struct kvm_vcpu *vcpu)
529{
Wei Huang212dba12015-06-19 14:00:33 +0200530 struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200531 int i;
532
533 irq_work_sync(&pmu->irq_work);
Robert Richter15c7ad52012-06-20 20:46:33 +0200534 for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) {
Gleb Natapovf5132b02011-11-10 14:57:22 +0200535 struct kvm_pmc *pmc = &pmu->gp_counters[i];
Wei Huangc6702c92015-06-19 13:44:45 +0200536 pmc_stop_counter(pmc);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200537 pmc->counter = pmc->eventsel = 0;
538 }
539
Robert Richter15c7ad52012-06-20 20:46:33 +0200540 for (i = 0; i < INTEL_PMC_MAX_FIXED; i++)
Wei Huangc6702c92015-06-19 13:44:45 +0200541 pmc_stop_counter(&pmu->fixed_counters[i]);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200542
543 pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status =
544 pmu->global_ovf_ctrl = 0;
545}
546
547void kvm_pmu_destroy(struct kvm_vcpu *vcpu)
548{
549 kvm_pmu_reset(vcpu);
550}
551
Wei Huangc6702c92015-06-19 13:44:45 +0200552void kvm_pmu_handle_event(struct kvm_vcpu *vcpu)
Gleb Natapovf5132b02011-11-10 14:57:22 +0200553{
Wei Huang212dba12015-06-19 14:00:33 +0200554 struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200555 u64 bitmask;
556 int bit;
557
558 bitmask = pmu->reprogram_pmi;
559
560 for_each_set_bit(bit, (unsigned long *)&bitmask, X86_PMC_IDX_MAX) {
561 struct kvm_pmc *pmc = global_idx_to_pmc(pmu, bit);
562
563 if (unlikely(!pmc || !pmc->perf_event)) {
564 clear_bit(bit, (unsigned long *)&pmu->reprogram_pmi);
565 continue;
566 }
567
Wei Huangc6702c92015-06-19 13:44:45 +0200568 reprogram_counter(pmu, bit);
Gleb Natapovf5132b02011-11-10 14:57:22 +0200569 }
570}