blob: 96cfc1a4fe9fb0c764a2209ea84628f1cd689ecc [file] [log] [blame]
Ingo Molnar241771e2008-12-03 10:39:53 +01001/*
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002 * Performance events x86 architecture code
Ingo Molnar241771e2008-12-03 10:39:53 +01003 *
Ingo Molnar98144512009-04-29 14:52:50 +02004 * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
5 * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
6 * Copyright (C) 2009 Jaswinder Singh Rajput
7 * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
8 * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
Markus Metzger30dd5682009-07-21 15:56:48 +02009 * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
Stephane Eranian1da53e02010-01-18 10:58:01 +020010 * Copyright (C) 2009 Google, Inc., Stephane Eranian
Ingo Molnar241771e2008-12-03 10:39:53 +010011 *
12 * For licencing details see kernel-base/COPYING
13 */
14
Ingo Molnarcdd6c482009-09-21 12:02:48 +020015#include <linux/perf_event.h>
Ingo Molnar241771e2008-12-03 10:39:53 +010016#include <linux/capability.h>
17#include <linux/notifier.h>
18#include <linux/hardirq.h>
19#include <linux/kprobes.h>
Thomas Gleixner4ac13292008-12-09 21:43:39 +010020#include <linux/module.h>
Ingo Molnar241771e2008-12-03 10:39:53 +010021#include <linux/kdebug.h>
22#include <linux/sched.h>
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +020023#include <linux/uaccess.h>
Peter Zijlstra74193ef2009-06-15 13:07:24 +020024#include <linux/highmem.h>
Markus Metzger30dd5682009-07-21 15:56:48 +020025#include <linux/cpu.h>
Peter Zijlstra272d30b2010-01-22 16:32:17 +010026#include <linux/bitops.h>
Ingo Molnar241771e2008-12-03 10:39:53 +010027
Ingo Molnar241771e2008-12-03 10:39:53 +010028#include <asm/apic.h>
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +020029#include <asm/stacktrace.h>
Peter Zijlstra4e935e42009-03-30 19:07:16 +020030#include <asm/nmi.h>
Ingo Molnar241771e2008-12-03 10:39:53 +010031
Ingo Molnarcdd6c482009-09-21 12:02:48 +020032static u64 perf_event_mask __read_mostly;
Ingo Molnar703e9372008-12-17 10:51:15 +010033
Ingo Molnarcdd6c482009-09-21 12:02:48 +020034/* The maximal number of PEBS events: */
35#define MAX_PEBS_EVENTS 4
Markus Metzger30dd5682009-07-21 15:56:48 +020036
37/* The size of a BTS record in bytes: */
38#define BTS_RECORD_SIZE 24
39
40/* The size of a per-cpu BTS buffer in bytes: */
Markus Metzger5622f292009-09-15 13:00:23 +020041#define BTS_BUFFER_SIZE (BTS_RECORD_SIZE * 2048)
Markus Metzger30dd5682009-07-21 15:56:48 +020042
43/* The BTS overflow threshold in bytes from the end of the buffer: */
Markus Metzger5622f292009-09-15 13:00:23 +020044#define BTS_OVFL_TH (BTS_RECORD_SIZE * 128)
Markus Metzger30dd5682009-07-21 15:56:48 +020045
46
47/*
48 * Bits in the debugctlmsr controlling branch tracing.
49 */
50#define X86_DEBUGCTL_TR (1 << 6)
51#define X86_DEBUGCTL_BTS (1 << 7)
52#define X86_DEBUGCTL_BTINT (1 << 8)
53#define X86_DEBUGCTL_BTS_OFF_OS (1 << 9)
54#define X86_DEBUGCTL_BTS_OFF_USR (1 << 10)
55
56/*
57 * A debug store configuration.
58 *
59 * We only support architectures that use 64bit fields.
60 */
61struct debug_store {
62 u64 bts_buffer_base;
63 u64 bts_index;
64 u64 bts_absolute_maximum;
65 u64 bts_interrupt_threshold;
66 u64 pebs_buffer_base;
67 u64 pebs_index;
68 u64 pebs_absolute_maximum;
69 u64 pebs_interrupt_threshold;
Ingo Molnarcdd6c482009-09-21 12:02:48 +020070 u64 pebs_event_reset[MAX_PEBS_EVENTS];
Markus Metzger30dd5682009-07-21 15:56:48 +020071};
72
Stephane Eranian1da53e02010-01-18 10:58:01 +020073struct event_constraint {
Peter Zijlstrac91e0f52010-01-22 15:25:59 +010074 union {
75 unsigned long idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
76 u64 idxmsk64[1];
77 };
Stephane Eranian1da53e02010-01-18 10:58:01 +020078 int code;
79 int cmask;
Peter Zijlstra272d30b2010-01-22 16:32:17 +010080 int weight;
Stephane Eranian1da53e02010-01-18 10:58:01 +020081};
82
Ingo Molnarcdd6c482009-09-21 12:02:48 +020083struct cpu_hw_events {
Stephane Eranian1da53e02010-01-18 10:58:01 +020084 struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */
Robert Richter43f62012009-04-29 16:55:56 +020085 unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
Mike Galbraith4b39fd92009-01-23 14:36:16 +010086 unsigned long interrupts;
Peter Zijlstrab0f3f282009-03-05 18:08:27 +010087 int enabled;
Markus Metzger30dd5682009-07-21 15:56:48 +020088 struct debug_store *ds;
Stephane Eranian1da53e02010-01-18 10:58:01 +020089
90 int n_events;
91 int n_added;
92 int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
93 struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */
Ingo Molnar241771e2008-12-03 10:39:53 +010094};
95
Peter Zijlstrafce877e2010-01-29 13:25:12 +010096#define __EVENT_CONSTRAINT(c, n, m, w) {\
Peter Zijlstrac91e0f52010-01-22 15:25:59 +010097 { .idxmsk64[0] = (n) }, \
98 .code = (c), \
99 .cmask = (m), \
Peter Zijlstrafce877e2010-01-29 13:25:12 +0100100 .weight = (w), \
Peter Zijlstrac91e0f52010-01-22 15:25:59 +0100101}
Stephane Eranianb6900812009-10-06 16:42:09 +0200102
Peter Zijlstrafce877e2010-01-29 13:25:12 +0100103#define EVENT_CONSTRAINT(c, n, m) \
104 __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n))
105
Peter Zijlstraed8777f2010-01-27 23:07:46 +0100106#define INTEL_EVENT_CONSTRAINT(c, n) \
107 EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVTSEL_MASK)
Peter Zijlstra8433be12010-01-22 15:38:26 +0100108
Peter Zijlstraed8777f2010-01-27 23:07:46 +0100109#define FIXED_EVENT_CONSTRAINT(c, n) \
110 EVENT_CONSTRAINT(c, n, INTEL_ARCH_FIXED_MASK)
Peter Zijlstra8433be12010-01-22 15:38:26 +0100111
Peter Zijlstraed8777f2010-01-27 23:07:46 +0100112#define EVENT_CONSTRAINT_END \
113 EVENT_CONSTRAINT(0, 0, 0)
114
115#define for_each_event_constraint(e, c) \
116 for ((e) = (c); (e)->cmask; (e)++)
Stephane Eranianb6900812009-10-06 16:42:09 +0200117
Ingo Molnar241771e2008-12-03 10:39:53 +0100118/*
Robert Richter5f4ec282009-04-29 12:47:04 +0200119 * struct x86_pmu - generic x86 pmu
Ingo Molnar241771e2008-12-03 10:39:53 +0100120 */
Robert Richter5f4ec282009-04-29 12:47:04 +0200121struct x86_pmu {
Robert Richterfaa28ae2009-04-29 12:47:13 +0200122 const char *name;
123 int version;
Yong Wanga3288102009-06-03 13:12:55 +0800124 int (*handle_irq)(struct pt_regs *);
Peter Zijlstra9e35ad32009-05-13 16:21:38 +0200125 void (*disable_all)(void);
126 void (*enable_all)(void);
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200127 void (*enable)(struct hw_perf_event *, int);
128 void (*disable)(struct hw_perf_event *, int);
Jaswinder Singh Rajput169e41e2009-02-28 18:37:49 +0530129 unsigned eventsel;
130 unsigned perfctr;
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100131 u64 (*event_map)(int);
132 u64 (*raw_event)(u64);
Jaswinder Singh Rajput169e41e2009-02-28 18:37:49 +0530133 int max_events;
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200134 int num_events;
135 int num_events_fixed;
136 int event_bits;
137 u64 event_mask;
Ingo Molnar04da8a42009-08-11 10:40:08 +0200138 int apic;
Robert Richterc619b8f2009-04-29 12:47:23 +0200139 u64 max_period;
Peter Zijlstra9e35ad32009-05-13 16:21:38 +0200140 u64 intel_ctrl;
Markus Metzger30dd5682009-07-21 15:56:48 +0200141 void (*enable_bts)(u64 config);
142 void (*disable_bts)(void);
Peter Zijlstra63b14642010-01-22 16:32:17 +0100143
144 struct event_constraint *
145 (*get_event_constraints)(struct cpu_hw_events *cpuc,
146 struct perf_event *event);
147
Peter Zijlstrac91e0f52010-01-22 15:25:59 +0100148 void (*put_event_constraints)(struct cpu_hw_events *cpuc,
149 struct perf_event *event);
Peter Zijlstra63b14642010-01-22 16:32:17 +0100150 struct event_constraint *event_constraints;
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +0530151};
152
Robert Richter4a06bd82009-04-29 12:47:11 +0200153static struct x86_pmu x86_pmu __read_mostly;
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +0530154
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200155static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100156 .enabled = 1,
157};
Ingo Molnar241771e2008-12-03 10:39:53 +0100158
Stephane Eranian1da53e02010-01-18 10:58:01 +0200159static int x86_perf_event_set_period(struct perf_event *event,
160 struct hw_perf_event *hwc, int idx);
Stephane Eranianb6900812009-10-06 16:42:09 +0200161
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +0530162/*
Vince Weaver11d15782009-07-08 17:46:14 -0400163 * Not sure about some of these
164 */
165static const u64 p6_perfmon_event_map[] =
166{
167 [PERF_COUNT_HW_CPU_CYCLES] = 0x0079,
168 [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
Ingo Molnarf64cccc2009-08-11 10:26:33 +0200169 [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e,
170 [PERF_COUNT_HW_CACHE_MISSES] = 0x012e,
Vince Weaver11d15782009-07-08 17:46:14 -0400171 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
172 [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
173 [PERF_COUNT_HW_BUS_CYCLES] = 0x0062,
174};
175
Ingo Molnardfc65092009-09-21 11:31:35 +0200176static u64 p6_pmu_event_map(int hw_event)
Vince Weaver11d15782009-07-08 17:46:14 -0400177{
Ingo Molnardfc65092009-09-21 11:31:35 +0200178 return p6_perfmon_event_map[hw_event];
Vince Weaver11d15782009-07-08 17:46:14 -0400179}
180
Peter Zijlstra9c74fb52009-07-08 10:21:41 +0200181/*
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200182 * Event setting that is specified not to count anything.
Peter Zijlstra9c74fb52009-07-08 10:21:41 +0200183 * We use this to effectively disable a counter.
184 *
185 * L2_RQSTS with 0 MESI unit mask.
186 */
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200187#define P6_NOP_EVENT 0x0000002EULL
Peter Zijlstra9c74fb52009-07-08 10:21:41 +0200188
Ingo Molnardfc65092009-09-21 11:31:35 +0200189static u64 p6_pmu_raw_event(u64 hw_event)
Vince Weaver11d15782009-07-08 17:46:14 -0400190{
191#define P6_EVNTSEL_EVENT_MASK 0x000000FFULL
192#define P6_EVNTSEL_UNIT_MASK 0x0000FF00ULL
193#define P6_EVNTSEL_EDGE_MASK 0x00040000ULL
194#define P6_EVNTSEL_INV_MASK 0x00800000ULL
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200195#define P6_EVNTSEL_REG_MASK 0xFF000000ULL
Vince Weaver11d15782009-07-08 17:46:14 -0400196
197#define P6_EVNTSEL_MASK \
198 (P6_EVNTSEL_EVENT_MASK | \
199 P6_EVNTSEL_UNIT_MASK | \
200 P6_EVNTSEL_EDGE_MASK | \
201 P6_EVNTSEL_INV_MASK | \
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200202 P6_EVNTSEL_REG_MASK)
Vince Weaver11d15782009-07-08 17:46:14 -0400203
Ingo Molnardfc65092009-09-21 11:31:35 +0200204 return hw_event & P6_EVNTSEL_MASK;
Vince Weaver11d15782009-07-08 17:46:14 -0400205}
206
Stephane Eranian1da53e02010-01-18 10:58:01 +0200207static struct event_constraint intel_p6_event_constraints[] =
Stephane Eranianb6900812009-10-06 16:42:09 +0200208{
Peter Zijlstra8433be12010-01-22 15:38:26 +0100209 INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FLOPS */
210 INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
211 INTEL_EVENT_CONSTRAINT(0x11, 0x1), /* FP_ASSIST */
212 INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
213 INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
214 INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
Stephane Eranianb6900812009-10-06 16:42:09 +0200215 EVENT_CONSTRAINT_END
216};
Vince Weaver11d15782009-07-08 17:46:14 -0400217
218/*
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +0530219 * Intel PerfMon v3. Used on Core2 and later.
220 */
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100221static const u64 intel_perfmon_event_map[] =
Ingo Molnar241771e2008-12-03 10:39:53 +0100222{
Peter Zijlstraf4dbfa82009-06-11 14:06:28 +0200223 [PERF_COUNT_HW_CPU_CYCLES] = 0x003c,
224 [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
225 [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e,
226 [PERF_COUNT_HW_CACHE_MISSES] = 0x412e,
227 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
228 [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
229 [PERF_COUNT_HW_BUS_CYCLES] = 0x013c,
Ingo Molnar241771e2008-12-03 10:39:53 +0100230};
231
Stephane Eranian1da53e02010-01-18 10:58:01 +0200232static struct event_constraint intel_core_event_constraints[] =
Stephane Eranianb6900812009-10-06 16:42:09 +0200233{
Peter Zijlstra8c48e442010-01-29 13:25:31 +0100234 INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
235 INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
236 INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
237 INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
238 INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
239 INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FP_COMP_INSTR_RET */
240 EVENT_CONSTRAINT_END
241};
242
243static struct event_constraint intel_core2_event_constraints[] =
244{
Peter Zijlstra8433be12010-01-22 15:38:26 +0100245 FIXED_EVENT_CONSTRAINT(0xc0, (0x3|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */
246 FIXED_EVENT_CONSTRAINT(0x3c, (0x3|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */
247 INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
248 INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
249 INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
250 INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
251 INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
252 INTEL_EVENT_CONSTRAINT(0x18, 0x1), /* IDLE_DURING_DIV */
253 INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
254 INTEL_EVENT_CONSTRAINT(0xa1, 0x1), /* RS_UOPS_DISPATCH_CYCLES */
255 INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED */
Stephane Eranianb6900812009-10-06 16:42:09 +0200256 EVENT_CONSTRAINT_END
257};
258
Stephane Eranian1da53e02010-01-18 10:58:01 +0200259static struct event_constraint intel_nehalem_event_constraints[] =
Stephane Eranianb6900812009-10-06 16:42:09 +0200260{
Peter Zijlstra452a3392010-01-27 23:07:48 +0100261 FIXED_EVENT_CONSTRAINT(0xc0, (0xf|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */
262 FIXED_EVENT_CONSTRAINT(0x3c, (0xf|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */
Peter Zijlstra8433be12010-01-22 15:38:26 +0100263 INTEL_EVENT_CONSTRAINT(0x40, 0x3), /* L1D_CACHE_LD */
264 INTEL_EVENT_CONSTRAINT(0x41, 0x3), /* L1D_CACHE_ST */
265 INTEL_EVENT_CONSTRAINT(0x42, 0x3), /* L1D_CACHE_LOCK */
266 INTEL_EVENT_CONSTRAINT(0x43, 0x3), /* L1D_ALL_REF */
Peter Zijlstra452a3392010-01-27 23:07:48 +0100267 INTEL_EVENT_CONSTRAINT(0x48, 0x3), /* L1D_PEND_MISS */
Peter Zijlstra8433be12010-01-22 15:38:26 +0100268 INTEL_EVENT_CONSTRAINT(0x4e, 0x3), /* L1D_PREFETCH */
Peter Zijlstra8433be12010-01-22 15:38:26 +0100269 INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
Peter Zijlstra452a3392010-01-27 23:07:48 +0100270 INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
271 EVENT_CONSTRAINT_END
272};
273
274static struct event_constraint intel_westmere_event_constraints[] =
275{
276 FIXED_EVENT_CONSTRAINT(0xc0, (0xf|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */
277 FIXED_EVENT_CONSTRAINT(0x3c, (0xf|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */
278 INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
279 INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */
280 INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
Stephane Eranian1da53e02010-01-18 10:58:01 +0200281 EVENT_CONSTRAINT_END
282};
283
284static struct event_constraint intel_gen_event_constraints[] =
285{
Peter Zijlstra8433be12010-01-22 15:38:26 +0100286 FIXED_EVENT_CONSTRAINT(0xc0, (0x3|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */
287 FIXED_EVENT_CONSTRAINT(0x3c, (0x3|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */
Stephane Eranianb6900812009-10-06 16:42:09 +0200288 EVENT_CONSTRAINT_END
289};
290
Ingo Molnardfc65092009-09-21 11:31:35 +0200291static u64 intel_pmu_event_map(int hw_event)
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +0530292{
Ingo Molnardfc65092009-09-21 11:31:35 +0200293 return intel_perfmon_event_map[hw_event];
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +0530294}
Ingo Molnar241771e2008-12-03 10:39:53 +0100295
Ingo Molnar8326f442009-06-05 20:22:46 +0200296/*
Ingo Molnardfc65092009-09-21 11:31:35 +0200297 * Generalized hw caching related hw_event table, filled
Ingo Molnar8326f442009-06-05 20:22:46 +0200298 * in on a per model basis. A value of 0 means
Ingo Molnardfc65092009-09-21 11:31:35 +0200299 * 'not supported', -1 means 'hw_event makes no sense on
300 * this CPU', any other value means the raw hw_event
Ingo Molnar8326f442009-06-05 20:22:46 +0200301 * ID.
302 */
303
304#define C(x) PERF_COUNT_HW_CACHE_##x
305
306static u64 __read_mostly hw_cache_event_ids
307 [PERF_COUNT_HW_CACHE_MAX]
308 [PERF_COUNT_HW_CACHE_OP_MAX]
309 [PERF_COUNT_HW_CACHE_RESULT_MAX];
310
Peter Zijlstra452a3392010-01-27 23:07:48 +0100311static __initconst u64 westmere_hw_cache_event_ids
312 [PERF_COUNT_HW_CACHE_MAX]
313 [PERF_COUNT_HW_CACHE_OP_MAX]
314 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
315{
316 [ C(L1D) ] = {
317 [ C(OP_READ) ] = {
318 [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */
319 [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPL */
320 },
321 [ C(OP_WRITE) ] = {
322 [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */
323 [ C(RESULT_MISS) ] = 0x0251, /* L1D.M_REPL */
324 },
325 [ C(OP_PREFETCH) ] = {
326 [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */
327 [ C(RESULT_MISS) ] = 0x024e, /* L1D_PREFETCH.MISS */
328 },
329 },
330 [ C(L1I ) ] = {
331 [ C(OP_READ) ] = {
332 [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
333 [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
334 },
335 [ C(OP_WRITE) ] = {
336 [ C(RESULT_ACCESS) ] = -1,
337 [ C(RESULT_MISS) ] = -1,
338 },
339 [ C(OP_PREFETCH) ] = {
340 [ C(RESULT_ACCESS) ] = 0x0,
341 [ C(RESULT_MISS) ] = 0x0,
342 },
343 },
344 [ C(LL ) ] = {
345 [ C(OP_READ) ] = {
346 [ C(RESULT_ACCESS) ] = 0x0324, /* L2_RQSTS.LOADS */
347 [ C(RESULT_MISS) ] = 0x0224, /* L2_RQSTS.LD_MISS */
348 },
349 [ C(OP_WRITE) ] = {
350 [ C(RESULT_ACCESS) ] = 0x0c24, /* L2_RQSTS.RFOS */
351 [ C(RESULT_MISS) ] = 0x0824, /* L2_RQSTS.RFO_MISS */
352 },
353 [ C(OP_PREFETCH) ] = {
354 [ C(RESULT_ACCESS) ] = 0x4f2e, /* LLC Reference */
355 [ C(RESULT_MISS) ] = 0x412e, /* LLC Misses */
356 },
357 },
358 [ C(DTLB) ] = {
359 [ C(OP_READ) ] = {
360 [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */
361 [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.ANY */
362 },
363 [ C(OP_WRITE) ] = {
364 [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */
365 [ C(RESULT_MISS) ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS */
366 },
367 [ C(OP_PREFETCH) ] = {
368 [ C(RESULT_ACCESS) ] = 0x0,
369 [ C(RESULT_MISS) ] = 0x0,
370 },
371 },
372 [ C(ITLB) ] = {
373 [ C(OP_READ) ] = {
374 [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P */
375 [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.ANY */
376 },
377 [ C(OP_WRITE) ] = {
378 [ C(RESULT_ACCESS) ] = -1,
379 [ C(RESULT_MISS) ] = -1,
380 },
381 [ C(OP_PREFETCH) ] = {
382 [ C(RESULT_ACCESS) ] = -1,
383 [ C(RESULT_MISS) ] = -1,
384 },
385 },
386 [ C(BPU ) ] = {
387 [ C(OP_READ) ] = {
388 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
389 [ C(RESULT_MISS) ] = 0x03e8, /* BPU_CLEARS.ANY */
390 },
391 [ C(OP_WRITE) ] = {
392 [ C(RESULT_ACCESS) ] = -1,
393 [ C(RESULT_MISS) ] = -1,
394 },
395 [ C(OP_PREFETCH) ] = {
396 [ C(RESULT_ACCESS) ] = -1,
397 [ C(RESULT_MISS) ] = -1,
398 },
399 },
400};
401
Hiroshi Shimamotodb48ccc2009-11-12 11:25:34 +0900402static __initconst u64 nehalem_hw_cache_event_ids
Ingo Molnar8326f442009-06-05 20:22:46 +0200403 [PERF_COUNT_HW_CACHE_MAX]
404 [PERF_COUNT_HW_CACHE_OP_MAX]
405 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
406{
407 [ C(L1D) ] = {
408 [ C(OP_READ) ] = {
409 [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI */
410 [ C(RESULT_MISS) ] = 0x0140, /* L1D_CACHE_LD.I_STATE */
411 },
412 [ C(OP_WRITE) ] = {
413 [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI */
414 [ C(RESULT_MISS) ] = 0x0141, /* L1D_CACHE_ST.I_STATE */
415 },
416 [ C(OP_PREFETCH) ] = {
417 [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */
418 [ C(RESULT_MISS) ] = 0x024e, /* L1D_PREFETCH.MISS */
419 },
420 },
421 [ C(L1I ) ] = {
422 [ C(OP_READ) ] = {
Yong Wangfecc8ac2009-06-09 21:15:53 +0800423 [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
Ingo Molnar8326f442009-06-05 20:22:46 +0200424 [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
425 },
426 [ C(OP_WRITE) ] = {
427 [ C(RESULT_ACCESS) ] = -1,
428 [ C(RESULT_MISS) ] = -1,
429 },
430 [ C(OP_PREFETCH) ] = {
431 [ C(RESULT_ACCESS) ] = 0x0,
432 [ C(RESULT_MISS) ] = 0x0,
433 },
434 },
Peter Zijlstra8be6e8f2009-06-11 14:19:11 +0200435 [ C(LL ) ] = {
Ingo Molnar8326f442009-06-05 20:22:46 +0200436 [ C(OP_READ) ] = {
437 [ C(RESULT_ACCESS) ] = 0x0324, /* L2_RQSTS.LOADS */
438 [ C(RESULT_MISS) ] = 0x0224, /* L2_RQSTS.LD_MISS */
439 },
440 [ C(OP_WRITE) ] = {
441 [ C(RESULT_ACCESS) ] = 0x0c24, /* L2_RQSTS.RFOS */
442 [ C(RESULT_MISS) ] = 0x0824, /* L2_RQSTS.RFO_MISS */
443 },
444 [ C(OP_PREFETCH) ] = {
Peter Zijlstra8be6e8f2009-06-11 14:19:11 +0200445 [ C(RESULT_ACCESS) ] = 0x4f2e, /* LLC Reference */
446 [ C(RESULT_MISS) ] = 0x412e, /* LLC Misses */
Ingo Molnar8326f442009-06-05 20:22:46 +0200447 },
448 },
449 [ C(DTLB) ] = {
450 [ C(OP_READ) ] = {
451 [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI (alias) */
452 [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.ANY */
453 },
454 [ C(OP_WRITE) ] = {
455 [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI (alias) */
456 [ C(RESULT_MISS) ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS */
457 },
458 [ C(OP_PREFETCH) ] = {
459 [ C(RESULT_ACCESS) ] = 0x0,
460 [ C(RESULT_MISS) ] = 0x0,
461 },
462 },
463 [ C(ITLB) ] = {
464 [ C(OP_READ) ] = {
465 [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P */
Yong Wangfecc8ac2009-06-09 21:15:53 +0800466 [ C(RESULT_MISS) ] = 0x20c8, /* ITLB_MISS_RETIRED */
Ingo Molnar8326f442009-06-05 20:22:46 +0200467 },
468 [ C(OP_WRITE) ] = {
469 [ C(RESULT_ACCESS) ] = -1,
470 [ C(RESULT_MISS) ] = -1,
471 },
472 [ C(OP_PREFETCH) ] = {
473 [ C(RESULT_ACCESS) ] = -1,
474 [ C(RESULT_MISS) ] = -1,
475 },
476 },
477 [ C(BPU ) ] = {
478 [ C(OP_READ) ] = {
479 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
480 [ C(RESULT_MISS) ] = 0x03e8, /* BPU_CLEARS.ANY */
481 },
482 [ C(OP_WRITE) ] = {
483 [ C(RESULT_ACCESS) ] = -1,
484 [ C(RESULT_MISS) ] = -1,
485 },
486 [ C(OP_PREFETCH) ] = {
487 [ C(RESULT_ACCESS) ] = -1,
488 [ C(RESULT_MISS) ] = -1,
489 },
490 },
491};
492
Hiroshi Shimamotodb48ccc2009-11-12 11:25:34 +0900493static __initconst u64 core2_hw_cache_event_ids
Ingo Molnar8326f442009-06-05 20:22:46 +0200494 [PERF_COUNT_HW_CACHE_MAX]
495 [PERF_COUNT_HW_CACHE_OP_MAX]
496 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
497{
Thomas Gleixner0312af82009-06-08 07:42:04 +0200498 [ C(L1D) ] = {
499 [ C(OP_READ) ] = {
500 [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI */
501 [ C(RESULT_MISS) ] = 0x0140, /* L1D_CACHE_LD.I_STATE */
502 },
503 [ C(OP_WRITE) ] = {
504 [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI */
505 [ C(RESULT_MISS) ] = 0x0141, /* L1D_CACHE_ST.I_STATE */
506 },
507 [ C(OP_PREFETCH) ] = {
508 [ C(RESULT_ACCESS) ] = 0x104e, /* L1D_PREFETCH.REQUESTS */
509 [ C(RESULT_MISS) ] = 0,
510 },
511 },
512 [ C(L1I ) ] = {
513 [ C(OP_READ) ] = {
514 [ C(RESULT_ACCESS) ] = 0x0080, /* L1I.READS */
515 [ C(RESULT_MISS) ] = 0x0081, /* L1I.MISSES */
516 },
517 [ C(OP_WRITE) ] = {
518 [ C(RESULT_ACCESS) ] = -1,
519 [ C(RESULT_MISS) ] = -1,
520 },
521 [ C(OP_PREFETCH) ] = {
522 [ C(RESULT_ACCESS) ] = 0,
523 [ C(RESULT_MISS) ] = 0,
524 },
525 },
Peter Zijlstra8be6e8f2009-06-11 14:19:11 +0200526 [ C(LL ) ] = {
Thomas Gleixner0312af82009-06-08 07:42:04 +0200527 [ C(OP_READ) ] = {
528 [ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI */
529 [ C(RESULT_MISS) ] = 0x4129, /* L2_LD.ISTATE */
530 },
531 [ C(OP_WRITE) ] = {
532 [ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI */
533 [ C(RESULT_MISS) ] = 0x412A, /* L2_ST.ISTATE */
534 },
535 [ C(OP_PREFETCH) ] = {
536 [ C(RESULT_ACCESS) ] = 0,
537 [ C(RESULT_MISS) ] = 0,
538 },
539 },
540 [ C(DTLB) ] = {
541 [ C(OP_READ) ] = {
542 [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI (alias) */
543 [ C(RESULT_MISS) ] = 0x0208, /* DTLB_MISSES.MISS_LD */
544 },
545 [ C(OP_WRITE) ] = {
546 [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI (alias) */
547 [ C(RESULT_MISS) ] = 0x0808, /* DTLB_MISSES.MISS_ST */
548 },
549 [ C(OP_PREFETCH) ] = {
550 [ C(RESULT_ACCESS) ] = 0,
551 [ C(RESULT_MISS) ] = 0,
552 },
553 },
554 [ C(ITLB) ] = {
555 [ C(OP_READ) ] = {
556 [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
557 [ C(RESULT_MISS) ] = 0x1282, /* ITLBMISSES */
558 },
559 [ C(OP_WRITE) ] = {
560 [ C(RESULT_ACCESS) ] = -1,
561 [ C(RESULT_MISS) ] = -1,
562 },
563 [ C(OP_PREFETCH) ] = {
564 [ C(RESULT_ACCESS) ] = -1,
565 [ C(RESULT_MISS) ] = -1,
566 },
567 },
568 [ C(BPU ) ] = {
569 [ C(OP_READ) ] = {
570 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
571 [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
572 },
573 [ C(OP_WRITE) ] = {
574 [ C(RESULT_ACCESS) ] = -1,
575 [ C(RESULT_MISS) ] = -1,
576 },
577 [ C(OP_PREFETCH) ] = {
578 [ C(RESULT_ACCESS) ] = -1,
579 [ C(RESULT_MISS) ] = -1,
580 },
581 },
Ingo Molnar8326f442009-06-05 20:22:46 +0200582};
583
Hiroshi Shimamotodb48ccc2009-11-12 11:25:34 +0900584static __initconst u64 atom_hw_cache_event_ids
Ingo Molnar8326f442009-06-05 20:22:46 +0200585 [PERF_COUNT_HW_CACHE_MAX]
586 [PERF_COUNT_HW_CACHE_OP_MAX]
587 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
588{
Thomas Gleixnerad689222009-06-08 09:30:41 +0200589 [ C(L1D) ] = {
590 [ C(OP_READ) ] = {
591 [ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE.LD */
592 [ C(RESULT_MISS) ] = 0,
593 },
594 [ C(OP_WRITE) ] = {
Yong Wangfecc8ac2009-06-09 21:15:53 +0800595 [ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE.ST */
Thomas Gleixnerad689222009-06-08 09:30:41 +0200596 [ C(RESULT_MISS) ] = 0,
597 },
598 [ C(OP_PREFETCH) ] = {
599 [ C(RESULT_ACCESS) ] = 0x0,
600 [ C(RESULT_MISS) ] = 0,
601 },
602 },
603 [ C(L1I ) ] = {
604 [ C(OP_READ) ] = {
Yong Wangfecc8ac2009-06-09 21:15:53 +0800605 [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
606 [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
Thomas Gleixnerad689222009-06-08 09:30:41 +0200607 },
608 [ C(OP_WRITE) ] = {
609 [ C(RESULT_ACCESS) ] = -1,
610 [ C(RESULT_MISS) ] = -1,
611 },
612 [ C(OP_PREFETCH) ] = {
613 [ C(RESULT_ACCESS) ] = 0,
614 [ C(RESULT_MISS) ] = 0,
615 },
616 },
Peter Zijlstra8be6e8f2009-06-11 14:19:11 +0200617 [ C(LL ) ] = {
Thomas Gleixnerad689222009-06-08 09:30:41 +0200618 [ C(OP_READ) ] = {
619 [ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI */
620 [ C(RESULT_MISS) ] = 0x4129, /* L2_LD.ISTATE */
621 },
622 [ C(OP_WRITE) ] = {
623 [ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI */
624 [ C(RESULT_MISS) ] = 0x412A, /* L2_ST.ISTATE */
625 },
626 [ C(OP_PREFETCH) ] = {
627 [ C(RESULT_ACCESS) ] = 0,
628 [ C(RESULT_MISS) ] = 0,
629 },
630 },
631 [ C(DTLB) ] = {
632 [ C(OP_READ) ] = {
Yong Wangfecc8ac2009-06-09 21:15:53 +0800633 [ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE_LD.MESI (alias) */
Thomas Gleixnerad689222009-06-08 09:30:41 +0200634 [ C(RESULT_MISS) ] = 0x0508, /* DTLB_MISSES.MISS_LD */
635 },
636 [ C(OP_WRITE) ] = {
Yong Wangfecc8ac2009-06-09 21:15:53 +0800637 [ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE_ST.MESI (alias) */
Thomas Gleixnerad689222009-06-08 09:30:41 +0200638 [ C(RESULT_MISS) ] = 0x0608, /* DTLB_MISSES.MISS_ST */
639 },
640 [ C(OP_PREFETCH) ] = {
641 [ C(RESULT_ACCESS) ] = 0,
642 [ C(RESULT_MISS) ] = 0,
643 },
644 },
645 [ C(ITLB) ] = {
646 [ C(OP_READ) ] = {
647 [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
648 [ C(RESULT_MISS) ] = 0x0282, /* ITLB.MISSES */
649 },
650 [ C(OP_WRITE) ] = {
651 [ C(RESULT_ACCESS) ] = -1,
652 [ C(RESULT_MISS) ] = -1,
653 },
654 [ C(OP_PREFETCH) ] = {
655 [ C(RESULT_ACCESS) ] = -1,
656 [ C(RESULT_MISS) ] = -1,
657 },
658 },
659 [ C(BPU ) ] = {
660 [ C(OP_READ) ] = {
661 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
662 [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
663 },
664 [ C(OP_WRITE) ] = {
665 [ C(RESULT_ACCESS) ] = -1,
666 [ C(RESULT_MISS) ] = -1,
667 },
668 [ C(OP_PREFETCH) ] = {
669 [ C(RESULT_ACCESS) ] = -1,
670 [ C(RESULT_MISS) ] = -1,
671 },
672 },
Ingo Molnar8326f442009-06-05 20:22:46 +0200673};
674
Ingo Molnardfc65092009-09-21 11:31:35 +0200675static u64 intel_pmu_raw_event(u64 hw_event)
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100676{
Peter Zijlstra82bae4f82009-03-13 12:21:31 +0100677#define CORE_EVNTSEL_EVENT_MASK 0x000000FFULL
678#define CORE_EVNTSEL_UNIT_MASK 0x0000FF00ULL
Peter Zijlstraff99be52009-05-25 17:39:03 +0200679#define CORE_EVNTSEL_EDGE_MASK 0x00040000ULL
680#define CORE_EVNTSEL_INV_MASK 0x00800000ULL
Peter Zijlstrafe9081c2009-10-08 11:56:07 +0200681#define CORE_EVNTSEL_REG_MASK 0xFF000000ULL
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100682
Ingo Molnar128f0482009-06-03 22:19:36 +0200683#define CORE_EVNTSEL_MASK \
Stephane Eranian1da53e02010-01-18 10:58:01 +0200684 (INTEL_ARCH_EVTSEL_MASK | \
685 INTEL_ARCH_UNIT_MASK | \
686 INTEL_ARCH_EDGE_MASK | \
687 INTEL_ARCH_INV_MASK | \
688 INTEL_ARCH_CNT_MASK)
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100689
Ingo Molnardfc65092009-09-21 11:31:35 +0200690 return hw_event & CORE_EVNTSEL_MASK;
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100691}
692
Hiroshi Shimamotodb48ccc2009-11-12 11:25:34 +0900693static __initconst u64 amd_hw_cache_event_ids
Thomas Gleixnerf86748e2009-06-08 22:33:10 +0200694 [PERF_COUNT_HW_CACHE_MAX]
695 [PERF_COUNT_HW_CACHE_OP_MAX]
696 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
697{
698 [ C(L1D) ] = {
699 [ C(OP_READ) ] = {
Jaswinder Singh Rajputf4db43a2009-06-13 01:06:21 +0530700 [ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses */
701 [ C(RESULT_MISS) ] = 0x0041, /* Data Cache Misses */
Thomas Gleixnerf86748e2009-06-08 22:33:10 +0200702 },
703 [ C(OP_WRITE) ] = {
Jaswinder Singh Rajputd9f2a5e2009-06-20 13:19:25 +0530704 [ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */
Thomas Gleixnerf86748e2009-06-08 22:33:10 +0200705 [ C(RESULT_MISS) ] = 0,
706 },
707 [ C(OP_PREFETCH) ] = {
Jaswinder Singh Rajputf4db43a2009-06-13 01:06:21 +0530708 [ C(RESULT_ACCESS) ] = 0x0267, /* Data Prefetcher :attempts */
709 [ C(RESULT_MISS) ] = 0x0167, /* Data Prefetcher :cancelled */
Thomas Gleixnerf86748e2009-06-08 22:33:10 +0200710 },
711 },
712 [ C(L1I ) ] = {
713 [ C(OP_READ) ] = {
714 [ C(RESULT_ACCESS) ] = 0x0080, /* Instruction cache fetches */
715 [ C(RESULT_MISS) ] = 0x0081, /* Instruction cache misses */
716 },
717 [ C(OP_WRITE) ] = {
718 [ C(RESULT_ACCESS) ] = -1,
719 [ C(RESULT_MISS) ] = -1,
720 },
721 [ C(OP_PREFETCH) ] = {
Jaswinder Singh Rajputf4db43a2009-06-13 01:06:21 +0530722 [ C(RESULT_ACCESS) ] = 0x014B, /* Prefetch Instructions :Load */
Thomas Gleixnerf86748e2009-06-08 22:33:10 +0200723 [ C(RESULT_MISS) ] = 0,
724 },
725 },
Peter Zijlstra8be6e8f2009-06-11 14:19:11 +0200726 [ C(LL ) ] = {
Thomas Gleixnerf86748e2009-06-08 22:33:10 +0200727 [ C(OP_READ) ] = {
Jaswinder Singh Rajputf4db43a2009-06-13 01:06:21 +0530728 [ C(RESULT_ACCESS) ] = 0x037D, /* Requests to L2 Cache :IC+DC */
729 [ C(RESULT_MISS) ] = 0x037E, /* L2 Cache Misses : IC+DC */
Thomas Gleixnerf86748e2009-06-08 22:33:10 +0200730 },
731 [ C(OP_WRITE) ] = {
Jaswinder Singh Rajputf4db43a2009-06-13 01:06:21 +0530732 [ C(RESULT_ACCESS) ] = 0x017F, /* L2 Fill/Writeback */
Thomas Gleixnerf86748e2009-06-08 22:33:10 +0200733 [ C(RESULT_MISS) ] = 0,
734 },
735 [ C(OP_PREFETCH) ] = {
736 [ C(RESULT_ACCESS) ] = 0,
737 [ C(RESULT_MISS) ] = 0,
738 },
739 },
740 [ C(DTLB) ] = {
741 [ C(OP_READ) ] = {
Jaswinder Singh Rajputf4db43a2009-06-13 01:06:21 +0530742 [ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses */
743 [ C(RESULT_MISS) ] = 0x0046, /* L1 DTLB and L2 DLTB Miss */
Thomas Gleixnerf86748e2009-06-08 22:33:10 +0200744 },
745 [ C(OP_WRITE) ] = {
746 [ C(RESULT_ACCESS) ] = 0,
747 [ C(RESULT_MISS) ] = 0,
748 },
749 [ C(OP_PREFETCH) ] = {
750 [ C(RESULT_ACCESS) ] = 0,
751 [ C(RESULT_MISS) ] = 0,
752 },
753 },
754 [ C(ITLB) ] = {
755 [ C(OP_READ) ] = {
756 [ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes */
757 [ C(RESULT_MISS) ] = 0x0085, /* Instr. fetch ITLB misses */
758 },
759 [ C(OP_WRITE) ] = {
760 [ C(RESULT_ACCESS) ] = -1,
761 [ C(RESULT_MISS) ] = -1,
762 },
763 [ C(OP_PREFETCH) ] = {
764 [ C(RESULT_ACCESS) ] = -1,
765 [ C(RESULT_MISS) ] = -1,
766 },
767 },
768 [ C(BPU ) ] = {
769 [ C(OP_READ) ] = {
770 [ C(RESULT_ACCESS) ] = 0x00c2, /* Retired Branch Instr. */
771 [ C(RESULT_MISS) ] = 0x00c3, /* Retired Mispredicted BI */
772 },
773 [ C(OP_WRITE) ] = {
774 [ C(RESULT_ACCESS) ] = -1,
775 [ C(RESULT_MISS) ] = -1,
776 },
777 [ C(OP_PREFETCH) ] = {
778 [ C(RESULT_ACCESS) ] = -1,
779 [ C(RESULT_MISS) ] = -1,
780 },
781 },
782};
783
Ingo Molnar241771e2008-12-03 10:39:53 +0100784/*
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +0530785 * AMD Performance Monitor K7 and later.
786 */
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100787static const u64 amd_perfmon_event_map[] =
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +0530788{
Peter Zijlstraf4dbfa82009-06-11 14:06:28 +0200789 [PERF_COUNT_HW_CPU_CYCLES] = 0x0076,
790 [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
791 [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0080,
792 [PERF_COUNT_HW_CACHE_MISSES] = 0x0081,
793 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
794 [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +0530795};
796
Ingo Molnardfc65092009-09-21 11:31:35 +0200797static u64 amd_pmu_event_map(int hw_event)
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +0530798{
Ingo Molnardfc65092009-09-21 11:31:35 +0200799 return amd_perfmon_event_map[hw_event];
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +0530800}
801
Ingo Molnardfc65092009-09-21 11:31:35 +0200802static u64 amd_pmu_raw_event(u64 hw_event)
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100803{
Peter Zijlstra82bae4f82009-03-13 12:21:31 +0100804#define K7_EVNTSEL_EVENT_MASK 0x7000000FFULL
805#define K7_EVNTSEL_UNIT_MASK 0x00000FF00ULL
Peter Zijlstraff99be52009-05-25 17:39:03 +0200806#define K7_EVNTSEL_EDGE_MASK 0x000040000ULL
807#define K7_EVNTSEL_INV_MASK 0x000800000ULL
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200808#define K7_EVNTSEL_REG_MASK 0x0FF000000ULL
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100809
810#define K7_EVNTSEL_MASK \
811 (K7_EVNTSEL_EVENT_MASK | \
812 K7_EVNTSEL_UNIT_MASK | \
Peter Zijlstraff99be52009-05-25 17:39:03 +0200813 K7_EVNTSEL_EDGE_MASK | \
814 K7_EVNTSEL_INV_MASK | \
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200815 K7_EVNTSEL_REG_MASK)
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100816
Ingo Molnardfc65092009-09-21 11:31:35 +0200817 return hw_event & K7_EVNTSEL_MASK;
Peter Zijlstrab0f3f282009-03-05 18:08:27 +0100818}
819
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +0530820/*
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200821 * Propagate event elapsed time into the generic event.
822 * Can only be executed on the CPU where the event is active.
Ingo Molnaree060942008-12-13 09:00:03 +0100823 * Returns the delta events processed.
824 */
Robert Richter4b7bfd02009-04-29 12:47:22 +0200825static u64
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200826x86_perf_event_update(struct perf_event *event,
827 struct hw_perf_event *hwc, int idx)
Ingo Molnaree060942008-12-13 09:00:03 +0100828{
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200829 int shift = 64 - x86_pmu.event_bits;
Peter Zijlstraec3232b2009-05-13 09:45:19 +0200830 u64 prev_raw_count, new_raw_count;
831 s64 delta;
Ingo Molnaree060942008-12-13 09:00:03 +0100832
Markus Metzger30dd5682009-07-21 15:56:48 +0200833 if (idx == X86_PMC_IDX_FIXED_BTS)
834 return 0;
835
Ingo Molnaree060942008-12-13 09:00:03 +0100836 /*
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200837 * Careful: an NMI might modify the previous event value.
Ingo Molnaree060942008-12-13 09:00:03 +0100838 *
839 * Our tactic to handle this is to first atomically read and
840 * exchange a new raw count - then add that new-prev delta
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200841 * count to the generic event atomically:
Ingo Molnaree060942008-12-13 09:00:03 +0100842 */
843again:
844 prev_raw_count = atomic64_read(&hwc->prev_count);
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200845 rdmsrl(hwc->event_base + idx, new_raw_count);
Ingo Molnaree060942008-12-13 09:00:03 +0100846
847 if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
848 new_raw_count) != prev_raw_count)
849 goto again;
850
851 /*
852 * Now we have the new raw value and have updated the prev
853 * timestamp already. We can now calculate the elapsed delta
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200854 * (event-)time and add that to the generic event.
Ingo Molnaree060942008-12-13 09:00:03 +0100855 *
856 * Careful, not all hw sign-extends above the physical width
Peter Zijlstraec3232b2009-05-13 09:45:19 +0200857 * of the count.
Ingo Molnaree060942008-12-13 09:00:03 +0100858 */
Peter Zijlstraec3232b2009-05-13 09:45:19 +0200859 delta = (new_raw_count << shift) - (prev_raw_count << shift);
860 delta >>= shift;
Ingo Molnaree060942008-12-13 09:00:03 +0100861
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200862 atomic64_add(delta, &event->count);
Ingo Molnaree060942008-12-13 09:00:03 +0100863 atomic64_sub(delta, &hwc->period_left);
Robert Richter4b7bfd02009-04-29 12:47:22 +0200864
865 return new_raw_count;
Ingo Molnaree060942008-12-13 09:00:03 +0100866}
867
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200868static atomic_t active_events;
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200869static DEFINE_MUTEX(pmc_reserve_mutex);
870
871static bool reserve_pmc_hardware(void)
872{
Ingo Molnar04da8a42009-08-11 10:40:08 +0200873#ifdef CONFIG_X86_LOCAL_APIC
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200874 int i;
875
876 if (nmi_watchdog == NMI_LOCAL_APIC)
877 disable_lapic_nmi_watchdog();
878
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200879 for (i = 0; i < x86_pmu.num_events; i++) {
Robert Richter4a06bd82009-04-29 12:47:11 +0200880 if (!reserve_perfctr_nmi(x86_pmu.perfctr + i))
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200881 goto perfctr_fail;
882 }
883
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200884 for (i = 0; i < x86_pmu.num_events; i++) {
Robert Richter4a06bd82009-04-29 12:47:11 +0200885 if (!reserve_evntsel_nmi(x86_pmu.eventsel + i))
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200886 goto eventsel_fail;
887 }
Ingo Molnar04da8a42009-08-11 10:40:08 +0200888#endif
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200889
890 return true;
891
Ingo Molnar04da8a42009-08-11 10:40:08 +0200892#ifdef CONFIG_X86_LOCAL_APIC
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200893eventsel_fail:
894 for (i--; i >= 0; i--)
Robert Richter4a06bd82009-04-29 12:47:11 +0200895 release_evntsel_nmi(x86_pmu.eventsel + i);
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200896
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200897 i = x86_pmu.num_events;
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200898
899perfctr_fail:
900 for (i--; i >= 0; i--)
Robert Richter4a06bd82009-04-29 12:47:11 +0200901 release_perfctr_nmi(x86_pmu.perfctr + i);
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200902
903 if (nmi_watchdog == NMI_LOCAL_APIC)
904 enable_lapic_nmi_watchdog();
905
906 return false;
Ingo Molnar04da8a42009-08-11 10:40:08 +0200907#endif
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200908}
909
910static void release_pmc_hardware(void)
911{
Ingo Molnar04da8a42009-08-11 10:40:08 +0200912#ifdef CONFIG_X86_LOCAL_APIC
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200913 int i;
914
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200915 for (i = 0; i < x86_pmu.num_events; i++) {
Robert Richter4a06bd82009-04-29 12:47:11 +0200916 release_perfctr_nmi(x86_pmu.perfctr + i);
917 release_evntsel_nmi(x86_pmu.eventsel + i);
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200918 }
919
920 if (nmi_watchdog == NMI_LOCAL_APIC)
921 enable_lapic_nmi_watchdog();
Ingo Molnar04da8a42009-08-11 10:40:08 +0200922#endif
Peter Zijlstra4e935e42009-03-30 19:07:16 +0200923}
924
Markus Metzger30dd5682009-07-21 15:56:48 +0200925static inline bool bts_available(void)
926{
927 return x86_pmu.enable_bts != NULL;
928}
929
930static inline void init_debug_store_on_cpu(int cpu)
931{
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200932 struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
Markus Metzger30dd5682009-07-21 15:56:48 +0200933
934 if (!ds)
935 return;
936
937 wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
markus.t.metzger@intel.com596da172009-09-02 16:04:47 +0200938 (u32)((u64)(unsigned long)ds),
939 (u32)((u64)(unsigned long)ds >> 32));
Markus Metzger30dd5682009-07-21 15:56:48 +0200940}
941
942static inline void fini_debug_store_on_cpu(int cpu)
943{
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200944 if (!per_cpu(cpu_hw_events, cpu).ds)
Markus Metzger30dd5682009-07-21 15:56:48 +0200945 return;
946
947 wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
948}
949
950static void release_bts_hardware(void)
951{
952 int cpu;
953
954 if (!bts_available())
955 return;
956
957 get_online_cpus();
958
959 for_each_online_cpu(cpu)
960 fini_debug_store_on_cpu(cpu);
961
962 for_each_possible_cpu(cpu) {
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200963 struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
Markus Metzger30dd5682009-07-21 15:56:48 +0200964
965 if (!ds)
966 continue;
967
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200968 per_cpu(cpu_hw_events, cpu).ds = NULL;
Markus Metzger30dd5682009-07-21 15:56:48 +0200969
markus.t.metzger@intel.com596da172009-09-02 16:04:47 +0200970 kfree((void *)(unsigned long)ds->bts_buffer_base);
Markus Metzger30dd5682009-07-21 15:56:48 +0200971 kfree(ds);
972 }
973
974 put_online_cpus();
975}
976
977static int reserve_bts_hardware(void)
978{
979 int cpu, err = 0;
980
981 if (!bts_available())
markus.t.metzger@intel.com747b50a2009-09-02 16:04:46 +0200982 return 0;
Markus Metzger30dd5682009-07-21 15:56:48 +0200983
984 get_online_cpus();
985
986 for_each_possible_cpu(cpu) {
987 struct debug_store *ds;
988 void *buffer;
989
990 err = -ENOMEM;
991 buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
992 if (unlikely(!buffer))
993 break;
994
995 ds = kzalloc(sizeof(*ds), GFP_KERNEL);
996 if (unlikely(!ds)) {
997 kfree(buffer);
998 break;
999 }
1000
markus.t.metzger@intel.com596da172009-09-02 16:04:47 +02001001 ds->bts_buffer_base = (u64)(unsigned long)buffer;
Markus Metzger30dd5682009-07-21 15:56:48 +02001002 ds->bts_index = ds->bts_buffer_base;
1003 ds->bts_absolute_maximum =
1004 ds->bts_buffer_base + BTS_BUFFER_SIZE;
1005 ds->bts_interrupt_threshold =
1006 ds->bts_absolute_maximum - BTS_OVFL_TH;
1007
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001008 per_cpu(cpu_hw_events, cpu).ds = ds;
Markus Metzger30dd5682009-07-21 15:56:48 +02001009 err = 0;
1010 }
1011
1012 if (err)
1013 release_bts_hardware();
1014 else {
1015 for_each_online_cpu(cpu)
1016 init_debug_store_on_cpu(cpu);
1017 }
1018
1019 put_online_cpus();
1020
1021 return err;
1022}
1023
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001024static void hw_perf_event_destroy(struct perf_event *event)
Peter Zijlstra4e935e42009-03-30 19:07:16 +02001025{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001026 if (atomic_dec_and_mutex_lock(&active_events, &pmc_reserve_mutex)) {
Peter Zijlstra4e935e42009-03-30 19:07:16 +02001027 release_pmc_hardware();
Markus Metzger30dd5682009-07-21 15:56:48 +02001028 release_bts_hardware();
Peter Zijlstra4e935e42009-03-30 19:07:16 +02001029 mutex_unlock(&pmc_reserve_mutex);
1030 }
1031}
1032
Robert Richter85cf9db2009-04-29 12:47:20 +02001033static inline int x86_pmu_initialized(void)
1034{
1035 return x86_pmu.handle_irq != NULL;
1036}
1037
Ingo Molnar8326f442009-06-05 20:22:46 +02001038static inline int
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001039set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event_attr *attr)
Ingo Molnar8326f442009-06-05 20:22:46 +02001040{
1041 unsigned int cache_type, cache_op, cache_result;
1042 u64 config, val;
1043
1044 config = attr->config;
1045
1046 cache_type = (config >> 0) & 0xff;
1047 if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
1048 return -EINVAL;
1049
1050 cache_op = (config >> 8) & 0xff;
1051 if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
1052 return -EINVAL;
1053
1054 cache_result = (config >> 16) & 0xff;
1055 if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
1056 return -EINVAL;
1057
1058 val = hw_cache_event_ids[cache_type][cache_op][cache_result];
1059
1060 if (val == 0)
1061 return -ENOENT;
1062
1063 if (val == -1)
1064 return -EINVAL;
1065
1066 hwc->config |= val;
1067
1068 return 0;
1069}
1070
Markus Metzger30dd5682009-07-21 15:56:48 +02001071static void intel_pmu_enable_bts(u64 config)
1072{
1073 unsigned long debugctlmsr;
1074
1075 debugctlmsr = get_debugctlmsr();
1076
1077 debugctlmsr |= X86_DEBUGCTL_TR;
1078 debugctlmsr |= X86_DEBUGCTL_BTS;
1079 debugctlmsr |= X86_DEBUGCTL_BTINT;
1080
1081 if (!(config & ARCH_PERFMON_EVENTSEL_OS))
1082 debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS;
1083
1084 if (!(config & ARCH_PERFMON_EVENTSEL_USR))
1085 debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR;
1086
1087 update_debugctlmsr(debugctlmsr);
1088}
1089
1090static void intel_pmu_disable_bts(void)
1091{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001092 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
Markus Metzger30dd5682009-07-21 15:56:48 +02001093 unsigned long debugctlmsr;
1094
1095 if (!cpuc->ds)
1096 return;
1097
1098 debugctlmsr = get_debugctlmsr();
1099
1100 debugctlmsr &=
1101 ~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT |
1102 X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR);
1103
1104 update_debugctlmsr(debugctlmsr);
1105}
1106
Ingo Molnaree060942008-12-13 09:00:03 +01001107/*
Peter Zijlstra0d486962009-06-02 19:22:16 +02001108 * Setup the hardware configuration for a given attr_type
Ingo Molnar241771e2008-12-03 10:39:53 +01001109 */
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001110static int __hw_perf_event_init(struct perf_event *event)
Ingo Molnar241771e2008-12-03 10:39:53 +01001111{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001112 struct perf_event_attr *attr = &event->attr;
1113 struct hw_perf_event *hwc = &event->hw;
Peter Zijlstra9c74fb52009-07-08 10:21:41 +02001114 u64 config;
Peter Zijlstra4e935e42009-03-30 19:07:16 +02001115 int err;
Ingo Molnar241771e2008-12-03 10:39:53 +01001116
Robert Richter85cf9db2009-04-29 12:47:20 +02001117 if (!x86_pmu_initialized())
1118 return -ENODEV;
Ingo Molnar241771e2008-12-03 10:39:53 +01001119
Peter Zijlstra4e935e42009-03-30 19:07:16 +02001120 err = 0;
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001121 if (!atomic_inc_not_zero(&active_events)) {
Peter Zijlstra4e935e42009-03-30 19:07:16 +02001122 mutex_lock(&pmc_reserve_mutex);
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001123 if (atomic_read(&active_events) == 0) {
Markus Metzger30dd5682009-07-21 15:56:48 +02001124 if (!reserve_pmc_hardware())
1125 err = -EBUSY;
1126 else
markus.t.metzger@intel.com747b50a2009-09-02 16:04:46 +02001127 err = reserve_bts_hardware();
Markus Metzger30dd5682009-07-21 15:56:48 +02001128 }
1129 if (!err)
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001130 atomic_inc(&active_events);
Peter Zijlstra4e935e42009-03-30 19:07:16 +02001131 mutex_unlock(&pmc_reserve_mutex);
1132 }
1133 if (err)
1134 return err;
1135
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001136 event->destroy = hw_perf_event_destroy;
Peter Zijlstraa1792cdac2009-09-09 10:04:47 +02001137
Ingo Molnar241771e2008-12-03 10:39:53 +01001138 /*
Paul Mackerras0475f9e2009-02-11 14:35:35 +11001139 * Generate PMC IRQs:
Ingo Molnar241771e2008-12-03 10:39:53 +01001140 * (keep 'enabled' bit clear for now)
1141 */
Paul Mackerras0475f9e2009-02-11 14:35:35 +11001142 hwc->config = ARCH_PERFMON_EVENTSEL_INT;
Ingo Molnar241771e2008-12-03 10:39:53 +01001143
Stephane Eranianb6900812009-10-06 16:42:09 +02001144 hwc->idx = -1;
1145
Ingo Molnar241771e2008-12-03 10:39:53 +01001146 /*
Paul Mackerras0475f9e2009-02-11 14:35:35 +11001147 * Count user and OS events unless requested not to.
1148 */
Peter Zijlstra0d486962009-06-02 19:22:16 +02001149 if (!attr->exclude_user)
Paul Mackerras0475f9e2009-02-11 14:35:35 +11001150 hwc->config |= ARCH_PERFMON_EVENTSEL_USR;
Peter Zijlstra0d486962009-06-02 19:22:16 +02001151 if (!attr->exclude_kernel)
Paul Mackerras0475f9e2009-02-11 14:35:35 +11001152 hwc->config |= ARCH_PERFMON_EVENTSEL_OS;
1153
Peter Zijlstrabd2b5b12009-06-10 13:40:57 +02001154 if (!hwc->sample_period) {
Peter Zijlstrab23f3322009-06-02 15:13:03 +02001155 hwc->sample_period = x86_pmu.max_period;
Peter Zijlstra9e350de2009-06-10 21:34:59 +02001156 hwc->last_period = hwc->sample_period;
Peter Zijlstrabd2b5b12009-06-10 13:40:57 +02001157 atomic64_set(&hwc->period_left, hwc->sample_period);
Ingo Molnar04da8a42009-08-11 10:40:08 +02001158 } else {
1159 /*
1160 * If we have a PMU initialized but no APIC
1161 * interrupts, we cannot sample hardware
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001162 * events (user-space has to fall back and
1163 * sample via a hrtimer based software event):
Ingo Molnar04da8a42009-08-11 10:40:08 +02001164 */
1165 if (!x86_pmu.apic)
1166 return -EOPNOTSUPP;
Peter Zijlstrabd2b5b12009-06-10 13:40:57 +02001167 }
Ingo Molnard2517a42009-05-17 10:04:45 +02001168
Ingo Molnar241771e2008-12-03 10:39:53 +01001169 /*
Ingo Molnardfc65092009-09-21 11:31:35 +02001170 * Raw hw_event type provide the config in the hw_event structure
Ingo Molnar241771e2008-12-03 10:39:53 +01001171 */
Ingo Molnara21ca2c2009-06-06 09:58:57 +02001172 if (attr->type == PERF_TYPE_RAW) {
1173 hwc->config |= x86_pmu.raw_event(attr->config);
Ingo Molnar8326f442009-06-05 20:22:46 +02001174 return 0;
Ingo Molnar241771e2008-12-03 10:39:53 +01001175 }
Ingo Molnar241771e2008-12-03 10:39:53 +01001176
Ingo Molnar8326f442009-06-05 20:22:46 +02001177 if (attr->type == PERF_TYPE_HW_CACHE)
1178 return set_ext_hw_attr(hwc, attr);
1179
1180 if (attr->config >= x86_pmu.max_events)
1181 return -EINVAL;
Peter Zijlstra9c74fb52009-07-08 10:21:41 +02001182
Ingo Molnar8326f442009-06-05 20:22:46 +02001183 /*
1184 * The generic map:
1185 */
Peter Zijlstra9c74fb52009-07-08 10:21:41 +02001186 config = x86_pmu.event_map(attr->config);
1187
1188 if (config == 0)
1189 return -ENOENT;
1190
1191 if (config == -1LL)
1192 return -EINVAL;
1193
markus.t.metzger@intel.com747b50a2009-09-02 16:04:46 +02001194 /*
1195 * Branch tracing:
1196 */
1197 if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
markus.t.metzger@intel.com16531922009-09-02 16:04:48 +02001198 (hwc->sample_period == 1)) {
1199 /* BTS is not supported by this architecture. */
1200 if (!bts_available())
1201 return -EOPNOTSUPP;
1202
1203 /* BTS is currently only allowed for user-mode. */
1204 if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
1205 return -EOPNOTSUPP;
1206 }
markus.t.metzger@intel.com747b50a2009-09-02 16:04:46 +02001207
Peter Zijlstra9c74fb52009-07-08 10:21:41 +02001208 hwc->config |= config;
Peter Zijlstra4e935e42009-03-30 19:07:16 +02001209
Ingo Molnar241771e2008-12-03 10:39:53 +01001210 return 0;
1211}
1212
Vince Weaver11d15782009-07-08 17:46:14 -04001213static void p6_pmu_disable_all(void)
1214{
Peter Zijlstra9c74fb52009-07-08 10:21:41 +02001215 u64 val;
Vince Weaver11d15782009-07-08 17:46:14 -04001216
Vince Weaver11d15782009-07-08 17:46:14 -04001217 /* p6 only has one enable register */
1218 rdmsrl(MSR_P6_EVNTSEL0, val);
1219 val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
1220 wrmsrl(MSR_P6_EVNTSEL0, val);
1221}
1222
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02001223static void intel_pmu_disable_all(void)
Thomas Gleixner4ac13292008-12-09 21:43:39 +01001224{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001225 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
Markus Metzger30dd5682009-07-21 15:56:48 +02001226
Ingo Molnar862a1a52008-12-17 13:09:20 +01001227 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
Markus Metzger30dd5682009-07-21 15:56:48 +02001228
1229 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask))
1230 intel_pmu_disable_bts();
Thomas Gleixner4ac13292008-12-09 21:43:39 +01001231}
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05301232
Peter Zijlstra8c48e442010-01-29 13:25:31 +01001233static void x86_pmu_disable_all(void)
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05301234{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001235 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02001236 int idx;
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01001237
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001238 for (idx = 0; idx < x86_pmu.num_events; idx++) {
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01001239 u64 val;
1240
Robert Richter43f62012009-04-29 16:55:56 +02001241 if (!test_bit(idx, cpuc->active_mask))
Robert Richter4295ee62009-04-29 12:47:01 +02001242 continue;
Peter Zijlstra8c48e442010-01-29 13:25:31 +01001243 rdmsrl(x86_pmu.eventsel + idx, val);
Robert Richter4295ee62009-04-29 12:47:01 +02001244 if (!(val & ARCH_PERFMON_EVENTSEL0_ENABLE))
1245 continue;
1246 val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
Peter Zijlstra8c48e442010-01-29 13:25:31 +01001247 wrmsrl(x86_pmu.eventsel + idx, val);
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05301248 }
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05301249}
1250
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02001251void hw_perf_disable(void)
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05301252{
Stephane Eranian1da53e02010-01-18 10:58:01 +02001253 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1254
Robert Richter85cf9db2009-04-29 12:47:20 +02001255 if (!x86_pmu_initialized())
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02001256 return;
Stephane Eranian1da53e02010-01-18 10:58:01 +02001257
Peter Zijlstra1a6e21f2010-01-27 23:07:47 +01001258 if (!cpuc->enabled)
1259 return;
1260
1261 cpuc->n_added = 0;
1262 cpuc->enabled = 0;
1263 barrier();
Stephane Eranian1da53e02010-01-18 10:58:01 +02001264
1265 x86_pmu.disable_all();
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05301266}
Ingo Molnar241771e2008-12-03 10:39:53 +01001267
Vince Weaver11d15782009-07-08 17:46:14 -04001268static void p6_pmu_enable_all(void)
1269{
Vince Weaver11d15782009-07-08 17:46:14 -04001270 unsigned long val;
1271
Vince Weaver11d15782009-07-08 17:46:14 -04001272 /* p6 only has one enable register */
1273 rdmsrl(MSR_P6_EVNTSEL0, val);
1274 val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
1275 wrmsrl(MSR_P6_EVNTSEL0, val);
1276}
1277
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02001278static void intel_pmu_enable_all(void)
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05301279{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001280 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
Markus Metzger30dd5682009-07-21 15:56:48 +02001281
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02001282 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
Markus Metzger30dd5682009-07-21 15:56:48 +02001283
1284 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001285 struct perf_event *event =
1286 cpuc->events[X86_PMC_IDX_FIXED_BTS];
Markus Metzger30dd5682009-07-21 15:56:48 +02001287
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001288 if (WARN_ON_ONCE(!event))
Markus Metzger30dd5682009-07-21 15:56:48 +02001289 return;
1290
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001291 intel_pmu_enable_bts(event->hw.config);
Markus Metzger30dd5682009-07-21 15:56:48 +02001292 }
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05301293}
1294
Peter Zijlstra8c48e442010-01-29 13:25:31 +01001295static void x86_pmu_enable_all(void)
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05301296{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001297 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05301298 int idx;
1299
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001300 for (idx = 0; idx < x86_pmu.num_events; idx++) {
1301 struct perf_event *event = cpuc->events[idx];
Robert Richter4295ee62009-04-29 12:47:01 +02001302 u64 val;
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01001303
Robert Richter43f62012009-04-29 16:55:56 +02001304 if (!test_bit(idx, cpuc->active_mask))
Robert Richter4295ee62009-04-29 12:47:01 +02001305 continue;
Peter Zijlstra984b8382009-07-10 09:59:56 +02001306
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001307 val = event->hw.config;
Robert Richter4295ee62009-04-29 12:47:01 +02001308 val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
Peter Zijlstra8c48e442010-01-29 13:25:31 +01001309 wrmsrl(x86_pmu.eventsel + idx, val);
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05301310 }
1311}
1312
Stephane Eranian1da53e02010-01-18 10:58:01 +02001313static const struct pmu pmu;
1314
1315static inline int is_x86_event(struct perf_event *event)
1316{
1317 return event->pmu == &pmu;
1318}
1319
1320static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
1321{
Peter Zijlstra63b14642010-01-22 16:32:17 +01001322 struct event_constraint *c, *constraints[X86_PMC_IDX_MAX];
Stephane Eranian1da53e02010-01-18 10:58:01 +02001323 unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
Peter Zijlstrac933c1a2010-01-22 16:40:12 +01001324 int i, j, w, wmax, num = 0;
Stephane Eranian1da53e02010-01-18 10:58:01 +02001325 struct hw_perf_event *hwc;
1326
1327 bitmap_zero(used_mask, X86_PMC_IDX_MAX);
1328
1329 for (i = 0; i < n; i++) {
Peter Zijlstra63b14642010-01-22 16:32:17 +01001330 constraints[i] =
1331 x86_pmu.get_event_constraints(cpuc, cpuc->event_list[i]);
Stephane Eranian1da53e02010-01-18 10:58:01 +02001332 }
1333
1334 /*
Stephane Eranian81130702010-01-21 17:39:01 +02001335 * fastpath, try to reuse previous register
1336 */
Peter Zijlstrac933c1a2010-01-22 16:40:12 +01001337 for (i = 0; i < n; i++) {
Stephane Eranian81130702010-01-21 17:39:01 +02001338 hwc = &cpuc->event_list[i]->hw;
Peter Zijlstra81269a02010-01-22 14:55:22 +01001339 c = constraints[i];
Stephane Eranian81130702010-01-21 17:39:01 +02001340
1341 /* never assigned */
1342 if (hwc->idx == -1)
1343 break;
1344
1345 /* constraint still honored */
Peter Zijlstra63b14642010-01-22 16:32:17 +01001346 if (!test_bit(hwc->idx, c->idxmsk))
Stephane Eranian81130702010-01-21 17:39:01 +02001347 break;
1348
1349 /* not already used */
1350 if (test_bit(hwc->idx, used_mask))
1351 break;
1352
Stephane Eranian81130702010-01-21 17:39:01 +02001353 set_bit(hwc->idx, used_mask);
1354 if (assign)
1355 assign[i] = hwc->idx;
1356 }
Peter Zijlstrac933c1a2010-01-22 16:40:12 +01001357 if (i == n)
Stephane Eranian81130702010-01-21 17:39:01 +02001358 goto done;
1359
1360 /*
1361 * begin slow path
1362 */
1363
1364 bitmap_zero(used_mask, X86_PMC_IDX_MAX);
1365
1366 /*
Stephane Eranian1da53e02010-01-18 10:58:01 +02001367 * weight = number of possible counters
1368 *
1369 * 1 = most constrained, only works on one counter
1370 * wmax = least constrained, works on any counter
1371 *
1372 * assign events to counters starting with most
1373 * constrained events.
1374 */
1375 wmax = x86_pmu.num_events;
1376
1377 /*
1378 * when fixed event counters are present,
1379 * wmax is incremented by 1 to account
1380 * for one more choice
1381 */
1382 if (x86_pmu.num_events_fixed)
1383 wmax++;
1384
Stephane Eranian81130702010-01-21 17:39:01 +02001385 for (w = 1, num = n; num && w <= wmax; w++) {
Stephane Eranian1da53e02010-01-18 10:58:01 +02001386 /* for each event */
Stephane Eranian81130702010-01-21 17:39:01 +02001387 for (i = 0; num && i < n; i++) {
Peter Zijlstra81269a02010-01-22 14:55:22 +01001388 c = constraints[i];
Stephane Eranian1da53e02010-01-18 10:58:01 +02001389 hwc = &cpuc->event_list[i]->hw;
1390
Peter Zijlstra272d30b2010-01-22 16:32:17 +01001391 if (c->weight != w)
Stephane Eranian1da53e02010-01-18 10:58:01 +02001392 continue;
1393
Peter Zijlstra63b14642010-01-22 16:32:17 +01001394 for_each_bit(j, c->idxmsk, X86_PMC_IDX_MAX) {
Stephane Eranian1da53e02010-01-18 10:58:01 +02001395 if (!test_bit(j, used_mask))
1396 break;
1397 }
1398
1399 if (j == X86_PMC_IDX_MAX)
1400 break;
Stephane Eranian1da53e02010-01-18 10:58:01 +02001401
Stephane Eranian81130702010-01-21 17:39:01 +02001402 set_bit(j, used_mask);
1403
Stephane Eranian1da53e02010-01-18 10:58:01 +02001404 if (assign)
1405 assign[i] = j;
1406 num--;
1407 }
1408 }
Stephane Eranian81130702010-01-21 17:39:01 +02001409done:
Stephane Eranian1da53e02010-01-18 10:58:01 +02001410 /*
1411 * scheduling failed or is just a simulation,
1412 * free resources if necessary
1413 */
1414 if (!assign || num) {
1415 for (i = 0; i < n; i++) {
1416 if (x86_pmu.put_event_constraints)
1417 x86_pmu.put_event_constraints(cpuc, cpuc->event_list[i]);
1418 }
1419 }
1420 return num ? -ENOSPC : 0;
1421}
1422
1423/*
1424 * dogrp: true if must collect siblings events (group)
1425 * returns total number of events and error code
1426 */
1427static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, bool dogrp)
1428{
1429 struct perf_event *event;
1430 int n, max_count;
1431
1432 max_count = x86_pmu.num_events + x86_pmu.num_events_fixed;
1433
1434 /* current number of events already accepted */
1435 n = cpuc->n_events;
1436
1437 if (is_x86_event(leader)) {
1438 if (n >= max_count)
1439 return -ENOSPC;
1440 cpuc->event_list[n] = leader;
1441 n++;
1442 }
1443 if (!dogrp)
1444 return n;
1445
1446 list_for_each_entry(event, &leader->sibling_list, group_entry) {
1447 if (!is_x86_event(event) ||
Stephane Eranian81130702010-01-21 17:39:01 +02001448 event->state <= PERF_EVENT_STATE_OFF)
Stephane Eranian1da53e02010-01-18 10:58:01 +02001449 continue;
1450
1451 if (n >= max_count)
1452 return -ENOSPC;
1453
1454 cpuc->event_list[n] = event;
1455 n++;
1456 }
1457 return n;
1458}
1459
1460
1461static inline void x86_assign_hw_event(struct perf_event *event,
1462 struct hw_perf_event *hwc, int idx)
1463{
1464 hwc->idx = idx;
1465
1466 if (hwc->idx == X86_PMC_IDX_FIXED_BTS) {
1467 hwc->config_base = 0;
1468 hwc->event_base = 0;
1469 } else if (hwc->idx >= X86_PMC_IDX_FIXED) {
1470 hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
1471 /*
1472 * We set it so that event_base + idx in wrmsr/rdmsr maps to
1473 * MSR_ARCH_PERFMON_FIXED_CTR0 ... CTR2:
1474 */
1475 hwc->event_base =
1476 MSR_ARCH_PERFMON_FIXED_CTR0 - X86_PMC_IDX_FIXED;
1477 } else {
1478 hwc->config_base = x86_pmu.eventsel;
1479 hwc->event_base = x86_pmu.perfctr;
1480 }
1481}
1482
Peter Zijlstra2e841872010-01-25 15:58:43 +01001483static void __x86_pmu_disable(struct perf_event *event, struct cpu_hw_events *cpuc);
1484
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02001485void hw_perf_enable(void)
Ingo Molnaree060942008-12-13 09:00:03 +01001486{
Stephane Eranian1da53e02010-01-18 10:58:01 +02001487 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1488 struct perf_event *event;
1489 struct hw_perf_event *hwc;
1490 int i;
1491
Robert Richter85cf9db2009-04-29 12:47:20 +02001492 if (!x86_pmu_initialized())
Ingo Molnar2b9ff0d2008-12-14 18:36:30 +01001493 return;
Peter Zijlstra1a6e21f2010-01-27 23:07:47 +01001494
1495 if (cpuc->enabled)
1496 return;
1497
Stephane Eranian1da53e02010-01-18 10:58:01 +02001498 if (cpuc->n_added) {
1499 /*
1500 * apply assignment obtained either from
1501 * hw_perf_group_sched_in() or x86_pmu_enable()
1502 *
1503 * step1: save events moving to new counters
1504 * step2: reprogram moved events into new counters
1505 */
1506 for (i = 0; i < cpuc->n_events; i++) {
1507
1508 event = cpuc->event_list[i];
1509 hwc = &event->hw;
1510
1511 if (hwc->idx == -1 || hwc->idx == cpuc->assign[i])
1512 continue;
1513
Peter Zijlstra2e841872010-01-25 15:58:43 +01001514 __x86_pmu_disable(event, cpuc);
Stephane Eranian1da53e02010-01-18 10:58:01 +02001515
1516 hwc->idx = -1;
1517 }
1518
1519 for (i = 0; i < cpuc->n_events; i++) {
1520
1521 event = cpuc->event_list[i];
1522 hwc = &event->hw;
1523
1524 if (hwc->idx == -1) {
1525 x86_assign_hw_event(event, hwc, cpuc->assign[i]);
1526 x86_perf_event_set_period(event, hwc, hwc->idx);
1527 }
1528 /*
1529 * need to mark as active because x86_pmu_disable()
1530 * clear active_mask and eventsp[] yet it preserves
1531 * idx
1532 */
1533 set_bit(hwc->idx, cpuc->active_mask);
1534 cpuc->events[hwc->idx] = event;
1535
1536 x86_pmu.enable(hwc, hwc->idx);
1537 perf_event_update_userpage(event);
1538 }
1539 cpuc->n_added = 0;
1540 perf_events_lapic_init();
1541 }
Peter Zijlstra1a6e21f2010-01-27 23:07:47 +01001542
1543 cpuc->enabled = 1;
1544 barrier();
1545
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02001546 x86_pmu.enable_all();
Ingo Molnaree060942008-12-13 09:00:03 +01001547}
Ingo Molnaree060942008-12-13 09:00:03 +01001548
Robert Richter19d84da2009-04-29 12:47:25 +02001549static inline u64 intel_pmu_get_status(void)
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01001550{
1551 u64 status;
1552
1553 rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
1554
1555 return status;
1556}
1557
Robert Richterdee5d902009-04-29 12:47:07 +02001558static inline void intel_pmu_ack_status(u64 ack)
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01001559{
1560 wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
1561}
1562
Peter Zijlstra8c48e442010-01-29 13:25:31 +01001563static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, int idx)
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01001564{
Vince Weaver11d15782009-07-08 17:46:14 -04001565 (void)checking_wrmsrl(hwc->config_base + idx,
Robert Richter7c90cc42009-04-29 12:47:18 +02001566 hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE);
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01001567}
1568
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001569static inline void x86_pmu_disable_event(struct hw_perf_event *hwc, int idx)
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01001570{
Vince Weaver11d15782009-07-08 17:46:14 -04001571 (void)checking_wrmsrl(hwc->config_base + idx, hwc->config);
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01001572}
1573
Ingo Molnar7e2ae342008-12-09 11:40:46 +01001574static inline void
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001575intel_pmu_disable_fixed(struct hw_perf_event *hwc, int __idx)
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001576{
1577 int idx = __idx - X86_PMC_IDX_FIXED;
1578 u64 ctrl_val, mask;
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001579
1580 mask = 0xfULL << (idx * 4);
1581
1582 rdmsrl(hwc->config_base, ctrl_val);
1583 ctrl_val &= ~mask;
Vince Weaver11d15782009-07-08 17:46:14 -04001584 (void)checking_wrmsrl(hwc->config_base, ctrl_val);
1585}
1586
1587static inline void
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001588p6_pmu_disable_event(struct hw_perf_event *hwc, int idx)
Vince Weaver11d15782009-07-08 17:46:14 -04001589{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001590 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1591 u64 val = P6_NOP_EVENT;
Vince Weaver11d15782009-07-08 17:46:14 -04001592
Peter Zijlstra9c74fb52009-07-08 10:21:41 +02001593 if (cpuc->enabled)
1594 val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
Vince Weaver11d15782009-07-08 17:46:14 -04001595
1596 (void)checking_wrmsrl(hwc->config_base + idx, val);
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001597}
1598
1599static inline void
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001600intel_pmu_disable_event(struct hw_perf_event *hwc, int idx)
Ingo Molnar7e2ae342008-12-09 11:40:46 +01001601{
Markus Metzger30dd5682009-07-21 15:56:48 +02001602 if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
1603 intel_pmu_disable_bts();
1604 return;
1605 }
1606
Robert Richterd4369892009-04-29 12:47:19 +02001607 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
1608 intel_pmu_disable_fixed(hwc, idx);
1609 return;
1610 }
1611
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001612 x86_pmu_disable_event(hwc, idx);
Robert Richterd4369892009-04-29 12:47:19 +02001613}
1614
Tejun Heo245b2e72009-06-24 15:13:48 +09001615static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
Ingo Molnar241771e2008-12-03 10:39:53 +01001616
Ingo Molnaree060942008-12-13 09:00:03 +01001617/*
1618 * Set the next IRQ period, based on the hwc->period_left value.
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001619 * To be called with the event disabled in hw:
Ingo Molnaree060942008-12-13 09:00:03 +01001620 */
Peter Zijlstrae4abb5d2009-06-02 16:08:20 +02001621static int
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001622x86_perf_event_set_period(struct perf_event *event,
1623 struct hw_perf_event *hwc, int idx)
Ingo Molnar241771e2008-12-03 10:39:53 +01001624{
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001625 s64 left = atomic64_read(&hwc->period_left);
Peter Zijlstrae4abb5d2009-06-02 16:08:20 +02001626 s64 period = hwc->sample_period;
1627 int err, ret = 0;
Ingo Molnar241771e2008-12-03 10:39:53 +01001628
Markus Metzger30dd5682009-07-21 15:56:48 +02001629 if (idx == X86_PMC_IDX_FIXED_BTS)
1630 return 0;
1631
Ingo Molnaree060942008-12-13 09:00:03 +01001632 /*
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02001633 * If we are way outside a reasonable range then just skip forward:
Ingo Molnaree060942008-12-13 09:00:03 +01001634 */
1635 if (unlikely(left <= -period)) {
1636 left = period;
1637 atomic64_set(&hwc->period_left, left);
Peter Zijlstra9e350de2009-06-10 21:34:59 +02001638 hwc->last_period = period;
Peter Zijlstrae4abb5d2009-06-02 16:08:20 +02001639 ret = 1;
Ingo Molnaree060942008-12-13 09:00:03 +01001640 }
1641
1642 if (unlikely(left <= 0)) {
1643 left += period;
1644 atomic64_set(&hwc->period_left, left);
Peter Zijlstra9e350de2009-06-10 21:34:59 +02001645 hwc->last_period = period;
Peter Zijlstrae4abb5d2009-06-02 16:08:20 +02001646 ret = 1;
Ingo Molnaree060942008-12-13 09:00:03 +01001647 }
Ingo Molnar1c80f4b2009-05-15 08:25:22 +02001648 /*
Ingo Molnardfc65092009-09-21 11:31:35 +02001649 * Quirk: certain CPUs dont like it if just 1 hw_event is left:
Ingo Molnar1c80f4b2009-05-15 08:25:22 +02001650 */
1651 if (unlikely(left < 2))
1652 left = 2;
Ingo Molnaree060942008-12-13 09:00:03 +01001653
Peter Zijlstrae4abb5d2009-06-02 16:08:20 +02001654 if (left > x86_pmu.max_period)
1655 left = x86_pmu.max_period;
1656
Tejun Heo245b2e72009-06-24 15:13:48 +09001657 per_cpu(pmc_prev_left[idx], smp_processor_id()) = left;
Ingo Molnaree060942008-12-13 09:00:03 +01001658
1659 /*
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001660 * The hw event starts counting from this event offset,
Ingo Molnaree060942008-12-13 09:00:03 +01001661 * mark it to be able to extra future deltas:
1662 */
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001663 atomic64_set(&hwc->prev_count, (u64)-left);
Ingo Molnaree060942008-12-13 09:00:03 +01001664
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001665 err = checking_wrmsrl(hwc->event_base + idx,
1666 (u64)(-left) & x86_pmu.event_mask);
Peter Zijlstrae4abb5d2009-06-02 16:08:20 +02001667
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001668 perf_event_update_userpage(event);
Peter Zijlstra194002b2009-06-22 16:35:24 +02001669
Peter Zijlstrae4abb5d2009-06-02 16:08:20 +02001670 return ret;
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001671}
1672
1673static inline void
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001674intel_pmu_enable_fixed(struct hw_perf_event *hwc, int __idx)
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001675{
1676 int idx = __idx - X86_PMC_IDX_FIXED;
1677 u64 ctrl_val, bits, mask;
1678 int err;
1679
1680 /*
Paul Mackerras0475f9e2009-02-11 14:35:35 +11001681 * Enable IRQ generation (0x8),
1682 * and enable ring-3 counting (0x2) and ring-0 counting (0x1)
1683 * if requested:
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001684 */
Paul Mackerras0475f9e2009-02-11 14:35:35 +11001685 bits = 0x8ULL;
1686 if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
1687 bits |= 0x2;
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001688 if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
1689 bits |= 0x1;
Stephane Eranianb27d5152010-01-18 10:58:01 +02001690
1691 /*
1692 * ANY bit is supported in v3 and up
1693 */
1694 if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY)
1695 bits |= 0x4;
1696
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001697 bits <<= (idx * 4);
1698 mask = 0xfULL << (idx * 4);
1699
1700 rdmsrl(hwc->config_base, ctrl_val);
1701 ctrl_val &= ~mask;
1702 ctrl_val |= bits;
1703 err = checking_wrmsrl(hwc->config_base, ctrl_val);
Ingo Molnar7e2ae342008-12-09 11:40:46 +01001704}
1705
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001706static void p6_pmu_enable_event(struct hw_perf_event *hwc, int idx)
Vince Weaver11d15782009-07-08 17:46:14 -04001707{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001708 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
Peter Zijlstra984b8382009-07-10 09:59:56 +02001709 u64 val;
Vince Weaver11d15782009-07-08 17:46:14 -04001710
Peter Zijlstra984b8382009-07-10 09:59:56 +02001711 val = hwc->config;
Vince Weaver11d15782009-07-08 17:46:14 -04001712 if (cpuc->enabled)
Peter Zijlstra984b8382009-07-10 09:59:56 +02001713 val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
1714
1715 (void)checking_wrmsrl(hwc->config_base + idx, val);
Vince Weaver11d15782009-07-08 17:46:14 -04001716}
1717
1718
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001719static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx)
Ingo Molnar7e2ae342008-12-09 11:40:46 +01001720{
Markus Metzger30dd5682009-07-21 15:56:48 +02001721 if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001722 if (!__get_cpu_var(cpu_hw_events).enabled)
Markus Metzger30dd5682009-07-21 15:56:48 +02001723 return;
1724
1725 intel_pmu_enable_bts(hwc->config);
1726 return;
1727 }
1728
Robert Richter7c90cc42009-04-29 12:47:18 +02001729 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
1730 intel_pmu_enable_fixed(hwc, idx);
1731 return;
1732 }
1733
Peter Zijlstra8c48e442010-01-29 13:25:31 +01001734 __x86_pmu_enable_event(hwc, idx);
Robert Richter7c90cc42009-04-29 12:47:18 +02001735}
1736
Peter Zijlstra8c48e442010-01-29 13:25:31 +01001737static void x86_pmu_enable_event(struct hw_perf_event *hwc, int idx)
Robert Richter7c90cc42009-04-29 12:47:18 +02001738{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001739 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
Robert Richter7c90cc42009-04-29 12:47:18 +02001740 if (cpuc->enabled)
Peter Zijlstra8c48e442010-01-29 13:25:31 +01001741 __x86_pmu_enable_event(hwc, idx);
Ingo Molnar241771e2008-12-03 10:39:53 +01001742}
1743
Ingo Molnaree060942008-12-13 09:00:03 +01001744/*
Stephane Eranian1da53e02010-01-18 10:58:01 +02001745 * activate a single event
1746 *
1747 * The event is added to the group of enabled events
1748 * but only if it can be scehduled with existing events.
1749 *
1750 * Called with PMU disabled. If successful and return value 1,
1751 * then guaranteed to call perf_enable() and hw_perf_enable()
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02001752 */
1753static int x86_pmu_enable(struct perf_event *event)
1754{
1755 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
Stephane Eranian1da53e02010-01-18 10:58:01 +02001756 struct hw_perf_event *hwc;
1757 int assign[X86_PMC_IDX_MAX];
1758 int n, n0, ret;
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02001759
Stephane Eranian1da53e02010-01-18 10:58:01 +02001760 hwc = &event->hw;
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02001761
Stephane Eranian1da53e02010-01-18 10:58:01 +02001762 n0 = cpuc->n_events;
1763 n = collect_events(cpuc, event, false);
1764 if (n < 0)
1765 return n;
Ingo Molnar53b441a2009-05-25 21:41:28 +02001766
Stephane Eranian1da53e02010-01-18 10:58:01 +02001767 ret = x86_schedule_events(cpuc, n, assign);
1768 if (ret)
1769 return ret;
1770 /*
1771 * copy new assignment, now we know it is possible
1772 * will be used by hw_perf_enable()
1773 */
1774 memcpy(cpuc->assign, assign, n*sizeof(int));
Ingo Molnar241771e2008-12-03 10:39:53 +01001775
Stephane Eranian1da53e02010-01-18 10:58:01 +02001776 cpuc->n_events = n;
1777 cpuc->n_added = n - n0;
Ingo Molnar7e2ae342008-12-09 11:40:46 +01001778
Ingo Molnar95cdd2e2008-12-21 13:50:42 +01001779 return 0;
Ingo Molnar241771e2008-12-03 10:39:53 +01001780}
1781
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001782static void x86_pmu_unthrottle(struct perf_event *event)
Peter Zijlstraa78ac322009-05-25 17:39:05 +02001783{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001784 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1785 struct hw_perf_event *hwc = &event->hw;
Peter Zijlstraa78ac322009-05-25 17:39:05 +02001786
1787 if (WARN_ON_ONCE(hwc->idx >= X86_PMC_IDX_MAX ||
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001788 cpuc->events[hwc->idx] != event))
Peter Zijlstraa78ac322009-05-25 17:39:05 +02001789 return;
1790
1791 x86_pmu.enable(hwc, hwc->idx);
1792}
1793
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001794void perf_event_print_debug(void)
Ingo Molnar241771e2008-12-03 10:39:53 +01001795{
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001796 u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed;
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001797 struct cpu_hw_events *cpuc;
Peter Zijlstra5bb9efe2009-05-13 08:12:51 +02001798 unsigned long flags;
Ingo Molnar1e125672008-12-09 12:18:18 +01001799 int cpu, idx;
1800
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001801 if (!x86_pmu.num_events)
Ingo Molnar1e125672008-12-09 12:18:18 +01001802 return;
Ingo Molnar241771e2008-12-03 10:39:53 +01001803
Peter Zijlstra5bb9efe2009-05-13 08:12:51 +02001804 local_irq_save(flags);
Ingo Molnar241771e2008-12-03 10:39:53 +01001805
1806 cpu = smp_processor_id();
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001807 cpuc = &per_cpu(cpu_hw_events, cpu);
Ingo Molnar241771e2008-12-03 10:39:53 +01001808
Robert Richterfaa28ae2009-04-29 12:47:13 +02001809 if (x86_pmu.version >= 2) {
Jaswinder Singh Rajputa1ef58f2009-02-28 18:45:39 +05301810 rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl);
1811 rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
1812 rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow);
1813 rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed);
Ingo Molnar241771e2008-12-03 10:39:53 +01001814
Jaswinder Singh Rajputa1ef58f2009-02-28 18:45:39 +05301815 pr_info("\n");
1816 pr_info("CPU#%d: ctrl: %016llx\n", cpu, ctrl);
1817 pr_info("CPU#%d: status: %016llx\n", cpu, status);
1818 pr_info("CPU#%d: overflow: %016llx\n", cpu, overflow);
1819 pr_info("CPU#%d: fixed: %016llx\n", cpu, fixed);
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05301820 }
Stephane Eranian1da53e02010-01-18 10:58:01 +02001821 pr_info("CPU#%d: active: %016llx\n", cpu, *(u64 *)cpuc->active_mask);
Ingo Molnar241771e2008-12-03 10:39:53 +01001822
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001823 for (idx = 0; idx < x86_pmu.num_events; idx++) {
Robert Richter4a06bd82009-04-29 12:47:11 +02001824 rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl);
1825 rdmsrl(x86_pmu.perfctr + idx, pmc_count);
Ingo Molnar241771e2008-12-03 10:39:53 +01001826
Tejun Heo245b2e72009-06-24 15:13:48 +09001827 prev_left = per_cpu(pmc_prev_left[idx], cpu);
Ingo Molnar241771e2008-12-03 10:39:53 +01001828
Jaswinder Singh Rajputa1ef58f2009-02-28 18:45:39 +05301829 pr_info("CPU#%d: gen-PMC%d ctrl: %016llx\n",
Ingo Molnar241771e2008-12-03 10:39:53 +01001830 cpu, idx, pmc_ctrl);
Jaswinder Singh Rajputa1ef58f2009-02-28 18:45:39 +05301831 pr_info("CPU#%d: gen-PMC%d count: %016llx\n",
Ingo Molnar241771e2008-12-03 10:39:53 +01001832 cpu, idx, pmc_count);
Jaswinder Singh Rajputa1ef58f2009-02-28 18:45:39 +05301833 pr_info("CPU#%d: gen-PMC%d left: %016llx\n",
Ingo Molnaree060942008-12-13 09:00:03 +01001834 cpu, idx, prev_left);
Ingo Molnar241771e2008-12-03 10:39:53 +01001835 }
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001836 for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001837 rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
1838
Jaswinder Singh Rajputa1ef58f2009-02-28 18:45:39 +05301839 pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001840 cpu, idx, pmc_count);
1841 }
Peter Zijlstra5bb9efe2009-05-13 08:12:51 +02001842 local_irq_restore(flags);
Ingo Molnar241771e2008-12-03 10:39:53 +01001843}
1844
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001845static void intel_pmu_drain_bts_buffer(struct cpu_hw_events *cpuc)
Markus Metzger30dd5682009-07-21 15:56:48 +02001846{
1847 struct debug_store *ds = cpuc->ds;
1848 struct bts_record {
1849 u64 from;
1850 u64 to;
1851 u64 flags;
1852 };
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001853 struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS];
markus.t.metzger@intel.com596da172009-09-02 16:04:47 +02001854 struct bts_record *at, *top;
Markus Metzger5622f292009-09-15 13:00:23 +02001855 struct perf_output_handle handle;
1856 struct perf_event_header header;
1857 struct perf_sample_data data;
1858 struct pt_regs regs;
Markus Metzger30dd5682009-07-21 15:56:48 +02001859
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001860 if (!event)
Markus Metzger30dd5682009-07-21 15:56:48 +02001861 return;
1862
1863 if (!ds)
1864 return;
1865
markus.t.metzger@intel.com596da172009-09-02 16:04:47 +02001866 at = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
1867 top = (struct bts_record *)(unsigned long)ds->bts_index;
Markus Metzger30dd5682009-07-21 15:56:48 +02001868
Markus Metzger5622f292009-09-15 13:00:23 +02001869 if (top <= at)
1870 return;
1871
markus.t.metzger@intel.com596da172009-09-02 16:04:47 +02001872 ds->bts_index = ds->bts_buffer_base;
1873
Markus Metzger30dd5682009-07-21 15:56:48 +02001874
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001875 data.period = event->hw.last_period;
Markus Metzger5622f292009-09-15 13:00:23 +02001876 data.addr = 0;
Xiao Guangrong5e855db2009-12-10 17:08:54 +08001877 data.raw = NULL;
Markus Metzger5622f292009-09-15 13:00:23 +02001878 regs.ip = 0;
1879
1880 /*
1881 * Prepare a generic sample, i.e. fill in the invariant fields.
1882 * We will overwrite the from and to address before we output
1883 * the sample.
1884 */
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001885 perf_prepare_sample(&header, &data, event, &regs);
Markus Metzger5622f292009-09-15 13:00:23 +02001886
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001887 if (perf_output_begin(&handle, event,
Markus Metzger5622f292009-09-15 13:00:23 +02001888 header.size * (top - at), 1, 1))
1889 return;
1890
1891 for (; at < top; at++) {
1892 data.ip = at->from;
1893 data.addr = at->to;
1894
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001895 perf_output_sample(&handle, &header, &data, event);
Markus Metzger30dd5682009-07-21 15:56:48 +02001896 }
1897
Markus Metzger5622f292009-09-15 13:00:23 +02001898 perf_output_end(&handle);
Markus Metzger30dd5682009-07-21 15:56:48 +02001899
1900 /* There's new data available. */
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001901 event->hw.interrupts++;
1902 event->pending_kill = POLL_IN;
Markus Metzger30dd5682009-07-21 15:56:48 +02001903}
1904
Peter Zijlstra2e841872010-01-25 15:58:43 +01001905static void __x86_pmu_disable(struct perf_event *event, struct cpu_hw_events *cpuc)
Ingo Molnar241771e2008-12-03 10:39:53 +01001906{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001907 struct hw_perf_event *hwc = &event->hw;
Peter Zijlstra2e841872010-01-25 15:58:43 +01001908 int idx = hwc->idx;
Ingo Molnar241771e2008-12-03 10:39:53 +01001909
Robert Richter09534232009-04-29 12:47:16 +02001910 /*
1911 * Must be done before we disable, otherwise the nmi handler
1912 * could reenable again:
1913 */
Robert Richter43f62012009-04-29 16:55:56 +02001914 clear_bit(idx, cpuc->active_mask);
Robert Richterd4369892009-04-29 12:47:19 +02001915 x86_pmu.disable(hwc, idx);
Ingo Molnar241771e2008-12-03 10:39:53 +01001916
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01001917 /*
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001918 * Drain the remaining delta count out of a event
Ingo Molnaree060942008-12-13 09:00:03 +01001919 * that we are disabling:
1920 */
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001921 x86_perf_event_update(event, hwc, idx);
Markus Metzger30dd5682009-07-21 15:56:48 +02001922
1923 /* Drain the remaining BTS records. */
Markus Metzger5622f292009-09-15 13:00:23 +02001924 if (unlikely(idx == X86_PMC_IDX_FIXED_BTS))
1925 intel_pmu_drain_bts_buffer(cpuc);
Markus Metzger30dd5682009-07-21 15:56:48 +02001926
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001927 cpuc->events[idx] = NULL;
Peter Zijlstra2e841872010-01-25 15:58:43 +01001928}
1929
1930static void x86_pmu_disable(struct perf_event *event)
1931{
1932 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1933 int i;
1934
1935 __x86_pmu_disable(event, cpuc);
Peter Zijlstra194002b2009-06-22 16:35:24 +02001936
Stephane Eranian1da53e02010-01-18 10:58:01 +02001937 for (i = 0; i < cpuc->n_events; i++) {
1938 if (event == cpuc->event_list[i]) {
1939
1940 if (x86_pmu.put_event_constraints)
1941 x86_pmu.put_event_constraints(cpuc, event);
1942
1943 while (++i < cpuc->n_events)
1944 cpuc->event_list[i-1] = cpuc->event_list[i];
1945
1946 --cpuc->n_events;
Peter Zijlstra6c9687a2010-01-25 11:57:25 +01001947 break;
Stephane Eranian1da53e02010-01-18 10:58:01 +02001948 }
1949 }
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001950 perf_event_update_userpage(event);
Ingo Molnar241771e2008-12-03 10:39:53 +01001951}
1952
Ingo Molnar7e2ae342008-12-09 11:40:46 +01001953/*
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001954 * Save and restart an expired event. Called by NMI contexts,
1955 * so it has to be careful about preempting normal event ops:
Ingo Molnar7e2ae342008-12-09 11:40:46 +01001956 */
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001957static int intel_pmu_save_and_restart(struct perf_event *event)
Ingo Molnar241771e2008-12-03 10:39:53 +01001958{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001959 struct hw_perf_event *hwc = &event->hw;
Ingo Molnar241771e2008-12-03 10:39:53 +01001960 int idx = hwc->idx;
Peter Zijlstrae4abb5d2009-06-02 16:08:20 +02001961 int ret;
Ingo Molnar241771e2008-12-03 10:39:53 +01001962
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001963 x86_perf_event_update(event, hwc, idx);
1964 ret = x86_perf_event_set_period(event, hwc, idx);
Ingo Molnar7e2ae342008-12-09 11:40:46 +01001965
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001966 if (event->state == PERF_EVENT_STATE_ACTIVE)
1967 intel_pmu_enable_event(hwc, idx);
Peter Zijlstrae4abb5d2009-06-02 16:08:20 +02001968
1969 return ret;
Ingo Molnar241771e2008-12-03 10:39:53 +01001970}
1971
Ingo Molnaraaba9802009-05-26 08:10:00 +02001972static void intel_pmu_reset(void)
1973{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001974 struct debug_store *ds = __get_cpu_var(cpu_hw_events).ds;
Ingo Molnaraaba9802009-05-26 08:10:00 +02001975 unsigned long flags;
1976 int idx;
1977
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001978 if (!x86_pmu.num_events)
Ingo Molnaraaba9802009-05-26 08:10:00 +02001979 return;
1980
1981 local_irq_save(flags);
1982
1983 printk("clearing PMU state on CPU#%d\n", smp_processor_id());
1984
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001985 for (idx = 0; idx < x86_pmu.num_events; idx++) {
Ingo Molnaraaba9802009-05-26 08:10:00 +02001986 checking_wrmsrl(x86_pmu.eventsel + idx, 0ull);
1987 checking_wrmsrl(x86_pmu.perfctr + idx, 0ull);
1988 }
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001989 for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
Ingo Molnaraaba9802009-05-26 08:10:00 +02001990 checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
1991 }
Markus Metzger30dd5682009-07-21 15:56:48 +02001992 if (ds)
1993 ds->bts_index = ds->bts_buffer_base;
Ingo Molnaraaba9802009-05-26 08:10:00 +02001994
1995 local_irq_restore(flags);
1996}
1997
Ingo Molnar241771e2008-12-03 10:39:53 +01001998/*
1999 * This handler is triggered by the local APIC, so the APIC IRQ handling
2000 * rules apply:
2001 */
Yong Wanga3288102009-06-03 13:12:55 +08002002static int intel_pmu_handle_irq(struct pt_regs *regs)
Ingo Molnar241771e2008-12-03 10:39:53 +01002003{
Peter Zijlstradf1a1322009-06-10 21:02:22 +02002004 struct perf_sample_data data;
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002005 struct cpu_hw_events *cpuc;
Vince Weaver11d15782009-07-08 17:46:14 -04002006 int bit, loops;
Mike Galbraith4b39fd92009-01-23 14:36:16 +01002007 u64 ack, status;
Ingo Molnar9029a5e2009-05-15 08:26:20 +02002008
Peter Zijlstradf1a1322009-06-10 21:02:22 +02002009 data.addr = 0;
Xiao Guangrong5e855db2009-12-10 17:08:54 +08002010 data.raw = NULL;
Peter Zijlstradf1a1322009-06-10 21:02:22 +02002011
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002012 cpuc = &__get_cpu_var(cpu_hw_events);
Ingo Molnar43874d22008-12-09 12:23:59 +01002013
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02002014 perf_disable();
Markus Metzger5622f292009-09-15 13:00:23 +02002015 intel_pmu_drain_bts_buffer(cpuc);
Robert Richter19d84da2009-04-29 12:47:25 +02002016 status = intel_pmu_get_status();
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02002017 if (!status) {
2018 perf_enable();
2019 return 0;
2020 }
Ingo Molnar87b9cf42008-12-08 14:20:16 +01002021
Ingo Molnar9029a5e2009-05-15 08:26:20 +02002022 loops = 0;
Ingo Molnar241771e2008-12-03 10:39:53 +01002023again:
Ingo Molnar9029a5e2009-05-15 08:26:20 +02002024 if (++loops > 100) {
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002025 WARN_ONCE(1, "perfevents: irq loop stuck!\n");
2026 perf_event_print_debug();
Ingo Molnaraaba9802009-05-26 08:10:00 +02002027 intel_pmu_reset();
2028 perf_enable();
Ingo Molnar9029a5e2009-05-15 08:26:20 +02002029 return 1;
2030 }
2031
Mike Galbraithd278c482009-02-09 07:38:50 +01002032 inc_irq_stat(apic_perf_irqs);
Ingo Molnar241771e2008-12-03 10:39:53 +01002033 ack = status;
Ingo Molnar2f18d1e2008-12-22 11:10:42 +01002034 for_each_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002035 struct perf_event *event = cpuc->events[bit];
Ingo Molnar241771e2008-12-03 10:39:53 +01002036
2037 clear_bit(bit, (unsigned long *) &status);
Robert Richter43f62012009-04-29 16:55:56 +02002038 if (!test_bit(bit, cpuc->active_mask))
Ingo Molnar241771e2008-12-03 10:39:53 +01002039 continue;
2040
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002041 if (!intel_pmu_save_and_restart(event))
Peter Zijlstrae4abb5d2009-06-02 16:08:20 +02002042 continue;
2043
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002044 data.period = event->hw.last_period;
Peter Zijlstra60f916d2009-06-15 19:00:20 +02002045
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002046 if (perf_event_overflow(event, 1, &data, regs))
2047 intel_pmu_disable_event(&event->hw, bit);
Ingo Molnar241771e2008-12-03 10:39:53 +01002048 }
2049
Robert Richterdee5d902009-04-29 12:47:07 +02002050 intel_pmu_ack_status(ack);
Ingo Molnar241771e2008-12-03 10:39:53 +01002051
2052 /*
2053 * Repeat if there is more work to be done:
2054 */
Robert Richter19d84da2009-04-29 12:47:25 +02002055 status = intel_pmu_get_status();
Ingo Molnar241771e2008-12-03 10:39:53 +01002056 if (status)
2057 goto again;
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01002058
Peter Zijlstra48e22d52009-05-25 17:39:04 +02002059 perf_enable();
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02002060
2061 return 1;
Mike Galbraith1b023a92009-01-23 10:13:01 +01002062}
2063
Peter Zijlstra8c48e442010-01-29 13:25:31 +01002064static int x86_pmu_handle_irq(struct pt_regs *regs)
Robert Richtera29aa8a2009-04-29 12:47:21 +02002065{
Peter Zijlstradf1a1322009-06-10 21:02:22 +02002066 struct perf_sample_data data;
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002067 struct cpu_hw_events *cpuc;
2068 struct perf_event *event;
2069 struct hw_perf_event *hwc;
Vince Weaver11d15782009-07-08 17:46:14 -04002070 int idx, handled = 0;
Ingo Molnar9029a5e2009-05-15 08:26:20 +02002071 u64 val;
2072
Peter Zijlstradf1a1322009-06-10 21:02:22 +02002073 data.addr = 0;
Xiao Guangrong5e855db2009-12-10 17:08:54 +08002074 data.raw = NULL;
Peter Zijlstradf1a1322009-06-10 21:02:22 +02002075
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002076 cpuc = &__get_cpu_var(cpu_hw_events);
Robert Richtera29aa8a2009-04-29 12:47:21 +02002077
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002078 for (idx = 0; idx < x86_pmu.num_events; idx++) {
Robert Richter43f62012009-04-29 16:55:56 +02002079 if (!test_bit(idx, cpuc->active_mask))
Robert Richtera29aa8a2009-04-29 12:47:21 +02002080 continue;
Peter Zijlstra962bf7a2009-05-13 13:21:36 +02002081
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002082 event = cpuc->events[idx];
2083 hwc = &event->hw;
Peter Zijlstraa4016a72009-05-14 14:52:17 +02002084
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002085 val = x86_perf_event_update(event, hwc, idx);
2086 if (val & (1ULL << (x86_pmu.event_bits - 1)))
Peter Zijlstra48e22d52009-05-25 17:39:04 +02002087 continue;
Peter Zijlstra962bf7a2009-05-13 13:21:36 +02002088
Peter Zijlstra9e350de2009-06-10 21:34:59 +02002089 /*
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002090 * event overflow
Peter Zijlstra9e350de2009-06-10 21:34:59 +02002091 */
2092 handled = 1;
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002093 data.period = event->hw.last_period;
Peter Zijlstra9e350de2009-06-10 21:34:59 +02002094
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002095 if (!x86_perf_event_set_period(event, hwc, idx))
Peter Zijlstrae4abb5d2009-06-02 16:08:20 +02002096 continue;
2097
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002098 if (perf_event_overflow(event, 1, &data, regs))
Peter Zijlstra8c48e442010-01-29 13:25:31 +01002099 x86_pmu.disable(hwc, idx);
Robert Richtera29aa8a2009-04-29 12:47:21 +02002100 }
Peter Zijlstra962bf7a2009-05-13 13:21:36 +02002101
Peter Zijlstra9e350de2009-06-10 21:34:59 +02002102 if (handled)
2103 inc_irq_stat(apic_perf_irqs);
2104
Robert Richtera29aa8a2009-04-29 12:47:21 +02002105 return handled;
2106}
Robert Richter39d81ea2009-04-29 12:47:05 +02002107
Peter Zijlstrab6276f32009-04-06 11:45:03 +02002108void smp_perf_pending_interrupt(struct pt_regs *regs)
2109{
2110 irq_enter();
2111 ack_APIC_irq();
2112 inc_irq_stat(apic_pending_irqs);
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002113 perf_event_do_pending();
Peter Zijlstrab6276f32009-04-06 11:45:03 +02002114 irq_exit();
2115}
2116
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002117void set_perf_event_pending(void)
Peter Zijlstrab6276f32009-04-06 11:45:03 +02002118{
Ingo Molnar04da8a42009-08-11 10:40:08 +02002119#ifdef CONFIG_X86_LOCAL_APIC
Peter Zijlstra7d428962009-09-23 11:03:37 +02002120 if (!x86_pmu.apic || !x86_pmu_initialized())
2121 return;
2122
Peter Zijlstrab6276f32009-04-06 11:45:03 +02002123 apic->send_IPI_self(LOCAL_PENDING_VECTOR);
Ingo Molnar04da8a42009-08-11 10:40:08 +02002124#endif
Peter Zijlstrab6276f32009-04-06 11:45:03 +02002125}
2126
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002127void perf_events_lapic_init(void)
Ingo Molnar241771e2008-12-03 10:39:53 +01002128{
Ingo Molnar04da8a42009-08-11 10:40:08 +02002129#ifdef CONFIG_X86_LOCAL_APIC
2130 if (!x86_pmu.apic || !x86_pmu_initialized())
Ingo Molnar241771e2008-12-03 10:39:53 +01002131 return;
Robert Richter85cf9db2009-04-29 12:47:20 +02002132
Ingo Molnar241771e2008-12-03 10:39:53 +01002133 /*
Yong Wangc323d952009-05-29 13:28:35 +08002134 * Always use NMI for PMU
Ingo Molnar241771e2008-12-03 10:39:53 +01002135 */
Yong Wangc323d952009-05-29 13:28:35 +08002136 apic_write(APIC_LVTPC, APIC_DM_NMI);
Ingo Molnar04da8a42009-08-11 10:40:08 +02002137#endif
Ingo Molnar241771e2008-12-03 10:39:53 +01002138}
2139
2140static int __kprobes
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002141perf_event_nmi_handler(struct notifier_block *self,
Ingo Molnar241771e2008-12-03 10:39:53 +01002142 unsigned long cmd, void *__args)
2143{
2144 struct die_args *args = __args;
2145 struct pt_regs *regs;
2146
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002147 if (!atomic_read(&active_events))
Peter Zijlstra63a809a2009-05-01 12:23:17 +02002148 return NOTIFY_DONE;
2149
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01002150 switch (cmd) {
2151 case DIE_NMI:
2152 case DIE_NMI_IPI:
2153 break;
2154
2155 default:
Ingo Molnar241771e2008-12-03 10:39:53 +01002156 return NOTIFY_DONE;
Peter Zijlstrab0f3f282009-03-05 18:08:27 +01002157 }
Ingo Molnar241771e2008-12-03 10:39:53 +01002158
2159 regs = args->regs;
2160
Ingo Molnar04da8a42009-08-11 10:40:08 +02002161#ifdef CONFIG_X86_LOCAL_APIC
Ingo Molnar241771e2008-12-03 10:39:53 +01002162 apic_write(APIC_LVTPC, APIC_DM_NMI);
Ingo Molnar04da8a42009-08-11 10:40:08 +02002163#endif
Peter Zijlstraa4016a72009-05-14 14:52:17 +02002164 /*
2165 * Can't rely on the handled return value to say it was our NMI, two
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002166 * events could trigger 'simultaneously' raising two back-to-back NMIs.
Peter Zijlstraa4016a72009-05-14 14:52:17 +02002167 *
2168 * If the first NMI handles both, the latter will be empty and daze
2169 * the CPU.
2170 */
Yong Wanga3288102009-06-03 13:12:55 +08002171 x86_pmu.handle_irq(regs);
Ingo Molnar241771e2008-12-03 10:39:53 +01002172
Peter Zijlstraa4016a72009-05-14 14:52:17 +02002173 return NOTIFY_STOP;
Ingo Molnar241771e2008-12-03 10:39:53 +01002174}
2175
Peter Zijlstra63b14642010-01-22 16:32:17 +01002176static struct event_constraint unconstrained;
2177
Peter Zijlstrac91e0f52010-01-22 15:25:59 +01002178static struct event_constraint bts_constraint =
2179 EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0);
Stephane Eranian1da53e02010-01-18 10:58:01 +02002180
Peter Zijlstra63b14642010-01-22 16:32:17 +01002181static struct event_constraint *
2182intel_special_constraints(struct perf_event *event)
Stephane Eranian1da53e02010-01-18 10:58:01 +02002183{
2184 unsigned int hw_event;
2185
2186 hw_event = event->hw.config & INTEL_ARCH_EVENT_MASK;
2187
2188 if (unlikely((hw_event ==
2189 x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) &&
2190 (event->hw.sample_period == 1))) {
2191
Peter Zijlstra63b14642010-01-22 16:32:17 +01002192 return &bts_constraint;
Stephane Eranian1da53e02010-01-18 10:58:01 +02002193 }
Peter Zijlstra63b14642010-01-22 16:32:17 +01002194 return NULL;
Stephane Eranian1da53e02010-01-18 10:58:01 +02002195}
2196
Peter Zijlstra63b14642010-01-22 16:32:17 +01002197static struct event_constraint *
2198intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
Stephane Eranian1da53e02010-01-18 10:58:01 +02002199{
Peter Zijlstra63b14642010-01-22 16:32:17 +01002200 struct event_constraint *c;
Stephane Eranian1da53e02010-01-18 10:58:01 +02002201
Peter Zijlstra63b14642010-01-22 16:32:17 +01002202 c = intel_special_constraints(event);
2203 if (c)
2204 return c;
Stephane Eranian1da53e02010-01-18 10:58:01 +02002205
2206 if (x86_pmu.event_constraints) {
2207 for_each_event_constraint(c, x86_pmu.event_constraints) {
Peter Zijlstra63b14642010-01-22 16:32:17 +01002208 if ((event->hw.config & c->cmask) == c->code)
2209 return c;
Stephane Eranian1da53e02010-01-18 10:58:01 +02002210 }
2211 }
Peter Zijlstra63b14642010-01-22 16:32:17 +01002212
2213 return &unconstrained;
Stephane Eranian1da53e02010-01-18 10:58:01 +02002214}
2215
Peter Zijlstra63b14642010-01-22 16:32:17 +01002216static struct event_constraint *
2217amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
Stephane Eranian1da53e02010-01-18 10:58:01 +02002218{
Peter Zijlstra63b14642010-01-22 16:32:17 +01002219 return &unconstrained;
Stephane Eranian1da53e02010-01-18 10:58:01 +02002220}
2221
2222static int x86_event_sched_in(struct perf_event *event,
2223 struct perf_cpu_context *cpuctx, int cpu)
2224{
2225 int ret = 0;
2226
2227 event->state = PERF_EVENT_STATE_ACTIVE;
2228 event->oncpu = cpu;
2229 event->tstamp_running += event->ctx->time - event->tstamp_stopped;
2230
2231 if (!is_x86_event(event))
2232 ret = event->pmu->enable(event);
2233
2234 if (!ret && !is_software_event(event))
2235 cpuctx->active_oncpu++;
2236
2237 if (!ret && event->attr.exclusive)
2238 cpuctx->exclusive = 1;
2239
2240 return ret;
2241}
2242
2243static void x86_event_sched_out(struct perf_event *event,
2244 struct perf_cpu_context *cpuctx, int cpu)
2245{
2246 event->state = PERF_EVENT_STATE_INACTIVE;
2247 event->oncpu = -1;
2248
2249 if (!is_x86_event(event))
2250 event->pmu->disable(event);
2251
2252 event->tstamp_running -= event->ctx->time - event->tstamp_stopped;
2253
2254 if (!is_software_event(event))
2255 cpuctx->active_oncpu--;
2256
2257 if (event->attr.exclusive || !cpuctx->active_oncpu)
2258 cpuctx->exclusive = 0;
2259}
2260
2261/*
2262 * Called to enable a whole group of events.
2263 * Returns 1 if the group was enabled, or -EAGAIN if it could not be.
2264 * Assumes the caller has disabled interrupts and has
2265 * frozen the PMU with hw_perf_save_disable.
2266 *
2267 * called with PMU disabled. If successful and return value 1,
2268 * then guaranteed to call perf_enable() and hw_perf_enable()
2269 */
2270int hw_perf_group_sched_in(struct perf_event *leader,
2271 struct perf_cpu_context *cpuctx,
2272 struct perf_event_context *ctx, int cpu)
2273{
2274 struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
2275 struct perf_event *sub;
2276 int assign[X86_PMC_IDX_MAX];
2277 int n0, n1, ret;
2278
2279 /* n0 = total number of events */
2280 n0 = collect_events(cpuc, leader, true);
2281 if (n0 < 0)
2282 return n0;
2283
2284 ret = x86_schedule_events(cpuc, n0, assign);
2285 if (ret)
2286 return ret;
2287
2288 ret = x86_event_sched_in(leader, cpuctx, cpu);
2289 if (ret)
2290 return ret;
2291
2292 n1 = 1;
2293 list_for_each_entry(sub, &leader->sibling_list, group_entry) {
Stephane Eranian81130702010-01-21 17:39:01 +02002294 if (sub->state > PERF_EVENT_STATE_OFF) {
Stephane Eranian1da53e02010-01-18 10:58:01 +02002295 ret = x86_event_sched_in(sub, cpuctx, cpu);
2296 if (ret)
2297 goto undo;
2298 ++n1;
2299 }
2300 }
2301 /*
2302 * copy new assignment, now we know it is possible
2303 * will be used by hw_perf_enable()
2304 */
2305 memcpy(cpuc->assign, assign, n0*sizeof(int));
2306
2307 cpuc->n_events = n0;
2308 cpuc->n_added = n1;
2309 ctx->nr_active += n1;
2310
2311 /*
2312 * 1 means successful and events are active
2313 * This is not quite true because we defer
2314 * actual activation until hw_perf_enable() but
2315 * this way we* ensure caller won't try to enable
2316 * individual events
2317 */
2318 return 1;
2319undo:
2320 x86_event_sched_out(leader, cpuctx, cpu);
2321 n0 = 1;
2322 list_for_each_entry(sub, &leader->sibling_list, group_entry) {
2323 if (sub->state == PERF_EVENT_STATE_ACTIVE) {
2324 x86_event_sched_out(sub, cpuctx, cpu);
2325 if (++n0 == n1)
2326 break;
2327 }
2328 }
2329 return ret;
2330}
2331
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002332static __read_mostly struct notifier_block perf_event_nmi_notifier = {
2333 .notifier_call = perf_event_nmi_handler,
Mike Galbraith5b75af02009-02-04 17:11:34 +01002334 .next = NULL,
2335 .priority = 1
Ingo Molnar241771e2008-12-03 10:39:53 +01002336};
2337
Hiroshi Shimamotodb48ccc2009-11-12 11:25:34 +09002338static __initconst struct x86_pmu p6_pmu = {
Vince Weaver11d15782009-07-08 17:46:14 -04002339 .name = "p6",
Peter Zijlstra8c48e442010-01-29 13:25:31 +01002340 .handle_irq = x86_pmu_handle_irq,
Vince Weaver11d15782009-07-08 17:46:14 -04002341 .disable_all = p6_pmu_disable_all,
2342 .enable_all = p6_pmu_enable_all,
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002343 .enable = p6_pmu_enable_event,
2344 .disable = p6_pmu_disable_event,
Vince Weaver11d15782009-07-08 17:46:14 -04002345 .eventsel = MSR_P6_EVNTSEL0,
2346 .perfctr = MSR_P6_PERFCTR0,
2347 .event_map = p6_pmu_event_map,
2348 .raw_event = p6_pmu_raw_event,
2349 .max_events = ARRAY_SIZE(p6_perfmon_event_map),
Ingo Molnar04da8a42009-08-11 10:40:08 +02002350 .apic = 1,
Vince Weaver11d15782009-07-08 17:46:14 -04002351 .max_period = (1ULL << 31) - 1,
2352 .version = 0,
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002353 .num_events = 2,
Vince Weaver11d15782009-07-08 17:46:14 -04002354 /*
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002355 * Events have 40 bits implemented. However they are designed such
Vince Weaver11d15782009-07-08 17:46:14 -04002356 * that bits [32-39] are sign extensions of bit 31. As such the
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002357 * effective width of a event for P6-like PMU is 32 bits only.
Vince Weaver11d15782009-07-08 17:46:14 -04002358 *
2359 * See IA-32 Intel Architecture Software developer manual Vol 3B
2360 */
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002361 .event_bits = 32,
2362 .event_mask = (1ULL << 32) - 1,
Stephane Eranian1da53e02010-01-18 10:58:01 +02002363 .get_event_constraints = intel_get_event_constraints,
2364 .event_constraints = intel_p6_event_constraints
Vince Weaver11d15782009-07-08 17:46:14 -04002365};
2366
Peter Zijlstra8c48e442010-01-29 13:25:31 +01002367static __initconst struct x86_pmu core_pmu = {
2368 .name = "core",
2369 .handle_irq = x86_pmu_handle_irq,
2370 .disable_all = x86_pmu_disable_all,
2371 .enable_all = x86_pmu_enable_all,
2372 .enable = x86_pmu_enable_event,
2373 .disable = x86_pmu_disable_event,
2374 .eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
2375 .perfctr = MSR_ARCH_PERFMON_PERFCTR0,
2376 .event_map = intel_pmu_event_map,
2377 .raw_event = intel_pmu_raw_event,
2378 .max_events = ARRAY_SIZE(intel_perfmon_event_map),
2379 .apic = 1,
2380 /*
2381 * Intel PMCs cannot be accessed sanely above 32 bit width,
2382 * so we install an artificial 1<<31 period regardless of
2383 * the generic event period:
2384 */
2385 .max_period = (1ULL << 31) - 1,
2386 .get_event_constraints = intel_get_event_constraints,
2387 .event_constraints = intel_core_event_constraints,
2388};
2389
Hiroshi Shimamotodb48ccc2009-11-12 11:25:34 +09002390static __initconst struct x86_pmu intel_pmu = {
Robert Richterfaa28ae2009-04-29 12:47:13 +02002391 .name = "Intel",
Robert Richter39d81ea2009-04-29 12:47:05 +02002392 .handle_irq = intel_pmu_handle_irq,
Peter Zijlstra9e35ad32009-05-13 16:21:38 +02002393 .disable_all = intel_pmu_disable_all,
2394 .enable_all = intel_pmu_enable_all,
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002395 .enable = intel_pmu_enable_event,
2396 .disable = intel_pmu_disable_event,
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05302397 .eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
2398 .perfctr = MSR_ARCH_PERFMON_PERFCTR0,
Robert Richter5f4ec282009-04-29 12:47:04 +02002399 .event_map = intel_pmu_event_map,
2400 .raw_event = intel_pmu_raw_event,
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05302401 .max_events = ARRAY_SIZE(intel_perfmon_event_map),
Ingo Molnar04da8a42009-08-11 10:40:08 +02002402 .apic = 1,
Robert Richterc619b8f2009-04-29 12:47:23 +02002403 /*
2404 * Intel PMCs cannot be accessed sanely above 32 bit width,
2405 * so we install an artificial 1<<31 period regardless of
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002406 * the generic event period:
Robert Richterc619b8f2009-04-29 12:47:23 +02002407 */
2408 .max_period = (1ULL << 31) - 1,
Markus Metzger30dd5682009-07-21 15:56:48 +02002409 .enable_bts = intel_pmu_enable_bts,
2410 .disable_bts = intel_pmu_disable_bts,
Stephane Eranian1da53e02010-01-18 10:58:01 +02002411 .get_event_constraints = intel_get_event_constraints
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05302412};
2413
Hiroshi Shimamotodb48ccc2009-11-12 11:25:34 +09002414static __initconst struct x86_pmu amd_pmu = {
Robert Richterfaa28ae2009-04-29 12:47:13 +02002415 .name = "AMD",
Peter Zijlstra8c48e442010-01-29 13:25:31 +01002416 .handle_irq = x86_pmu_handle_irq,
2417 .disable_all = x86_pmu_disable_all,
2418 .enable_all = x86_pmu_enable_all,
2419 .enable = x86_pmu_enable_event,
2420 .disable = x86_pmu_disable_event,
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05302421 .eventsel = MSR_K7_EVNTSEL0,
2422 .perfctr = MSR_K7_PERFCTR0,
Robert Richter5f4ec282009-04-29 12:47:04 +02002423 .event_map = amd_pmu_event_map,
2424 .raw_event = amd_pmu_raw_event,
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05302425 .max_events = ARRAY_SIZE(amd_perfmon_event_map),
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002426 .num_events = 4,
2427 .event_bits = 48,
2428 .event_mask = (1ULL << 48) - 1,
Ingo Molnar04da8a42009-08-11 10:40:08 +02002429 .apic = 1,
Robert Richterc619b8f2009-04-29 12:47:23 +02002430 /* use highest bit to detect overflow */
2431 .max_period = (1ULL << 47) - 1,
Stephane Eranian1da53e02010-01-18 10:58:01 +02002432 .get_event_constraints = amd_get_event_constraints
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05302433};
2434
Hiroshi Shimamotodb48ccc2009-11-12 11:25:34 +09002435static __init int p6_pmu_init(void)
Vince Weaver11d15782009-07-08 17:46:14 -04002436{
Vince Weaver11d15782009-07-08 17:46:14 -04002437 switch (boot_cpu_data.x86_model) {
2438 case 1:
2439 case 3: /* Pentium Pro */
2440 case 5:
2441 case 6: /* Pentium II */
2442 case 7:
2443 case 8:
2444 case 11: /* Pentium III */
Vince Weaver11d15782009-07-08 17:46:14 -04002445 case 9:
2446 case 13:
Daniel Qarrasf1c6a582009-07-12 04:32:40 -07002447 /* Pentium M */
2448 break;
Vince Weaver11d15782009-07-08 17:46:14 -04002449 default:
2450 pr_cont("unsupported p6 CPU model %d ",
2451 boot_cpu_data.x86_model);
2452 return -ENODEV;
2453 }
2454
Ingo Molnar04da8a42009-08-11 10:40:08 +02002455 x86_pmu = p6_pmu;
Vince Weaver11d15782009-07-08 17:46:14 -04002456
Vince Weaver11d15782009-07-08 17:46:14 -04002457 return 0;
2458}
2459
Hiroshi Shimamotodb48ccc2009-11-12 11:25:34 +09002460static __init int intel_pmu_init(void)
Ingo Molnar241771e2008-12-03 10:39:53 +01002461{
Ingo Molnar703e9372008-12-17 10:51:15 +01002462 union cpuid10_edx edx;
Ingo Molnar7bb497b2009-03-18 08:59:21 +01002463 union cpuid10_eax eax;
2464 unsigned int unused;
2465 unsigned int ebx;
Robert Richterfaa28ae2009-04-29 12:47:13 +02002466 int version;
Ingo Molnar241771e2008-12-03 10:39:53 +01002467
Vince Weaver11d15782009-07-08 17:46:14 -04002468 if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
2469 /* check for P6 processor family */
2470 if (boot_cpu_data.x86 == 6) {
2471 return p6_pmu_init();
2472 } else {
Robert Richter72eae042009-04-29 12:47:10 +02002473 return -ENODEV;
Vince Weaver11d15782009-07-08 17:46:14 -04002474 }
2475 }
Robert Richterda1a7762009-04-29 12:46:58 +02002476
Ingo Molnar241771e2008-12-03 10:39:53 +01002477 /*
2478 * Check whether the Architectural PerfMon supports
Ingo Molnardfc65092009-09-21 11:31:35 +02002479 * Branch Misses Retired hw_event or not.
Ingo Molnar241771e2008-12-03 10:39:53 +01002480 */
Ingo Molnar703e9372008-12-17 10:51:15 +01002481 cpuid(10, &eax.full, &ebx, &unused, &edx.full);
Ingo Molnar241771e2008-12-03 10:39:53 +01002482 if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED)
Robert Richter72eae042009-04-29 12:47:10 +02002483 return -ENODEV;
Ingo Molnar241771e2008-12-03 10:39:53 +01002484
Robert Richterfaa28ae2009-04-29 12:47:13 +02002485 version = eax.split.version_id;
2486 if (version < 2)
Peter Zijlstra8c48e442010-01-29 13:25:31 +01002487 x86_pmu = core_pmu;
2488 else
2489 x86_pmu = intel_pmu;
Ingo Molnar7bb497b2009-03-18 08:59:21 +01002490
Ingo Molnar1123e3a2009-05-29 11:25:09 +02002491 x86_pmu.version = version;
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002492 x86_pmu.num_events = eax.split.num_events;
2493 x86_pmu.event_bits = eax.split.bit_width;
2494 x86_pmu.event_mask = (1ULL << eax.split.bit_width) - 1;
Ingo Molnar066d7de2009-05-04 19:04:09 +02002495
2496 /*
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002497 * Quirk: v2 perfmon does not report fixed-purpose events, so
2498 * assume at least 3 events:
Ingo Molnar066d7de2009-05-04 19:04:09 +02002499 */
Peter Zijlstra8c48e442010-01-29 13:25:31 +01002500 if (version > 1)
2501 x86_pmu.num_events_fixed = max((int)edx.split.num_events_fixed, 3);
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05302502
Ingo Molnar8326f442009-06-05 20:22:46 +02002503 /*
Ingo Molnar1123e3a2009-05-29 11:25:09 +02002504 * Install the hw-cache-events table:
Ingo Molnar8326f442009-06-05 20:22:46 +02002505 */
2506 switch (boot_cpu_data.x86_model) {
Peter Zijlstra8c48e442010-01-29 13:25:31 +01002507 case 14: /* 65 nm core solo/duo, "Yonah" */
2508 pr_cont("Core events, ");
2509 break;
2510
Yong Wangdc810812009-06-10 17:06:12 +08002511 case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
2512 case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
2513 case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
2514 case 29: /* six-core 45 nm xeon "Dunnington" */
Ingo Molnar8326f442009-06-05 20:22:46 +02002515 memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
Thomas Gleixner820a6442009-06-08 19:10:25 +02002516 sizeof(hw_cache_event_ids));
Ingo Molnar8326f442009-06-05 20:22:46 +02002517
Peter Zijlstra8c48e442010-01-29 13:25:31 +01002518 x86_pmu.event_constraints = intel_core2_event_constraints;
Ingo Molnar1123e3a2009-05-29 11:25:09 +02002519 pr_cont("Core2 events, ");
Ingo Molnar8326f442009-06-05 20:22:46 +02002520 break;
Peter Zijlstra452a3392010-01-27 23:07:48 +01002521
2522 case 26: /* 45 nm nehalem, "Bloomfield" */
2523 case 30: /* 45 nm nehalem, "Lynnfield" */
Ingo Molnar8326f442009-06-05 20:22:46 +02002524 memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
Thomas Gleixner820a6442009-06-08 19:10:25 +02002525 sizeof(hw_cache_event_ids));
Ingo Molnar8326f442009-06-05 20:22:46 +02002526
Stephane Eranian1da53e02010-01-18 10:58:01 +02002527 x86_pmu.event_constraints = intel_nehalem_event_constraints;
Ingo Molnar1123e3a2009-05-29 11:25:09 +02002528 pr_cont("Nehalem/Corei7 events, ");
Ingo Molnar8326f442009-06-05 20:22:46 +02002529 break;
2530 case 28:
2531 memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
Thomas Gleixner820a6442009-06-08 19:10:25 +02002532 sizeof(hw_cache_event_ids));
Ingo Molnar8326f442009-06-05 20:22:46 +02002533
Stephane Eranian1da53e02010-01-18 10:58:01 +02002534 x86_pmu.event_constraints = intel_gen_event_constraints;
Ingo Molnar1123e3a2009-05-29 11:25:09 +02002535 pr_cont("Atom events, ");
Ingo Molnar8326f442009-06-05 20:22:46 +02002536 break;
Peter Zijlstra452a3392010-01-27 23:07:48 +01002537
2538 case 37: /* 32 nm nehalem, "Clarkdale" */
2539 case 44: /* 32 nm nehalem, "Gulftown" */
2540 memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
2541 sizeof(hw_cache_event_ids));
2542
2543 x86_pmu.event_constraints = intel_westmere_event_constraints;
2544 pr_cont("Westmere events, ");
2545 break;
Stephane Eranian1da53e02010-01-18 10:58:01 +02002546 default:
2547 /*
2548 * default constraints for v2 and up
2549 */
2550 x86_pmu.event_constraints = intel_gen_event_constraints;
2551 pr_cont("generic architected perfmon, ");
Ingo Molnar8326f442009-06-05 20:22:46 +02002552 }
Robert Richter72eae042009-04-29 12:47:10 +02002553 return 0;
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05302554}
2555
Hiroshi Shimamotodb48ccc2009-11-12 11:25:34 +09002556static __init int amd_pmu_init(void)
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05302557{
Jaswinder Singh Rajput4d2be122009-06-11 15:28:09 +05302558 /* Performance-monitoring supported from K7 and later: */
2559 if (boot_cpu_data.x86 < 6)
2560 return -ENODEV;
2561
Robert Richter4a06bd82009-04-29 12:47:11 +02002562 x86_pmu = amd_pmu;
Thomas Gleixnerf86748e2009-06-08 22:33:10 +02002563
Jaswinder Singh Rajputf4db43a2009-06-13 01:06:21 +05302564 /* Events are common for all AMDs */
2565 memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
2566 sizeof(hw_cache_event_ids));
Thomas Gleixnerf86748e2009-06-08 22:33:10 +02002567
Robert Richter72eae042009-04-29 12:47:10 +02002568 return 0;
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05302569}
2570
Cyrill Gorcunov12558032009-12-10 19:56:34 +03002571static void __init pmu_check_apic(void)
2572{
2573 if (cpu_has_apic)
2574 return;
2575
2576 x86_pmu.apic = 0;
2577 pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
2578 pr_info("no hardware sampling interrupt available.\n");
2579}
2580
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002581void __init init_hw_perf_events(void)
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05302582{
Robert Richter72eae042009-04-29 12:47:10 +02002583 int err;
2584
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002585 pr_info("Performance Events: ");
Ingo Molnar1123e3a2009-05-29 11:25:09 +02002586
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05302587 switch (boot_cpu_data.x86_vendor) {
2588 case X86_VENDOR_INTEL:
Robert Richter72eae042009-04-29 12:47:10 +02002589 err = intel_pmu_init();
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05302590 break;
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05302591 case X86_VENDOR_AMD:
Robert Richter72eae042009-04-29 12:47:10 +02002592 err = amd_pmu_init();
Jaswinder Singh Rajputf87ad352009-02-27 20:15:14 +05302593 break;
Robert Richter41389602009-04-29 12:47:00 +02002594 default:
2595 return;
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05302596 }
Ingo Molnar1123e3a2009-05-29 11:25:09 +02002597 if (err != 0) {
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002598 pr_cont("no PMU driver, software events only.\n");
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05302599 return;
Ingo Molnar1123e3a2009-05-29 11:25:09 +02002600 }
Jaswinder Singh Rajputb56a3802009-02-27 18:09:09 +05302601
Cyrill Gorcunov12558032009-12-10 19:56:34 +03002602 pmu_check_apic();
2603
Ingo Molnar1123e3a2009-05-29 11:25:09 +02002604 pr_cont("%s PMU driver.\n", x86_pmu.name);
Robert Richterfaa28ae2009-04-29 12:47:13 +02002605
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002606 if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) {
2607 WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
2608 x86_pmu.num_events, X86_PMC_MAX_GENERIC);
2609 x86_pmu.num_events = X86_PMC_MAX_GENERIC;
Ingo Molnar241771e2008-12-03 10:39:53 +01002610 }
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002611 perf_event_mask = (1 << x86_pmu.num_events) - 1;
2612 perf_max_events = x86_pmu.num_events;
Ingo Molnar241771e2008-12-03 10:39:53 +01002613
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002614 if (x86_pmu.num_events_fixed > X86_PMC_MAX_FIXED) {
2615 WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
2616 x86_pmu.num_events_fixed, X86_PMC_MAX_FIXED);
2617 x86_pmu.num_events_fixed = X86_PMC_MAX_FIXED;
Ingo Molnar703e9372008-12-17 10:51:15 +01002618 }
Ingo Molnar241771e2008-12-03 10:39:53 +01002619
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002620 perf_event_mask |=
2621 ((1LL << x86_pmu.num_events_fixed)-1) << X86_PMC_IDX_FIXED;
2622 x86_pmu.intel_ctrl = perf_event_mask;
Ingo Molnar862a1a52008-12-17 13:09:20 +01002623
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002624 perf_events_lapic_init();
2625 register_die_notifier(&perf_event_nmi_notifier);
Ingo Molnar1123e3a2009-05-29 11:25:09 +02002626
Peter Zijlstra63b14642010-01-22 16:32:17 +01002627 unconstrained = (struct event_constraint)
Peter Zijlstrafce877e2010-01-29 13:25:12 +01002628 __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_events) - 1,
2629 0, x86_pmu.num_events);
Peter Zijlstra63b14642010-01-22 16:32:17 +01002630
Ingo Molnar57c0c152009-09-21 12:20:38 +02002631 pr_info("... version: %d\n", x86_pmu.version);
2632 pr_info("... bit width: %d\n", x86_pmu.event_bits);
2633 pr_info("... generic registers: %d\n", x86_pmu.num_events);
2634 pr_info("... value mask: %016Lx\n", x86_pmu.event_mask);
2635 pr_info("... max period: %016Lx\n", x86_pmu.max_period);
2636 pr_info("... fixed-purpose events: %d\n", x86_pmu.num_events_fixed);
2637 pr_info("... event mask: %016Lx\n", perf_event_mask);
Ingo Molnar241771e2008-12-03 10:39:53 +01002638}
Ingo Molnar621a01e2008-12-11 12:46:46 +01002639
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002640static inline void x86_pmu_read(struct perf_event *event)
Ingo Molnaree060942008-12-13 09:00:03 +01002641{
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002642 x86_perf_event_update(event, &event->hw, event->hw.idx);
Ingo Molnaree060942008-12-13 09:00:03 +01002643}
2644
Robert Richter4aeb0b42009-04-29 12:47:03 +02002645static const struct pmu pmu = {
2646 .enable = x86_pmu_enable,
2647 .disable = x86_pmu_disable,
2648 .read = x86_pmu_read,
Peter Zijlstraa78ac322009-05-25 17:39:05 +02002649 .unthrottle = x86_pmu_unthrottle,
Ingo Molnar621a01e2008-12-11 12:46:46 +01002650};
2651
Stephane Eranian1da53e02010-01-18 10:58:01 +02002652/*
2653 * validate a single event group
2654 *
2655 * validation include:
Ingo Molnar184f4122010-01-27 08:39:39 +01002656 * - check events are compatible which each other
2657 * - events do not compete for the same counter
2658 * - number of events <= number of counters
Stephane Eranian1da53e02010-01-18 10:58:01 +02002659 *
2660 * validation ensures the group can be loaded onto the
2661 * PMU if it was the only group available.
2662 */
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02002663static int validate_group(struct perf_event *event)
2664{
Stephane Eranian1da53e02010-01-18 10:58:01 +02002665 struct perf_event *leader = event->group_leader;
Peter Zijlstra502568d2010-01-22 14:35:46 +01002666 struct cpu_hw_events *fake_cpuc;
2667 int ret, n;
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02002668
Peter Zijlstra502568d2010-01-22 14:35:46 +01002669 ret = -ENOMEM;
2670 fake_cpuc = kmalloc(sizeof(*fake_cpuc), GFP_KERNEL | __GFP_ZERO);
2671 if (!fake_cpuc)
2672 goto out;
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02002673
Stephane Eranian1da53e02010-01-18 10:58:01 +02002674 /*
2675 * the event is not yet connected with its
2676 * siblings therefore we must first collect
2677 * existing siblings, then add the new event
2678 * before we can simulate the scheduling
2679 */
Peter Zijlstra502568d2010-01-22 14:35:46 +01002680 ret = -ENOSPC;
2681 n = collect_events(fake_cpuc, leader, true);
Stephane Eranian1da53e02010-01-18 10:58:01 +02002682 if (n < 0)
Peter Zijlstra502568d2010-01-22 14:35:46 +01002683 goto out_free;
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02002684
Peter Zijlstra502568d2010-01-22 14:35:46 +01002685 fake_cpuc->n_events = n;
2686 n = collect_events(fake_cpuc, event, false);
Stephane Eranian1da53e02010-01-18 10:58:01 +02002687 if (n < 0)
Peter Zijlstra502568d2010-01-22 14:35:46 +01002688 goto out_free;
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02002689
Peter Zijlstra502568d2010-01-22 14:35:46 +01002690 fake_cpuc->n_events = n;
Stephane Eranian1da53e02010-01-18 10:58:01 +02002691
Peter Zijlstra502568d2010-01-22 14:35:46 +01002692 ret = x86_schedule_events(fake_cpuc, n, NULL);
2693
2694out_free:
2695 kfree(fake_cpuc);
2696out:
2697 return ret;
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02002698}
2699
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002700const struct pmu *hw_perf_event_init(struct perf_event *event)
Ingo Molnar621a01e2008-12-11 12:46:46 +01002701{
Stephane Eranian81130702010-01-21 17:39:01 +02002702 const struct pmu *tmp;
Ingo Molnar621a01e2008-12-11 12:46:46 +01002703 int err;
2704
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002705 err = __hw_perf_event_init(event);
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02002706 if (!err) {
Stephane Eranian81130702010-01-21 17:39:01 +02002707 /*
2708 * we temporarily connect event to its pmu
2709 * such that validate_group() can classify
2710 * it as an x86 event using is_x86_event()
2711 */
2712 tmp = event->pmu;
2713 event->pmu = &pmu;
2714
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02002715 if (event->group_leader != event)
2716 err = validate_group(event);
Stephane Eranian81130702010-01-21 17:39:01 +02002717
2718 event->pmu = tmp;
Peter Zijlstrafe9081c2009-10-08 11:56:07 +02002719 }
Peter Zijlstraa1792cdac2009-09-09 10:04:47 +02002720 if (err) {
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002721 if (event->destroy)
2722 event->destroy(event);
Peter Zijlstra9ea98e12009-03-30 19:07:09 +02002723 return ERR_PTR(err);
Peter Zijlstraa1792cdac2009-09-09 10:04:47 +02002724 }
Ingo Molnar621a01e2008-12-11 12:46:46 +01002725
Robert Richter4aeb0b42009-04-29 12:47:03 +02002726 return &pmu;
Ingo Molnar621a01e2008-12-11 12:46:46 +01002727}
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002728
2729/*
2730 * callchain support
2731 */
2732
2733static inline
Peter Zijlstraf9188e02009-06-18 22:20:52 +02002734void callchain_store(struct perf_callchain_entry *entry, u64 ip)
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002735{
Peter Zijlstraf9188e02009-06-18 22:20:52 +02002736 if (entry->nr < PERF_MAX_STACK_DEPTH)
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002737 entry->ip[entry->nr++] = ip;
2738}
2739
Tejun Heo245b2e72009-06-24 15:13:48 +09002740static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
2741static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_nmi_entry);
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002742
2743
2744static void
2745backtrace_warning_symbol(void *data, char *msg, unsigned long symbol)
2746{
2747 /* Ignore warnings */
2748}
2749
2750static void backtrace_warning(void *data, char *msg)
2751{
2752 /* Ignore warnings */
2753}
2754
2755static int backtrace_stack(void *data, char *name)
2756{
Ingo Molnar038e8362009-06-15 09:57:59 +02002757 return 0;
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002758}
2759
2760static void backtrace_address(void *data, unsigned long addr, int reliable)
2761{
2762 struct perf_callchain_entry *entry = data;
2763
2764 if (reliable)
2765 callchain_store(entry, addr);
2766}
2767
2768static const struct stacktrace_ops backtrace_ops = {
2769 .warning = backtrace_warning,
2770 .warning_symbol = backtrace_warning_symbol,
2771 .stack = backtrace_stack,
2772 .address = backtrace_address,
Frederic Weisbecker06d65bd2009-12-17 05:40:34 +01002773 .walk_stack = print_context_stack_bp,
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002774};
2775
Ingo Molnar038e8362009-06-15 09:57:59 +02002776#include "../dumpstack.h"
2777
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002778static void
2779perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
2780{
Peter Zijlstraf9188e02009-06-18 22:20:52 +02002781 callchain_store(entry, PERF_CONTEXT_KERNEL);
Ingo Molnar038e8362009-06-15 09:57:59 +02002782 callchain_store(entry, regs->ip);
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002783
Frederic Weisbecker48b5ba92009-12-31 05:53:02 +01002784 dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry);
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002785}
2786
Peter Zijlstra74193ef2009-06-15 13:07:24 +02002787/*
2788 * best effort, GUP based copy_from_user() that assumes IRQ or NMI context
2789 */
2790static unsigned long
2791copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002792{
Peter Zijlstra74193ef2009-06-15 13:07:24 +02002793 unsigned long offset, addr = (unsigned long)from;
2794 int type = in_nmi() ? KM_NMI : KM_IRQ0;
2795 unsigned long size, len = 0;
2796 struct page *page;
2797 void *map;
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002798 int ret;
2799
Peter Zijlstra74193ef2009-06-15 13:07:24 +02002800 do {
2801 ret = __get_user_pages_fast(addr, 1, 0, &page);
2802 if (!ret)
2803 break;
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002804
Peter Zijlstra74193ef2009-06-15 13:07:24 +02002805 offset = addr & (PAGE_SIZE - 1);
2806 size = min(PAGE_SIZE - offset, n - len);
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002807
Peter Zijlstra74193ef2009-06-15 13:07:24 +02002808 map = kmap_atomic(page, type);
2809 memcpy(to, map+offset, size);
2810 kunmap_atomic(map, type);
2811 put_page(page);
2812
2813 len += size;
2814 to += size;
2815 addr += size;
2816
2817 } while (len < n);
2818
2819 return len;
2820}
2821
2822static int copy_stack_frame(const void __user *fp, struct stack_frame *frame)
2823{
2824 unsigned long bytes;
2825
2826 bytes = copy_from_user_nmi(frame, fp, sizeof(*frame));
2827
2828 return bytes == sizeof(*frame);
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002829}
2830
2831static void
2832perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry)
2833{
2834 struct stack_frame frame;
2835 const void __user *fp;
2836
Ingo Molnar5a6cec32009-05-29 11:25:09 +02002837 if (!user_mode(regs))
2838 regs = task_pt_regs(current);
2839
Peter Zijlstra74193ef2009-06-15 13:07:24 +02002840 fp = (void __user *)regs->bp;
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002841
Peter Zijlstraf9188e02009-06-18 22:20:52 +02002842 callchain_store(entry, PERF_CONTEXT_USER);
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002843 callchain_store(entry, regs->ip);
2844
Peter Zijlstraf9188e02009-06-18 22:20:52 +02002845 while (entry->nr < PERF_MAX_STACK_DEPTH) {
Ingo Molnar038e8362009-06-15 09:57:59 +02002846 frame.next_frame = NULL;
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002847 frame.return_address = 0;
2848
2849 if (!copy_stack_frame(fp, &frame))
2850 break;
2851
Ingo Molnar5a6cec32009-05-29 11:25:09 +02002852 if ((unsigned long)fp < regs->sp)
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002853 break;
2854
2855 callchain_store(entry, frame.return_address);
Ingo Molnar038e8362009-06-15 09:57:59 +02002856 fp = frame.next_frame;
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002857 }
2858}
2859
2860static void
2861perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry)
2862{
2863 int is_user;
2864
2865 if (!regs)
2866 return;
2867
2868 is_user = user_mode(regs);
2869
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002870 if (is_user && current->state != TASK_RUNNING)
2871 return;
2872
2873 if (!is_user)
2874 perf_callchain_kernel(regs, entry);
2875
2876 if (current->mm)
2877 perf_callchain_user(regs, entry);
2878}
2879
2880struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
2881{
2882 struct perf_callchain_entry *entry;
2883
2884 if (in_nmi())
Tejun Heo245b2e72009-06-24 15:13:48 +09002885 entry = &__get_cpu_var(pmc_nmi_entry);
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002886 else
Tejun Heo245b2e72009-06-24 15:13:48 +09002887 entry = &__get_cpu_var(pmc_irq_entry);
Peter Zijlstrad7d59fb2009-03-30 19:07:15 +02002888
2889 entry->nr = 0;
2890
2891 perf_do_callchain(regs, entry);
2892
2893 return entry;
2894}
Markus Metzger30dd5682009-07-21 15:56:48 +02002895
Ingo Molnarcdd6c482009-09-21 12:02:48 +02002896void hw_perf_event_setup_online(int cpu)
Markus Metzger30dd5682009-07-21 15:56:48 +02002897{
2898 init_debug_store_on_cpu(cpu);
2899}