1 #include <linux/perf_event.h>
2 #include <linux/types.h>
4 #include <asm/perf_event.h>
23 #define LBR_KERNEL_BIT 0
24 #define LBR_USER_BIT 1
26 #define LBR_REL_CALL_BIT 3
27 #define LBR_IND_CALL_BIT 4
28 #define LBR_RETURN_BIT 5
29 #define LBR_IND_JMP_BIT 6
30 #define LBR_REL_JMP_BIT 7
33 #define LBR_KERNEL (1 << LBR_KERNEL_BIT)
34 #define LBR_USER (1 << LBR_USER_BIT)
35 #define LBR_JCC (1 << LBR_JCC_BIT)
36 #define LBR_REL_CALL (1 << LBR_REL_CALL_BIT)
37 #define LBR_IND_CALL (1 << LBR_IND_CALL_BIT)
38 #define LBR_RETURN (1 << LBR_RETURN_BIT)
39 #define LBR_REL_JMP (1 << LBR_REL_JMP_BIT)
40 #define LBR_IND_JMP (1 << LBR_IND_JMP_BIT)
41 #define LBR_FAR (1 << LBR_FAR_BIT)
43 #define LBR_PLM (LBR_KERNEL | LBR_USER)
45 #define LBR_SEL_MASK 0x1ff
46 #define LBR_NOT_SUPP -1
58 #define LBR_FROM_FLAG_MISPRED (1ULL << 63)
60 #define for_each_branch_sample_type(x) \
61 for ((x) = PERF_SAMPLE_BRANCH_USER; \
62 (x) < PERF_SAMPLE_BRANCH_MAX; (x) <<= 1)
86 #define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
100 #define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
102 #define X86_BR_ANY_CALL \
109 static void intel_pmu_lbr_filter(
struct cpu_hw_events *cpuc);
116 static void __intel_pmu_lbr_enable(
void)
129 static void __intel_pmu_lbr_disable(
void)
138 static void intel_pmu_lbr_reset_32(
void)
146 static void intel_pmu_lbr_reset_64(
void)
162 intel_pmu_lbr_reset_32();
164 intel_pmu_lbr_reset_64();
178 if (event->ctx->task && cpuc->
lbr_context != event->ctx) {
182 cpuc->
br_sel =
event->hw.branch_reg.reg;
198 __intel_pmu_lbr_disable();
209 __intel_pmu_lbr_enable();
217 __intel_pmu_lbr_disable();
223 static inline u64 intel_pmu_lbr_tos(
void)
232 static void intel_pmu_lbr_read_32(
struct cpu_hw_events *cpuc)
235 u64 tos = intel_pmu_lbr_tos();
239 unsigned long lbr_idx = (tos -
i) & mask;
264 static void intel_pmu_lbr_read_64(
struct cpu_hw_events *cpuc)
268 u64 tos = intel_pmu_lbr_tos();
272 unsigned long lbr_idx = (tos -
i) & mask;
281 from = (
u64)((((
s64)from) << 1) >> 1);
301 intel_pmu_lbr_read_32(cpuc);
303 intel_pmu_lbr_read_64(cpuc);
305 intel_pmu_lbr_filter(cpuc);
315 u64 br_type =
event->attr.branch_sample_type;
341 event->hw.branch_reg.reg =
mask;
349 static int intel_pmu_setup_hw_lbr_filter(
struct perf_event *event)
352 u64 br_type =
event->attr.branch_sample_type;
367 reg = &
event->hw.branch_reg;
389 intel_pmu_setup_sw_lbr_filter(event);
395 ret = intel_pmu_setup_hw_lbr_filter(event);
411 static int branch_type(
unsigned long from,
unsigned long to)
417 int ext, to_plm, from_plm;
428 if (from == 0 || to == 0)
453 is64 = kernel_ip((
unsigned long)addr) || !test_thread_flag(
TIF_IA32);
554 int br_sel = cpuc->
br_sel;
556 bool compress =
false;
562 for (i = 0; i < cpuc->
lbr_stack.nr; i++) {
567 type = branch_type(from, to);
570 if (type ==
X86_BR_NONE || (br_sel & type) != type) {
583 while (++j < cpuc->lbr_stack.nr)
691 pr_cont(
"LBR disabled due to erratum");