KVM
Macros | Enumerations | Functions | Variables
pmu.c File Reference
#include <linux/types.h>
#include <linux/kvm_host.h>
#include <linux/perf_event.h>
#include "x86.h"
#include "cpuid.h"
#include "lapic.h"
#include "pmu.h"
#include "svm.h"
Include dependency graph for pmu.c:

Go to the source code of this file.

Macros

#define pr_fmt(fmt)   KBUILD_MODNAME ": " fmt
 

Enumerations

enum  pmu_type { PMU_TYPE_COUNTER = 0 , PMU_TYPE_EVNTSEL }
 

Functions

static struct kvm_pmc * amd_pmc_idx_to_pmc (struct kvm_pmu *pmu, int pmc_idx)
 
static struct kvm_pmc * get_gp_pmc_amd (struct kvm_pmu *pmu, u32 msr, enum pmu_type type)
 
static bool amd_hw_event_available (struct kvm_pmc *pmc)
 
static bool amd_is_valid_rdpmc_ecx (struct kvm_vcpu *vcpu, unsigned int idx)
 
static struct kvm_pmc * amd_rdpmc_ecx_to_pmc (struct kvm_vcpu *vcpu, unsigned int idx, u64 *mask)
 
static struct kvm_pmc * amd_msr_idx_to_pmc (struct kvm_vcpu *vcpu, u32 msr)
 
static bool amd_is_valid_msr (struct kvm_vcpu *vcpu, u32 msr)
 
static int amd_pmu_get_msr (struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 
static int amd_pmu_set_msr (struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 
static void amd_pmu_refresh (struct kvm_vcpu *vcpu)
 
static void amd_pmu_init (struct kvm_vcpu *vcpu)
 

Variables

struct kvm_pmu_ops amd_pmu_ops __initdata
 

Macro Definition Documentation

◆ pr_fmt

#define pr_fmt (   fmt)    KBUILD_MODNAME ": " fmt

Definition at line 12 of file pmu.c.

Enumeration Type Documentation

◆ pmu_type

enum pmu_type
Enumerator
PMU_TYPE_COUNTER 
PMU_TYPE_EVNTSEL 

Definition at line 23 of file pmu.c.

23  {
24  PMU_TYPE_COUNTER = 0,
26 };
@ PMU_TYPE_COUNTER
Definition: pmu.c:24
@ PMU_TYPE_EVNTSEL
Definition: pmu.c:25

Function Documentation

◆ amd_hw_event_available()

static bool amd_hw_event_available ( struct kvm_pmc *  pmc)
static

Definition at line 76 of file pmu.c.

77 {
78  return true;
79 }

◆ amd_is_valid_msr()

static bool amd_is_valid_msr ( struct kvm_vcpu *  vcpu,
u32  msr 
)
static

Definition at line 108 of file pmu.c.

109 {
110  struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
111 
112  switch (msr) {
113  case MSR_K7_EVNTSEL0 ... MSR_K7_PERFCTR3:
114  return pmu->version > 0;
115  case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5:
116  return guest_cpuid_has(vcpu, X86_FEATURE_PERFCTR_CORE);
117  case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS:
118  case MSR_AMD64_PERF_CNTR_GLOBAL_CTL:
119  case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR:
120  return pmu->version > 1;
121  default:
122  if (msr > MSR_F15H_PERF_CTR5 &&
123  msr < MSR_F15H_PERF_CTL0 + 2 * pmu->nr_arch_gp_counters)
124  return pmu->version > 1;
125  break;
126  }
127 
128  return amd_msr_idx_to_pmc(vcpu, msr);
129 }
static __always_inline bool guest_cpuid_has(struct kvm_vcpu *vcpu, unsigned int x86_feature)
Definition: cpuid.h:83
#define vcpu_to_pmu(vcpu)
Definition: pmu.h:7
static struct kvm_pmc * amd_msr_idx_to_pmc(struct kvm_vcpu *vcpu, u32 msr)
Definition: pmu.c:97
Here is the call graph for this function:

◆ amd_is_valid_rdpmc_ecx()

static bool amd_is_valid_rdpmc_ecx ( struct kvm_vcpu *  vcpu,
unsigned int  idx 
)
static

Definition at line 81 of file pmu.c.

82 {
83  struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
84 
85  idx &= ~(3u << 30);
86 
87  return idx < pmu->nr_arch_gp_counters;
88 }

◆ amd_msr_idx_to_pmc()

static struct kvm_pmc* amd_msr_idx_to_pmc ( struct kvm_vcpu *  vcpu,
u32  msr 
)
static

Definition at line 97 of file pmu.c.

98 {
99  struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
100  struct kvm_pmc *pmc;
101 
102  pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_COUNTER);
103  pmc = pmc ? pmc : get_gp_pmc_amd(pmu, msr, PMU_TYPE_EVNTSEL);
104 
105  return pmc;
106 }
static struct kvm_pmc * get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr, enum pmu_type type)
Definition: pmu.c:38
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amd_pmc_idx_to_pmc()

static struct kvm_pmc* amd_pmc_idx_to_pmc ( struct kvm_pmu pmu,
int  pmc_idx 
)
static

Definition at line 28 of file pmu.c.

29 {
30  unsigned int num_counters = pmu->nr_arch_gp_counters;
31 
32  if (pmc_idx >= num_counters)
33  return NULL;
34 
35  return &pmu->gp_counters[array_index_nospec(pmc_idx, num_counters)];
36 }
Here is the caller graph for this function:

◆ amd_pmu_get_msr()

static int amd_pmu_get_msr ( struct kvm_vcpu *  vcpu,
struct msr_data *  msr_info 
)
static

Definition at line 131 of file pmu.c.

132 {
133  struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
134  struct kvm_pmc *pmc;
135  u32 msr = msr_info->index;
136 
137  /* MSR_PERFCTRn */
138  pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_COUNTER);
139  if (pmc) {
140  msr_info->data = pmc_read_counter(pmc);
141  return 0;
142  }
143  /* MSR_EVNTSELn */
144  pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_EVNTSEL);
145  if (pmc) {
146  msr_info->data = pmc->eventsel;
147  return 0;
148  }
149 
150  return 1;
151 }
static u64 pmc_read_counter(struct kvm_pmc *pmc)
Definition: pmu.h:65
Here is the call graph for this function:

◆ amd_pmu_init()

static void amd_pmu_init ( struct kvm_vcpu *  vcpu)
static

Definition at line 219 of file pmu.c.

220 {
221  struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
222  int i;
223 
224  BUILD_BUG_ON(KVM_AMD_PMC_MAX_GENERIC > AMD64_NUM_COUNTERS_CORE);
225  BUILD_BUG_ON(KVM_AMD_PMC_MAX_GENERIC > INTEL_PMC_MAX_GENERIC);
226 
227  for (i = 0; i < KVM_AMD_PMC_MAX_GENERIC ; i++) {
228  pmu->gp_counters[i].type = KVM_PMC_GP;
229  pmu->gp_counters[i].vcpu = vcpu;
230  pmu->gp_counters[i].idx = i;
231  pmu->gp_counters[i].current_config = 0;
232  }
233 }

◆ amd_pmu_refresh()

static void amd_pmu_refresh ( struct kvm_vcpu *  vcpu)
static

Definition at line 180 of file pmu.c.

181 {
182  struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
183  union cpuid_0x80000022_ebx ebx;
184 
185  pmu->version = 1;
186  if (guest_cpuid_has(vcpu, X86_FEATURE_PERFMON_V2)) {
187  pmu->version = 2;
188  /*
189  * Note, PERFMON_V2 is also in 0x80000022.0x0, i.e. the guest
190  * CPUID entry is guaranteed to be non-NULL.
191  */
192  BUILD_BUG_ON(x86_feature_cpuid(X86_FEATURE_PERFMON_V2).function != 0x80000022 ||
193  x86_feature_cpuid(X86_FEATURE_PERFMON_V2).index);
194  ebx.full = kvm_find_cpuid_entry_index(vcpu, 0x80000022, 0)->ebx;
195  pmu->nr_arch_gp_counters = ebx.split.num_core_pmc;
196  } else if (guest_cpuid_has(vcpu, X86_FEATURE_PERFCTR_CORE)) {
197  pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS_CORE;
198  } else {
199  pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS;
200  }
201 
202  pmu->nr_arch_gp_counters = min_t(unsigned int, pmu->nr_arch_gp_counters,
203  kvm_pmu_cap.num_counters_gp);
204 
205  if (pmu->version > 1) {
206  pmu->global_ctrl_mask = ~((1ull << pmu->nr_arch_gp_counters) - 1);
207  pmu->global_status_mask = pmu->global_ctrl_mask;
208  }
209 
210  pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1;
211  pmu->reserved_bits = 0xfffffff000280000ull;
212  pmu->raw_event_mask = AMD64_RAW_EVENT_MASK;
213  /* not applicable to AMD; but clean them to prevent any fall out */
214  pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
215  pmu->nr_arch_fixed_counters = 0;
216  bitmap_set(pmu->all_valid_pmc_idx, 0, pmu->nr_arch_gp_counters);
217 }
struct kvm_cpuid_entry2 * kvm_find_cpuid_entry_index(struct kvm_vcpu *vcpu, u32 function, u32 index)
Definition: cpuid.c:1447
struct x86_pmu_capability __read_mostly kvm_pmu_cap
Definition: pmu.c:29
static __always_inline struct cpuid_reg x86_feature_cpuid(unsigned int x86_feature)
Here is the call graph for this function:

◆ amd_pmu_set_msr()

static int amd_pmu_set_msr ( struct kvm_vcpu *  vcpu,
struct msr_data *  msr_info 
)
static

Definition at line 153 of file pmu.c.

154 {
155  struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
156  struct kvm_pmc *pmc;
157  u32 msr = msr_info->index;
158  u64 data = msr_info->data;
159 
160  /* MSR_PERFCTRn */
161  pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_COUNTER);
162  if (pmc) {
163  pmc_write_counter(pmc, data);
164  return 0;
165  }
166  /* MSR_EVNTSELn */
167  pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_EVNTSEL);
168  if (pmc) {
169  data &= ~pmu->reserved_bits;
170  if (data != pmc->eventsel) {
171  pmc->eventsel = data;
173  }
174  return 0;
175  }
176 
177  return 1;
178 }
void pmc_write_counter(struct kvm_pmc *pmc, u64 val)
Definition: pmu.c:303
static void kvm_pmu_request_counter_reprogram(struct kvm_pmc *pmc)
Definition: pmu.h:183
Here is the call graph for this function:

◆ amd_rdpmc_ecx_to_pmc()

static struct kvm_pmc* amd_rdpmc_ecx_to_pmc ( struct kvm_vcpu *  vcpu,
unsigned int  idx,
u64 *  mask 
)
static

Definition at line 91 of file pmu.c.

93 {
94  return amd_pmc_idx_to_pmc(vcpu_to_pmu(vcpu), idx & ~(3u << 30));
95 }
static struct kvm_pmc * amd_pmc_idx_to_pmc(struct kvm_pmu *pmu, int pmc_idx)
Definition: pmu.c:28
Here is the call graph for this function:

◆ get_gp_pmc_amd()

static struct kvm_pmc* get_gp_pmc_amd ( struct kvm_pmu pmu,
u32  msr,
enum pmu_type  type 
)
inlinestatic

Definition at line 38 of file pmu.c.

40 {
41  struct kvm_vcpu *vcpu = pmu_to_vcpu(pmu);
42  unsigned int idx;
43 
44  if (!vcpu->kvm->arch.enable_pmu)
45  return NULL;
46 
47  switch (msr) {
48  case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5:
49  if (!guest_cpuid_has(vcpu, X86_FEATURE_PERFCTR_CORE))
50  return NULL;
51  /*
52  * Each PMU counter has a pair of CTL and CTR MSRs. CTLn
53  * MSRs (accessed via EVNTSEL) are even, CTRn MSRs are odd.
54  */
55  idx = (unsigned int)((msr - MSR_F15H_PERF_CTL0) / 2);
56  if (!(msr & 0x1) != (type == PMU_TYPE_EVNTSEL))
57  return NULL;
58  break;
59  case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3:
60  if (type != PMU_TYPE_EVNTSEL)
61  return NULL;
62  idx = msr - MSR_K7_EVNTSEL0;
63  break;
64  case MSR_K7_PERFCTR0 ... MSR_K7_PERFCTR3:
65  if (type != PMU_TYPE_COUNTER)
66  return NULL;
67  idx = msr - MSR_K7_PERFCTR0;
68  break;
69  default:
70  return NULL;
71  }
72 
73  return amd_pmc_idx_to_pmc(pmu, idx);
74 }
#define pmu_to_vcpu(pmu)
Definition: pmu.h:8
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ __initdata

static struct kvm_x86_init_ops vmx_init_ops __initdata
Initial value:
= {
.hw_event_available = amd_hw_event_available,
.pmc_idx_to_pmc = amd_pmc_idx_to_pmc,
.rdpmc_ecx_to_pmc = amd_rdpmc_ecx_to_pmc,
.msr_idx_to_pmc = amd_msr_idx_to_pmc,
.is_valid_rdpmc_ecx = amd_is_valid_rdpmc_ecx,
.is_valid_msr = amd_is_valid_msr,
.get_msr = amd_pmu_get_msr,
.set_msr = amd_pmu_set_msr,
.refresh = amd_pmu_refresh,
.init = amd_pmu_init,
.EVENTSEL_EVENT = AMD64_EVENTSEL_EVENT,
.MAX_NR_GP_COUNTERS = KVM_AMD_PMC_MAX_GENERIC,
.MIN_NR_GP_COUNTERS = AMD64_NUM_COUNTERS,
}
static void amd_pmu_init(struct kvm_vcpu *vcpu)
Definition: pmu.c:219
static int amd_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
Definition: pmu.c:153
static void amd_pmu_refresh(struct kvm_vcpu *vcpu)
Definition: pmu.c:180
static struct kvm_pmc * amd_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu, unsigned int idx, u64 *mask)
Definition: pmu.c:91
static int amd_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
Definition: pmu.c:131
static bool amd_is_valid_rdpmc_ecx(struct kvm_vcpu *vcpu, unsigned int idx)
Definition: pmu.c:81
static bool amd_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
Definition: pmu.c:108
static bool amd_hw_event_available(struct kvm_pmc *pmc)
Definition: pmu.c:76

Definition at line 219 of file pmu.c.