1 #include <linux/bitops.h>
2 #include <linux/types.h>
3 #include <linux/slab.h>
5 #include <asm/perf_event.h>
11 #define BTS_RECORD_SIZE 24
13 #define BTS_BUFFER_SIZE (PAGE_SIZE << 4)
14 #define PEBS_BUFFER_SIZE PAGE_SIZE
52 (
u32)((
u64)(
unsigned long)ds),
53 (
u32)((
u64)(
unsigned long)ds >> 32));
64 static int alloc_pebs_buffer(
int cpu)
91 static void release_pebs_buffer(
int cpu)
102 static int alloc_bts_buffer(
int cpu)
129 static void release_bts_buffer(
int cpu)
140 static int alloc_ds_buffer(
int cpu)
154 static void release_ds_buffer(
int cpu)
177 release_pebs_buffer(cpu);
178 release_bts_buffer(cpu);
179 release_ds_buffer(cpu);
186 int bts_err = 0, pebs_err = 0;
204 if (alloc_ds_buffer(cpu)) {
209 if (!bts_err && alloc_bts_buffer(cpu))
212 if (!pebs_err && alloc_pebs_buffer(cpu))
215 if (bts_err && pebs_err)
221 release_bts_buffer(cpu);
226 release_pebs_buffer(cpu);
229 if (bts_err && pebs_err) {
231 release_ds_buffer(cpu);
255 unsigned long debugctlmsr;
257 debugctlmsr = get_debugctlmsr();
269 update_debugctlmsr(debugctlmsr);
275 unsigned long debugctlmsr;
280 debugctlmsr = get_debugctlmsr();
286 update_debugctlmsr(debugctlmsr);
299 struct bts_record *
at, *
top;
302 struct perf_sample_data data;
312 top = (
struct bts_record *)(
unsigned long)ds->
bts_index;
319 perf_sample_data_init(&data, 0,
event->hw.last_period);
332 for (; at <
top; at++) {
342 event->hw.interrupts++;
428 if (!event->
attr.precise_ip)
433 if ((event->hw.config & c->
cmask) == c->
code)
479 static int intel_pmu_pebs_fixup_ip(
struct pt_regs *
regs)
483 unsigned long old_to, to = cpuc->
lbr_entries[0].to;
484 unsigned long ip = regs->ip;
502 if (kernel_ip(ip) != kernel_ip(to))
516 set_linear_ip(regs, from);
526 if (!kernel_ip(ip)) {
538 is_64bit = kernel_ip(to) || !test_thread_flag(
TIF_IA32);
546 set_linear_ip(regs, old_to);
558 struct pt_regs *iregs,
void *__pebs)
567 struct perf_sample_data
data;
573 perf_sample_data_init(&
data, 0, event->hw.last_period);
587 set_linear_ip(®s, pebs->
ip);
591 if (event->
attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(®s))
592 regs.
flags |= PERF_EFLAGS_EXACT;
594 regs.
flags &= ~PERF_EFLAGS_EXACT;
596 if (has_branch_stack(event))
603 static void intel_pmu_drain_pebs_core(
struct pt_regs *iregs)
627 if (!event->
attr.precise_ip)
638 WARN_ONCE(n > 1,
"bad leftover pebs %d\n", n);
641 __intel_pmu_pebs_event(event, iregs, at);
644 static void intel_pmu_drain_pebs_nhm(
struct pt_regs *iregs)
671 for ( ; at <
top; at++) {
679 if (!event->
attr.precise_ip)
691 __intel_pmu_pebs_event(event, iregs, at);