KVM
Macros | Functions
pmu.c File Reference
#include <linux/kvm_host.h>
#include <linux/perf_event.h>
Include dependency graph for pmu.c:

Go to the source code of this file.

Macros

#define PMEVTYPER_READ_CASE(idx)
 
#define PMEVTYPER_WRITE_CASE(idx)
 
#define PMEVTYPER_CASES(readwrite)
 

Functions

static DEFINE_PER_CPU (struct kvm_pmu_events, kvm_pmu_events)
 
static bool kvm_pmu_switch_needed (struct perf_event_attr *attr)
 
struct kvm_pmu_events * kvm_get_pmu_events (void)
 
void kvm_set_pmu_events (u32 set, struct perf_event_attr *attr)
 
void kvm_clr_pmu_events (u32 clr)
 
static u64 kvm_vcpu_pmu_read_evtype_direct (int idx)
 
static void kvm_vcpu_pmu_write_evtype_direct (int idx, u32 val)
 
static void kvm_vcpu_pmu_enable_el0 (unsigned long events)
 
static void kvm_vcpu_pmu_disable_el0 (unsigned long events)
 
void kvm_vcpu_pmu_restore_guest (struct kvm_vcpu *vcpu)
 
void kvm_vcpu_pmu_restore_host (struct kvm_vcpu *vcpu)
 
bool kvm_set_pmuserenr (u64 val)
 
void kvm_vcpu_pmu_resync_el0 (void)
 

Macro Definition Documentation

◆ PMEVTYPER_CASES

#define PMEVTYPER_CASES (   readwrite)

Definition at line 74 of file pmu.c.

◆ PMEVTYPER_READ_CASE

#define PMEVTYPER_READ_CASE (   idx)
Value:
case idx: \
return read_sysreg(pmevtyper##idx##_el0)

Definition at line 65 of file pmu.c.

◆ PMEVTYPER_WRITE_CASE

#define PMEVTYPER_WRITE_CASE (   idx)
Value:
case idx: \
write_sysreg(val, pmevtyper##idx##_el0); \
break

Definition at line 69 of file pmu.c.

Function Documentation

◆ DEFINE_PER_CPU()

static DEFINE_PER_CPU ( struct kvm_pmu_events  ,
kvm_pmu_events   
)
static

◆ kvm_clr_pmu_events()

void kvm_clr_pmu_events ( u32  clr)

Definition at line 54 of file pmu.c.

55 {
56  struct kvm_pmu_events *pmu = kvm_get_pmu_events();
57 
59  return;
60 
61  pmu->events_host &= ~clr;
62  pmu->events_guest &= ~clr;
63 }
static bool kvm_arm_support_pmu_v3(void)
Definition: arm_pmu.h:113
struct kvm_pmu_events * kvm_get_pmu_events(void)
Definition: pmu.c:29
Here is the call graph for this function:

◆ kvm_get_pmu_events()

struct kvm_pmu_events* kvm_get_pmu_events ( void  )

Definition at line 29 of file pmu.c.

30 {
31  return this_cpu_ptr(&kvm_pmu_events);
32 }
Here is the caller graph for this function:

◆ kvm_pmu_switch_needed()

static bool kvm_pmu_switch_needed ( struct perf_event_attr *  attr)
static

With VHE the guest kernel runs at EL1 and the host at EL2, where user (EL0) is excluded then we have no reason to switch counters.

Definition at line 15 of file pmu.c.

16 {
17  /**
18  * With VHE the guest kernel runs at EL1 and the host at EL2,
19  * where user (EL0) is excluded then we have no reason to switch
20  * counters.
21  */
22  if (has_vhe() && attr->exclude_user)
23  return false;
24 
25  /* Only switch if attributes are different */
26  return (attr->exclude_host != attr->exclude_guest);
27 }
Here is the caller graph for this function:

◆ kvm_set_pmu_events()

void kvm_set_pmu_events ( u32  set,
struct perf_event_attr *  attr 
)

Definition at line 38 of file pmu.c.

39 {
40  struct kvm_pmu_events *pmu = kvm_get_pmu_events();
41 
43  return;
44 
45  if (!attr->exclude_host)
46  pmu->events_host |= set;
47  if (!attr->exclude_guest)
48  pmu->events_guest |= set;
49 }
static bool kvm_pmu_switch_needed(struct perf_event_attr *attr)
Definition: pmu.c:15
Here is the call graph for this function:

◆ kvm_set_pmuserenr()

bool kvm_set_pmuserenr ( u64  val)

Definition at line 223 of file pmu.c.

224 {
225  struct kvm_cpu_context *hctxt;
226  struct kvm_vcpu *vcpu;
227 
228  if (!kvm_arm_support_pmu_v3() || !has_vhe())
229  return false;
230 
231  vcpu = kvm_get_running_vcpu();
232  if (!vcpu || !vcpu_get_flag(vcpu, PMUSERENR_ON_CPU))
233  return false;
234 
235  hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
236  ctxt_sys_reg(hctxt, PMUSERENR_EL0) = val;
237  return true;
238 }
struct kvm_vcpu * kvm_get_running_vcpu(void)
Definition: kvm_main.c:6338
Here is the call graph for this function:

◆ kvm_vcpu_pmu_disable_el0()

static void kvm_vcpu_pmu_disable_el0 ( unsigned long  events)
static

Definition at line 158 of file pmu.c.

159 {
160  u64 typer;
161  u32 counter;
162 
163  for_each_set_bit(counter, &events, 32) {
164  typer = kvm_vcpu_pmu_read_evtype_direct(counter);
165  typer |= ARMV8_PMU_EXCLUDE_EL0;
166  kvm_vcpu_pmu_write_evtype_direct(counter, typer);
167  }
168 }
static u64 kvm_vcpu_pmu_read_evtype_direct(int idx)
Definition: pmu.c:111
static void kvm_vcpu_pmu_write_evtype_direct(int idx, u32 val)
Definition: pmu.c:128
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_vcpu_pmu_enable_el0()

static void kvm_vcpu_pmu_enable_el0 ( unsigned long  events)
static

Definition at line 143 of file pmu.c.

144 {
145  u64 typer;
146  u32 counter;
147 
148  for_each_set_bit(counter, &events, 32) {
149  typer = kvm_vcpu_pmu_read_evtype_direct(counter);
150  typer &= ~ARMV8_PMU_EXCLUDE_EL0;
151  kvm_vcpu_pmu_write_evtype_direct(counter, typer);
152  }
153 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_vcpu_pmu_read_evtype_direct()

static u64 kvm_vcpu_pmu_read_evtype_direct ( int  idx)
static

Definition at line 111 of file pmu.c.

112 {
113  switch (idx) {
114  PMEVTYPER_CASES(READ);
115  case ARMV8_PMU_CYCLE_IDX:
116  return read_sysreg(pmccfiltr_el0);
117  default:
118  WARN_ON(1);
119  }
120 
121  return 0;
122 }
#define ARMV8_PMU_CYCLE_IDX
Definition: arm_pmu.h:13
#define PMEVTYPER_CASES(readwrite)
Definition: pmu.c:74
Here is the caller graph for this function:

◆ kvm_vcpu_pmu_restore_guest()

void kvm_vcpu_pmu_restore_guest ( struct kvm_vcpu *  vcpu)

Definition at line 176 of file pmu.c.

177 {
178  struct kvm_pmu_events *pmu;
179  u32 events_guest, events_host;
180 
181  if (!kvm_arm_support_pmu_v3() || !has_vhe())
182  return;
183 
184  preempt_disable();
185  pmu = kvm_get_pmu_events();
186  events_guest = pmu->events_guest;
187  events_host = pmu->events_host;
188 
189  kvm_vcpu_pmu_enable_el0(events_guest);
190  kvm_vcpu_pmu_disable_el0(events_host);
191  preempt_enable();
192 }
static void kvm_vcpu_pmu_enable_el0(unsigned long events)
Definition: pmu.c:143
static void kvm_vcpu_pmu_disable_el0(unsigned long events)
Definition: pmu.c:158
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_vcpu_pmu_restore_host()

void kvm_vcpu_pmu_restore_host ( struct kvm_vcpu *  vcpu)

Definition at line 197 of file pmu.c.

198 {
199  struct kvm_pmu_events *pmu;
200  u32 events_guest, events_host;
201 
202  if (!kvm_arm_support_pmu_v3() || !has_vhe())
203  return;
204 
205  pmu = kvm_get_pmu_events();
206  events_guest = pmu->events_guest;
207  events_host = pmu->events_host;
208 
209  kvm_vcpu_pmu_enable_el0(events_host);
210  kvm_vcpu_pmu_disable_el0(events_guest);
211 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_vcpu_pmu_resync_el0()

void kvm_vcpu_pmu_resync_el0 ( void  )

Definition at line 244 of file pmu.c.

245 {
246  struct kvm_vcpu *vcpu;
247 
248  if (!has_vhe() || !in_interrupt())
249  return;
250 
251  vcpu = kvm_get_running_vcpu();
252  if (!vcpu)
253  return;
254 
255  kvm_make_request(KVM_REQ_RESYNC_PMU_EL0, vcpu);
256 }
Here is the call graph for this function:

◆ kvm_vcpu_pmu_write_evtype_direct()

static void kvm_vcpu_pmu_write_evtype_direct ( int  idx,
u32  val 
)
static

Definition at line 128 of file pmu.c.

129 {
130  switch (idx) {
131  PMEVTYPER_CASES(WRITE);
132  case ARMV8_PMU_CYCLE_IDX:
133  write_sysreg(val, pmccfiltr_el0);
134  break;
135  default:
136  WARN_ON(1);
137  }
138 }
Here is the caller graph for this function: