1 // SPDX-License-Identifier: GPL-2.0
3 * Implement support for AMD Fam19h Branch Sampling feature
4 * Based on specifications published in AMD PPR Fam19 Model 01
6 * Copyright 2021 Google LLC
7 * Contributed by Stephane Eranian <eranian@google.com>
9 #include <linux/kernel.h>
10 #include <linux/jump_label.h>
12 #include <asm/cpufeature.h>
14 #include "../perf_event.h"
16 #define BRS_POISON 0xFFFFFFFFFFFFFFFEULL /* mark limit of valid entries */
18 /* Debug Extension Configuration register layout */
19 union amd_debug_extn_cfg {
22 __u64 rsvd0:2, /* reserved */
23 brsmen:1, /* branch sample enable */
24 rsvd4_3:2,/* reserved - must be 0x3 */
25 vb:1, /* valid branches recorded */
26 rsvd2:10, /* reserved */
27 msroff:4, /* index of next entry to write */
28 rsvd3:4, /* reserved */
29 pmc:3, /* #PMC holding the sampling event */
30 rsvd4:37; /* reserved */
34 static inline unsigned int brs_from(int idx)
36 return MSR_AMD_SAMP_BR_FROM + 2 * idx;
39 static inline unsigned int brs_to(int idx)
41 return MSR_AMD_SAMP_BR_FROM + 2 * idx + 1;
44 static inline void set_debug_extn_cfg(u64 val)
46 /* bits[4:3] must always be set to 11b */
47 wrmsrl(MSR_AMD_DBG_EXTN_CFG, val | 3ULL << 3);
50 static inline u64 get_debug_extn_cfg(void)
54 rdmsrl(MSR_AMD_DBG_EXTN_CFG, val);
58 static bool __init amd_brs_detect(void)
60 if (!cpu_feature_enabled(X86_FEATURE_BRS))
63 switch (boot_cpu_data.x86) {
64 case 0x19: /* AMD Fam19h (Zen3) */
67 /* No hardware filtering supported */
68 x86_pmu.lbr_sel_map = NULL;
69 x86_pmu.lbr_sel_mask = 0;
79 * Current BRS implementation does not support branch type or privilege level
80 * filtering. Therefore, this function simply enforces these limitations. No need for
81 * a br_sel_map. Software filtering is not supported because it would not correlate well
82 * with a sampling period.
84 static int amd_brs_setup_filter(struct perf_event *event)
86 u64 type = event->attr.branch_sample_type;
92 /* Can only capture all branches, i.e., no filtering */
93 if ((type & ~PERF_SAMPLE_BRANCH_PLM_ALL) != PERF_SAMPLE_BRANCH_ANY)
99 static inline int amd_is_brs_event(struct perf_event *e)
101 return (e->hw.config & AMD64_RAW_EVENT_MASK) == AMD_FAM19H_BRS_EVENT;
104 int amd_brs_hw_config(struct perf_event *event)
109 * Due to interrupt holding, BRS is not recommended in
112 if (!is_sampling_event(event))
116 * Due to the way BRS operates by holding the interrupt until
117 * lbr_nr entries have been captured, it does not make sense
118 * to allow sampling on BRS with an event that does not match
119 * what BRS is capturing, i.e., retired taken branches.
120 * Otherwise the correlation with the event's period is even
123 * With retired taken branch:
124 * Effective P = P + 16 + X
125 * With any other event:
126 * Effective P = P + Y + X
128 * Where X is the number of taken branches due to interrupt
129 * skid. Skid is large.
131 * Where Y is the occurences of the event while BRS is
132 * capturing the lbr_nr entries.
134 * By using retired taken branches, we limit the impact on the
135 * Y variable. We know it cannot be more than the depth of
138 if (!amd_is_brs_event(event))
142 * BRS implementation does not work with frequency mode
143 * reprogramming of the period.
145 if (event->attr.freq)
148 * The kernel subtracts BRS depth from period, so it must
151 if (event->attr.sample_period <= x86_pmu.lbr_nr)
155 * Check if we can allow PERF_SAMPLE_BRANCH_STACK
157 ret = amd_brs_setup_filter(event);
159 /* only set in case of success */
161 event->hw.flags |= PERF_X86_EVENT_AMD_BRS;
166 /* tos = top of stack, i.e., last valid entry written */
167 static inline int amd_brs_get_tos(union amd_debug_extn_cfg *cfg)
170 * msroff: index of next entry to write so top-of-stack is one off
171 * if BRS is full then msroff is set back to 0.
173 return (cfg->msroff ? cfg->msroff : x86_pmu.lbr_nr) - 1;
177 * make sure we have a sane BRS offset to begin with
178 * especially with kexec
180 void amd_brs_reset(void)
182 if (!cpu_feature_enabled(X86_FEATURE_BRS))
188 set_debug_extn_cfg(0);
191 * Mark first entry as poisoned
193 wrmsrl(brs_to(0), BRS_POISON);
196 int __init amd_brs_init(void)
198 if (!amd_brs_detect())
201 pr_cont("%d-deep BRS, ", x86_pmu.lbr_nr);
206 void amd_brs_enable(void)
208 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
209 union amd_debug_extn_cfg cfg;
211 /* Activate only on first user */
212 if (++cpuc->brs_active > 1)
215 cfg.val = 0; /* reset all fields */
216 cfg.brsmen = 1; /* enable branch sampling */
219 set_debug_extn_cfg(cfg.val);
222 void amd_brs_enable_all(void)
224 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
229 void amd_brs_disable(void)
231 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
232 union amd_debug_extn_cfg cfg;
234 /* Check if active (could be disabled via x86_pmu_disable_all()) */
235 if (!cpuc->brs_active)
238 /* Only disable for last user */
239 if (--cpuc->brs_active)
243 * Clear the brsmen bit but preserve the others as they contain
244 * useful state such as vb and msroff
246 cfg.val = get_debug_extn_cfg();
249 * When coming in on interrupt and BRS is full, then hw will have
250 * already stopped BRS, no need to issue wrmsr again
254 set_debug_extn_cfg(cfg.val);
258 void amd_brs_disable_all(void)
260 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
265 static bool amd_brs_match_plm(struct perf_event *event, u64 to)
267 int type = event->attr.branch_sample_type;
268 int plm_k = PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_HV;
269 int plm_u = PERF_SAMPLE_BRANCH_USER;
271 if (!(type & plm_k) && kernel_ip(to))
274 if (!(type & plm_u) && !kernel_ip(to))
281 * Caller must ensure amd_brs_inuse() is true before calling
284 void amd_brs_drain(void)
286 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
287 struct perf_event *event = cpuc->events[0];
288 struct perf_branch_entry *br = cpuc->lbr_entries;
289 union amd_debug_extn_cfg cfg;
290 u32 i, nr = 0, num, tos, start;
291 u32 shift = 64 - boot_cpu_data.x86_virt_bits;
294 * BRS event forced on PMC0,
295 * so check if there is an event.
296 * It is possible to have lbr_users > 0 but the event
297 * not yet scheduled due to long latency PMU irq
302 cfg.val = get_debug_extn_cfg();
304 /* Sanity check [0-x86_pmu.lbr_nr] */
305 if (WARN_ON_ONCE(cfg.msroff >= x86_pmu.lbr_nr))
308 /* No valid branch */
313 * msr.off points to next entry to be written
314 * tos = most recent entry index = msr.off - 1
315 * BRS register buffer saturates, so we know we have
316 * start < tos and that we have to read from start to tos
319 tos = amd_brs_get_tos(&cfg);
321 num = tos - start + 1;
324 * BRS is only one pass (saturation) from MSROFF to depth-1
325 * MSROFF wraps to zero when buffer is full
327 for (i = 0; i < num; i++) {
328 u32 brs_idx = tos - i;
331 rdmsrl(brs_to(brs_idx), to);
333 /* Entry does not belong to us (as marked by kernel) */
334 if (to == BRS_POISON)
338 * Sign-extend SAMP_BR_TO to 64 bits, bits 61-63 are reserved.
339 * Necessary to generate proper virtual addresses suitable for
342 to = (u64)(((s64)to << shift) >> shift);
344 if (!amd_brs_match_plm(event, to))
347 rdmsrl(brs_from(brs_idx), from);
349 perf_clear_branch_entry_bitfields(br+nr);
357 /* Record number of sampled branches */
358 cpuc->lbr_stack.nr = nr;
362 * Poison most recent entry to prevent reuse by next task
363 * required because BRS entry are not tagged by PID
365 static void amd_brs_poison_buffer(void)
367 union amd_debug_extn_cfg cfg;
370 /* Get current state */
371 cfg.val = get_debug_extn_cfg();
373 /* idx is most recently written entry */
374 idx = amd_brs_get_tos(&cfg);
376 /* Poison target of entry */
377 wrmsrl(brs_to(idx), BRS_POISON);
381 * On context switch in, we need to make sure no samples from previous user
382 * are left in the BRS.
384 * On ctxswin, sched_in = true, called after the PMU has started
385 * On ctxswout, sched_in = false, called before the PMU is stopped
387 void amd_pmu_brs_sched_task(struct perf_event_context *ctx, bool sched_in)
389 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
391 /* no active users */
392 if (!cpuc->lbr_users)
396 * On context switch in, we need to ensure we do not use entries
397 * from previous BRS user on that CPU, so we poison the buffer as
398 * a faster way compared to resetting all entries.
401 amd_brs_poison_buffer();
405 * called from ACPI processor_idle.c or acpi_pad.c
406 * with interrupts disabled
408 void perf_amd_brs_lopwr_cb(bool lopwr_in)
410 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
411 union amd_debug_extn_cfg cfg;
414 * on mwait in, we may end up in non C0 state.
415 * we must disable branch sampling to avoid holding the NMI
416 * for too long. We disable it in hardware but we
417 * keep the state in cpuc, so we can re-enable.
419 * The hardware will deliver the NMI if needed when brsmen cleared
421 if (cpuc->brs_active) {
422 cfg.val = get_debug_extn_cfg();
423 cfg.brsmen = !lopwr_in;
424 set_debug_extn_cfg(cfg.val);
428 DEFINE_STATIC_CALL_NULL(perf_lopwr_cb, perf_amd_brs_lopwr_cb);
429 EXPORT_STATIC_CALL_TRAMP_GPL(perf_lopwr_cb);
431 void __init amd_brs_lopwr_init(void)
433 static_call_update(perf_lopwr_cb, perf_amd_brs_lopwr_cb);