blob: 5cd137ab267238fc0e6a002f3b7426c8f74daff9 [file] [log] [blame]
Markus Metzgereee3af42008-01-30 13:31:09 +01001/*
2 * Debug Store support
3 *
4 * This provides a low-level interface to the hardware's Debug Store
Markus Metzger93fa7632008-04-08 11:01:58 +02005 * feature that is used for branch trace store (BTS) and
Markus Metzgereee3af42008-01-30 13:31:09 +01006 * precise-event based sampling (PEBS).
7 *
Markus Metzger93fa7632008-04-08 11:01:58 +02008 * It manages:
Markus Metzgerc2724772008-12-11 13:49:59 +01009 * - DS and BTS hardware configuration
Markus Metzger6abb11a2008-11-25 09:05:27 +010010 * - buffer overflow handling (to be done)
Markus Metzger93fa7632008-04-08 11:01:58 +020011 * - buffer access
12 *
Markus Metzgerc2724772008-12-11 13:49:59 +010013 * It does not do:
14 * - security checking (is the caller allowed to trace the task)
15 * - buffer allocation (memory accounting)
Markus Metzgereee3af42008-01-30 13:31:09 +010016 *
17 *
Markus Metzgerba2607f2009-01-19 10:38:35 +010018 * Copyright (C) 2007-2009 Intel Corporation.
19 * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
Markus Metzgereee3af42008-01-30 13:31:09 +010020 */
21
Ingo Molnare9a22d12009-03-13 11:54:40 +010022#include <linux/kernel.h>
23#include <linux/string.h>
24#include <linux/errno.h>
25#include <linux/sched.h>
26#include <linux/slab.h>
27#include <linux/mm.h>
Markus Metzger93fa7632008-04-08 11:01:58 +020028
Markus Metzgereee3af42008-01-30 13:31:09 +010029#include <asm/ds.h>
30
Markus Metzger8a327f62009-03-13 10:45:07 +010031#include "ds_selftest.h"
Markus Metzger93fa7632008-04-08 11:01:58 +020032
33/*
Ingo Molnare9a22d12009-03-13 11:54:40 +010034 * The configuration for a particular DS hardware implementation:
Markus Metzger93fa7632008-04-08 11:01:58 +020035 */
36struct ds_configuration {
Ingo Molnare9a22d12009-03-13 11:54:40 +010037 /* The name of the configuration: */
38 const char *name;
39
40 /* The size of pointer-typed fields in DS, BTS, and PEBS: */
41 unsigned char sizeof_ptr_field;
42
43 /* The size of a BTS/PEBS record in bytes: */
44 unsigned char sizeof_rec[2];
45
46 /* Control bit-masks indexed by enum ds_feature: */
47 unsigned long ctl[dsf_ctl_max];
Markus Metzger93fa7632008-04-08 11:01:58 +020048};
Markus Metzgerc2724772008-12-11 13:49:59 +010049static DEFINE_PER_CPU(struct ds_configuration, ds_cfg_array);
50
51#define ds_cfg per_cpu(ds_cfg_array, smp_processor_id())
52
Ingo Molnare9a22d12009-03-13 11:54:40 +010053/* Maximal size of a DS configuration: */
54#define MAX_SIZEOF_DS (12 * 8)
Markus Metzgerc2724772008-12-11 13:49:59 +010055
Ingo Molnare9a22d12009-03-13 11:54:40 +010056/* Maximal size of a BTS record: */
57#define MAX_SIZEOF_BTS (3 * 8)
Markus Metzgerc2724772008-12-11 13:49:59 +010058
Ingo Molnare9a22d12009-03-13 11:54:40 +010059/* BTS and PEBS buffer alignment: */
60#define DS_ALIGNMENT (1 << 3)
61
62/* Mask of control bits in the DS MSR register: */
63#define BTS_CONTROL \
64 ( ds_cfg.ctl[dsf_bts] | \
65 ds_cfg.ctl[dsf_bts_kernel] | \
66 ds_cfg.ctl[dsf_bts_user] | \
67 ds_cfg.ctl[dsf_bts_overflow] )
Markus Metzgereee3af42008-01-30 13:31:09 +010068
Markus Metzgerca0002a2008-11-25 09:01:25 +010069/*
70 * A BTS or PEBS tracer.
71 *
72 * This holds the configuration of the tracer and serves as a handle
73 * to identify tracers.
74 */
75struct ds_tracer {
Markus Metzgerb8e47192009-03-13 10:46:42 +010076 /* The DS context (partially) owned by this tracer. */
Ingo Molnare9a22d12009-03-13 11:54:40 +010077 struct ds_context *context;
Markus Metzgerb8e47192009-03-13 10:46:42 +010078 /* The buffer provided on ds_request() and its size in bytes. */
Ingo Molnare9a22d12009-03-13 11:54:40 +010079 void *buffer;
80 size_t size;
Markus Metzgerca0002a2008-11-25 09:01:25 +010081};
82
83struct bts_tracer {
Ingo Molnare9a22d12009-03-13 11:54:40 +010084 /* The common DS part: */
85 struct ds_tracer ds;
86
87 /* The trace including the DS configuration: */
88 struct bts_trace trace;
89
90 /* Buffer overflow notification function: */
91 bts_ovfl_callback_t ovfl;
Markus Metzgercac94f92009-04-03 16:43:33 +020092
93 /* Active flags affecting trace collection. */
94 unsigned int flags;
Markus Metzgerca0002a2008-11-25 09:01:25 +010095};
96
97struct pebs_tracer {
Ingo Molnare9a22d12009-03-13 11:54:40 +010098 /* The common DS part: */
99 struct ds_tracer ds;
100
101 /* The trace including the DS configuration: */
102 struct pebs_trace trace;
103
104 /* Buffer overflow notification function: */
105 pebs_ovfl_callback_t ovfl;
Markus Metzgerca0002a2008-11-25 09:01:25 +0100106};
Markus Metzgereee3af42008-01-30 13:31:09 +0100107
108/*
109 * Debug Store (DS) save area configuration (see Intel64 and IA32
110 * Architectures Software Developer's Manual, section 18.5)
111 *
112 * The DS configuration consists of the following fields; different
113 * architetures vary in the size of those fields.
Ingo Molnare9a22d12009-03-13 11:54:40 +0100114 *
Markus Metzgereee3af42008-01-30 13:31:09 +0100115 * - double-word aligned base linear address of the BTS buffer
116 * - write pointer into the BTS buffer
117 * - end linear address of the BTS buffer (one byte beyond the end of
118 * the buffer)
119 * - interrupt pointer into BTS buffer
120 * (interrupt occurs when write pointer passes interrupt pointer)
121 * - double-word aligned base linear address of the PEBS buffer
122 * - write pointer into the PEBS buffer
123 * - end linear address of the PEBS buffer (one byte beyond the end of
124 * the buffer)
125 * - interrupt pointer into PEBS buffer
126 * (interrupt occurs when write pointer passes interrupt pointer)
127 * - value to which counter is reset following counter overflow
128 *
Markus Metzger93fa7632008-04-08 11:01:58 +0200129 * Later architectures use 64bit pointers throughout, whereas earlier
130 * architectures use 32bit pointers in 32bit mode.
Markus Metzgereee3af42008-01-30 13:31:09 +0100131 *
132 *
Markus Metzger93fa7632008-04-08 11:01:58 +0200133 * We compute the base address for the first 8 fields based on:
134 * - the field size stored in the DS configuration
135 * - the relative field position
136 * - an offset giving the start of the respective region
Markus Metzgereee3af42008-01-30 13:31:09 +0100137 *
Markus Metzger93fa7632008-04-08 11:01:58 +0200138 * This offset is further used to index various arrays holding
139 * information for BTS and PEBS at the respective index.
Markus Metzgereee3af42008-01-30 13:31:09 +0100140 *
Markus Metzger93fa7632008-04-08 11:01:58 +0200141 * On later 32bit processors, we only access the lower 32bit of the
142 * 64bit pointer fields. The upper halves will be zeroed out.
Markus Metzgereee3af42008-01-30 13:31:09 +0100143 */
144
Markus Metzger93fa7632008-04-08 11:01:58 +0200145enum ds_field {
146 ds_buffer_base = 0,
147 ds_index,
148 ds_absolute_maximum,
149 ds_interrupt_threshold,
Markus Metzgereee3af42008-01-30 13:31:09 +0100150};
151
Markus Metzger93fa7632008-04-08 11:01:58 +0200152enum ds_qualifier {
Ingo Molnare9a22d12009-03-13 11:54:40 +0100153 ds_bts = 0,
Markus Metzger93fa7632008-04-08 11:01:58 +0200154 ds_pebs
Markus Metzgereee3af42008-01-30 13:31:09 +0100155};
156
Ingo Molnare9a22d12009-03-13 11:54:40 +0100157static inline unsigned long
158ds_get(const unsigned char *base, enum ds_qualifier qual, enum ds_field field)
Markus Metzger93fa7632008-04-08 11:01:58 +0200159{
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100160 base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
Markus Metzger93fa7632008-04-08 11:01:58 +0200161 return *(unsigned long *)base;
162}
163
Ingo Molnare9a22d12009-03-13 11:54:40 +0100164static inline void
165ds_set(unsigned char *base, enum ds_qualifier qual, enum ds_field field,
166 unsigned long value)
Markus Metzger93fa7632008-04-08 11:01:58 +0200167{
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100168 base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
Markus Metzger93fa7632008-04-08 11:01:58 +0200169 (*(unsigned long *)base) = value;
170}
171
Markus Metzgereee3af42008-01-30 13:31:09 +0100172
173/*
Markus Metzger6abb11a2008-11-25 09:05:27 +0100174 * Locking is done only for allocating BTS or PEBS resources.
Markus Metzgereee3af42008-01-30 13:31:09 +0100175 */
Markus Metzgerc2724772008-12-11 13:49:59 +0100176static DEFINE_SPINLOCK(ds_lock);
Markus Metzgereee3af42008-01-30 13:31:09 +0100177
Markus Metzger93fa7632008-04-08 11:01:58 +0200178/*
179 * We either support (system-wide) per-cpu or per-thread allocation.
180 * We distinguish the two based on the task_struct pointer, where a
181 * NULL pointer indicates per-cpu allocation for the current cpu.
182 *
183 * Allocations are use-counted. As soon as resources are allocated,
184 * further allocations must be of the same type (per-cpu or
185 * per-thread). We model this by counting allocations (i.e. the number
186 * of tracers of a certain type) for one type negatively:
187 * =0 no tracers
188 * >0 number of per-thread tracers
189 * <0 number of per-cpu tracers
190 *
Markus Metzger93fa7632008-04-08 11:01:58 +0200191 * Tracers essentially gives the number of ds contexts for a certain
192 * type of allocation.
193 */
Markus Metzgerc2724772008-12-11 13:49:59 +0100194static atomic_t tracers = ATOMIC_INIT(0);
Markus Metzger93fa7632008-04-08 11:01:58 +0200195
196static inline void get_tracer(struct task_struct *task)
Markus Metzgera95d67f2008-01-30 13:31:20 +0100197{
Markus Metzgerc2724772008-12-11 13:49:59 +0100198 if (task)
199 atomic_inc(&tracers);
200 else
201 atomic_dec(&tracers);
Markus Metzgereee3af42008-01-30 13:31:09 +0100202}
203
Markus Metzger93fa7632008-04-08 11:01:58 +0200204static inline void put_tracer(struct task_struct *task)
Markus Metzgereee3af42008-01-30 13:31:09 +0100205{
Markus Metzgerc2724772008-12-11 13:49:59 +0100206 if (task)
207 atomic_dec(&tracers);
208 else
209 atomic_inc(&tracers);
Markus Metzgereee3af42008-01-30 13:31:09 +0100210}
211
Markus Metzger93fa7632008-04-08 11:01:58 +0200212static inline int check_tracer(struct task_struct *task)
Markus Metzgera95d67f2008-01-30 13:31:20 +0100213{
Markus Metzgerc2724772008-12-11 13:49:59 +0100214 return task ?
215 (atomic_read(&tracers) >= 0) :
216 (atomic_read(&tracers) <= 0);
Markus Metzger93fa7632008-04-08 11:01:58 +0200217}
218
219
220/*
221 * The DS context is either attached to a thread or to a cpu:
222 * - in the former case, the thread_struct contains a pointer to the
223 * attached context.
224 * - in the latter case, we use a static array of per-cpu context
225 * pointers.
226 *
227 * Contexts are use-counted. They are allocated on first access and
228 * deallocated when the last user puts the context.
Markus Metzger93fa7632008-04-08 11:01:58 +0200229 */
Markus Metzgerc2724772008-12-11 13:49:59 +0100230struct ds_context {
Ingo Molnare9a22d12009-03-13 11:54:40 +0100231 /* The DS configuration; goes into MSR_IA32_DS_AREA: */
232 unsigned char ds[MAX_SIZEOF_DS];
233
234 /* The owner of the BTS and PEBS configuration, respectively: */
235 struct bts_tracer *bts_master;
236 struct pebs_tracer *pebs_master;
237
238 /* Use count: */
Markus Metzgerc2724772008-12-11 13:49:59 +0100239 unsigned long count;
Ingo Molnare9a22d12009-03-13 11:54:40 +0100240
241 /* Pointer to the context pointer field: */
242 struct ds_context **this;
243
244 /* The traced task; NULL for current cpu: */
245 struct task_struct *task;
Markus Metzgerc2724772008-12-11 13:49:59 +0100246};
Markus Metzger93fa7632008-04-08 11:01:58 +0200247
Markus Metzgerc2724772008-12-11 13:49:59 +0100248static DEFINE_PER_CPU(struct ds_context *, system_context_array);
249
250#define system_context per_cpu(system_context_array, smp_processor_id())
Markus Metzger93fa7632008-04-08 11:01:58 +0200251
Markus Metzgercc1dc6d2008-12-16 15:51:03 +0100252
253static inline struct ds_context *ds_get_context(struct task_struct *task)
Markus Metzger93fa7632008-04-08 11:01:58 +0200254{
Markus Metzger93fa7632008-04-08 11:01:58 +0200255 struct ds_context **p_context =
Markus Metzgerc2724772008-12-11 13:49:59 +0100256 (task ? &task->thread.ds_ctx : &system_context);
Markus Metzgercc1dc6d2008-12-16 15:51:03 +0100257 struct ds_context *context = NULL;
258 struct ds_context *new_context = NULL;
Markus Metzgerde90add2008-11-25 08:52:56 +0100259 unsigned long irq;
Markus Metzger93fa7632008-04-08 11:01:58 +0200260
Markus Metzgerc78a3952009-03-18 19:27:00 +0100261 /*
262 * Chances are small that we already have a context.
263 *
264 * Contexts for per-cpu tracing are allocated using
265 * smp_call_function(). We must not sleep.
266 */
267 new_context = kzalloc(sizeof(*new_context), GFP_ATOMIC);
Markus Metzgercc1dc6d2008-12-16 15:51:03 +0100268 if (!new_context)
269 return NULL;
270
271 spin_lock_irqsave(&ds_lock, irq);
272
273 context = *p_context;
Markus Metzger93fa7632008-04-08 11:01:58 +0200274 if (!context) {
Markus Metzgercc1dc6d2008-12-16 15:51:03 +0100275 context = new_context;
Markus Metzger93fa7632008-04-08 11:01:58 +0200276
Markus Metzgercc1dc6d2008-12-16 15:51:03 +0100277 context->this = p_context;
278 context->task = task;
279 context->count = 0;
Markus Metzgerde90add2008-11-25 08:52:56 +0100280
Markus Metzgercc1dc6d2008-12-16 15:51:03 +0100281 if (task)
282 set_tsk_thread_flag(task, TIF_DS_AREA_MSR);
Markus Metzgerde90add2008-11-25 08:52:56 +0100283
Markus Metzgercc1dc6d2008-12-16 15:51:03 +0100284 if (!task || (task == current))
285 wrmsrl(MSR_IA32_DS_AREA, (unsigned long)context->ds);
Markus Metzgerde90add2008-11-25 08:52:56 +0100286
Markus Metzgercc1dc6d2008-12-16 15:51:03 +0100287 *p_context = context;
Markus Metzgerc2724772008-12-11 13:49:59 +0100288 }
Markus Metzger93fa7632008-04-08 11:01:58 +0200289
Markus Metzgercc1dc6d2008-12-16 15:51:03 +0100290 context->count++;
291
292 spin_unlock_irqrestore(&ds_lock, irq);
293
294 if (context != new_context)
295 kfree(new_context);
296
Markus Metzger93fa7632008-04-08 11:01:58 +0200297 return context;
298}
299
Markus Metzger93fa7632008-04-08 11:01:58 +0200300static inline void ds_put_context(struct ds_context *context)
301{
Markus Metzger8d99b3a2009-04-03 16:43:36 +0200302 struct task_struct *task;
Markus Metzgerde90add2008-11-25 08:52:56 +0100303 unsigned long irq;
304
Markus Metzger93fa7632008-04-08 11:01:58 +0200305 if (!context)
306 return;
307
Markus Metzgerde90add2008-11-25 08:52:56 +0100308 spin_lock_irqsave(&ds_lock, irq);
Markus Metzger93fa7632008-04-08 11:01:58 +0200309
Markus Metzgerc2724772008-12-11 13:49:59 +0100310 if (--context->count) {
311 spin_unlock_irqrestore(&ds_lock, irq);
312 return;
313 }
Markus Metzger93fa7632008-04-08 11:01:58 +0200314
Cyrill Gorcunov573da422008-04-28 23:15:04 +0400315 *(context->this) = NULL;
Markus Metzger93fa7632008-04-08 11:01:58 +0200316
Markus Metzger8d99b3a2009-04-03 16:43:36 +0200317 task = context->task;
Markus Metzger93fa7632008-04-08 11:01:58 +0200318
Markus Metzger8d99b3a2009-04-03 16:43:36 +0200319 if (task)
320 clear_tsk_thread_flag(task, TIF_DS_AREA_MSR);
321
322 if (!task || (task == current))
Markus Metzger93fa7632008-04-08 11:01:58 +0200323 wrmsrl(MSR_IA32_DS_AREA, 0);
324
Markus Metzgerde90add2008-11-25 08:52:56 +0100325 spin_unlock_irqrestore(&ds_lock, irq);
Markus Metzgerc2724772008-12-11 13:49:59 +0100326
Markus Metzger8d99b3a2009-04-03 16:43:36 +0200327 /* The context might still be in use for context switching. */
328 if (task && (task != current))
329 wait_task_context_switch(task);
330
Markus Metzgerc2724772008-12-11 13:49:59 +0100331 kfree(context);
Markus Metzger93fa7632008-04-08 11:01:58 +0200332}
333
334
335/*
Markus Metzgerc2724772008-12-11 13:49:59 +0100336 * Call the tracer's callback on a buffer overflow.
Markus Metzger93fa7632008-04-08 11:01:58 +0200337 *
Markus Metzger93fa7632008-04-08 11:01:58 +0200338 * context: the ds context
339 * qual: the buffer type
340 */
Markus Metzgerca0002a2008-11-25 09:01:25 +0100341static void ds_overflow(struct ds_context *context, enum ds_qualifier qual)
Markus Metzger93fa7632008-04-08 11:01:58 +0200342{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100343 switch (qual) {
Markus Metzgerc2724772008-12-11 13:49:59 +0100344 case ds_bts:
345 if (context->bts_master &&
346 context->bts_master->ovfl)
347 context->bts_master->ovfl(context->bts_master);
Markus Metzgerca0002a2008-11-25 09:01:25 +0100348 break;
Markus Metzgerc2724772008-12-11 13:49:59 +0100349 case ds_pebs:
350 if (context->pebs_master &&
351 context->pebs_master->ovfl)
352 context->pebs_master->ovfl(context->pebs_master);
Markus Metzgerca0002a2008-11-25 09:01:25 +0100353 break;
354 }
Markus Metzger93fa7632008-04-08 11:01:58 +0200355}
356
357
Markus Metzgerc2724772008-12-11 13:49:59 +0100358/*
359 * Write raw data into the BTS or PEBS buffer.
360 *
361 * The remainder of any partially written record is zeroed out.
362 *
363 * context: the DS context
Ingo Molnare9a22d12009-03-13 11:54:40 +0100364 * qual: the buffer type
365 * record: the data to write
366 * size: the size of the data
Markus Metzgerc2724772008-12-11 13:49:59 +0100367 */
Markus Metzgerca0002a2008-11-25 09:01:25 +0100368static int ds_write(struct ds_context *context, enum ds_qualifier qual,
369 const void *record, size_t size)
Markus Metzger93fa7632008-04-08 11:01:58 +0200370{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100371 int bytes_written = 0;
Markus Metzger93fa7632008-04-08 11:01:58 +0200372
373 if (!record)
374 return -EINVAL;
375
Markus Metzger93fa7632008-04-08 11:01:58 +0200376 while (size) {
377 unsigned long base, index, end, write_end, int_th;
378 unsigned long write_size, adj_write_size;
Markus Metzgereee3af42008-01-30 13:31:09 +0100379
Markus Metzger93fa7632008-04-08 11:01:58 +0200380 /*
Markus Metzgerb8e47192009-03-13 10:46:42 +0100381 * Write as much as possible without producing an
Markus Metzger93fa7632008-04-08 11:01:58 +0200382 * overflow interrupt.
383 *
Markus Metzgerb8e47192009-03-13 10:46:42 +0100384 * Interrupt_threshold must either be
Markus Metzger93fa7632008-04-08 11:01:58 +0200385 * - bigger than absolute_maximum or
386 * - point to a record between buffer_base and absolute_maximum
387 *
Markus Metzgerb8e47192009-03-13 10:46:42 +0100388 * Index points to a valid record.
Markus Metzger93fa7632008-04-08 11:01:58 +0200389 */
390 base = ds_get(context->ds, qual, ds_buffer_base);
391 index = ds_get(context->ds, qual, ds_index);
392 end = ds_get(context->ds, qual, ds_absolute_maximum);
393 int_th = ds_get(context->ds, qual, ds_interrupt_threshold);
394
395 write_end = min(end, int_th);
396
Markus Metzgerb8e47192009-03-13 10:46:42 +0100397 /*
398 * If we are already beyond the interrupt threshold,
399 * we fill the entire buffer.
400 */
Markus Metzger93fa7632008-04-08 11:01:58 +0200401 if (write_end <= index)
402 write_end = end;
403
404 if (write_end <= index)
Markus Metzgerca0002a2008-11-25 09:01:25 +0100405 break;
Markus Metzger93fa7632008-04-08 11:01:58 +0200406
407 write_size = min((unsigned long) size, write_end - index);
408 memcpy((void *)index, record, write_size);
409
410 record = (const char *)record + write_size;
Markus Metzgerca0002a2008-11-25 09:01:25 +0100411 size -= write_size;
412 bytes_written += write_size;
Markus Metzger93fa7632008-04-08 11:01:58 +0200413
414 adj_write_size = write_size / ds_cfg.sizeof_rec[qual];
415 adj_write_size *= ds_cfg.sizeof_rec[qual];
416
Markus Metzgerb8e47192009-03-13 10:46:42 +0100417 /* Zero out trailing bytes. */
Markus Metzger93fa7632008-04-08 11:01:58 +0200418 memset((char *)index + write_size, 0,
419 adj_write_size - write_size);
420 index += adj_write_size;
421
422 if (index >= end)
423 index = base;
424 ds_set(context->ds, qual, ds_index, index);
425
426 if (index >= int_th)
Markus Metzgerca0002a2008-11-25 09:01:25 +0100427 ds_overflow(context, qual);
Markus Metzger93fa7632008-04-08 11:01:58 +0200428 }
429
Markus Metzgerca0002a2008-11-25 09:01:25 +0100430 return bytes_written;
Markus Metzgereee3af42008-01-30 13:31:09 +0100431}
432
Markus Metzgerc2724772008-12-11 13:49:59 +0100433
434/*
435 * Branch Trace Store (BTS) uses the following format. Different
436 * architectures vary in the size of those fields.
437 * - source linear address
438 * - destination linear address
439 * - flags
440 *
441 * Later architectures use 64bit pointers throughout, whereas earlier
442 * architectures use 32bit pointers in 32bit mode.
443 *
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100444 * We compute the base address for the fields based on:
Markus Metzgerc2724772008-12-11 13:49:59 +0100445 * - the field size stored in the DS configuration
446 * - the relative field position
447 *
448 * In order to store additional information in the BTS buffer, we use
449 * a special source address to indicate that the record requires
450 * special interpretation.
451 *
452 * Netburst indicated via a bit in the flags field whether the branch
453 * was predicted; this is ignored.
454 *
455 * We use two levels of abstraction:
456 * - the raw data level defined here
457 * - an arch-independent level defined in ds.h
458 */
459
460enum bts_field {
461 bts_from,
462 bts_to,
463 bts_flags,
464
Ingo Molnare9a22d12009-03-13 11:54:40 +0100465 bts_qual = bts_from,
466 bts_jiffies = bts_to,
467 bts_pid = bts_flags,
Markus Metzgerc2724772008-12-11 13:49:59 +0100468
Ingo Molnare9a22d12009-03-13 11:54:40 +0100469 bts_qual_mask = (bts_qual_max - 1),
470 bts_escape = ((unsigned long)-1 & ~bts_qual_mask)
Markus Metzgerc2724772008-12-11 13:49:59 +0100471};
472
473static inline unsigned long bts_get(const char *base, enum bts_field field)
474{
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100475 base += (ds_cfg.sizeof_ptr_field * field);
Markus Metzgerc2724772008-12-11 13:49:59 +0100476 return *(unsigned long *)base;
477}
478
479static inline void bts_set(char *base, enum bts_field field, unsigned long val)
480{
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100481 base += (ds_cfg.sizeof_ptr_field * field);;
Markus Metzgerc2724772008-12-11 13:49:59 +0100482 (*(unsigned long *)base) = val;
483}
484
485
486/*
487 * The raw BTS data is architecture dependent.
488 *
489 * For higher-level users, we give an arch-independent view.
490 * - ds.h defines struct bts_struct
491 * - bts_read translates one raw bts record into a bts_struct
492 * - bts_write translates one bts_struct into the raw format and
493 * writes it into the top of the parameter tracer's buffer.
494 *
495 * return: bytes read/written on success; -Eerrno, otherwise
496 */
Ingo Molnare9a22d12009-03-13 11:54:40 +0100497static int
498bts_read(struct bts_tracer *tracer, const void *at, struct bts_struct *out)
Markus Metzgereee3af42008-01-30 13:31:09 +0100499{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100500 if (!tracer)
501 return -EINVAL;
502
Markus Metzgerc2724772008-12-11 13:49:59 +0100503 if (at < tracer->trace.ds.begin)
504 return -EINVAL;
505
506 if (tracer->trace.ds.end < (at + tracer->trace.ds.size))
507 return -EINVAL;
508
509 memset(out, 0, sizeof(*out));
510 if ((bts_get(at, bts_qual) & ~bts_qual_mask) == bts_escape) {
511 out->qualifier = (bts_get(at, bts_qual) & bts_qual_mask);
512 out->variant.timestamp.jiffies = bts_get(at, bts_jiffies);
513 out->variant.timestamp.pid = bts_get(at, bts_pid);
514 } else {
515 out->qualifier = bts_branch;
516 out->variant.lbr.from = bts_get(at, bts_from);
517 out->variant.lbr.to = bts_get(at, bts_to);
Markus Metzgerd072c252008-12-16 15:53:11 +0100518
519 if (!out->variant.lbr.from && !out->variant.lbr.to)
520 out->qualifier = bts_invalid;
Markus Metzgerc2724772008-12-11 13:49:59 +0100521 }
522
523 return ds_cfg.sizeof_rec[ds_bts];
Markus Metzgereee3af42008-01-30 13:31:09 +0100524}
525
Markus Metzgerc2724772008-12-11 13:49:59 +0100526static int bts_write(struct bts_tracer *tracer, const struct bts_struct *in)
Markus Metzger93fa7632008-04-08 11:01:58 +0200527{
Markus Metzgerc2724772008-12-11 13:49:59 +0100528 unsigned char raw[MAX_SIZEOF_BTS];
529
Markus Metzgerca0002a2008-11-25 09:01:25 +0100530 if (!tracer)
531 return -EINVAL;
532
Markus Metzgerc2724772008-12-11 13:49:59 +0100533 if (MAX_SIZEOF_BTS < ds_cfg.sizeof_rec[ds_bts])
534 return -EOVERFLOW;
535
536 switch (in->qualifier) {
537 case bts_invalid:
538 bts_set(raw, bts_from, 0);
539 bts_set(raw, bts_to, 0);
540 bts_set(raw, bts_flags, 0);
541 break;
542 case bts_branch:
543 bts_set(raw, bts_from, in->variant.lbr.from);
544 bts_set(raw, bts_to, in->variant.lbr.to);
545 bts_set(raw, bts_flags, 0);
546 break;
547 case bts_task_arrives:
548 case bts_task_departs:
549 bts_set(raw, bts_qual, (bts_escape | in->qualifier));
550 bts_set(raw, bts_jiffies, in->variant.timestamp.jiffies);
551 bts_set(raw, bts_pid, in->variant.timestamp.pid);
552 break;
553 default:
554 return -EINVAL;
555 }
556
557 return ds_write(tracer->ds.context, ds_bts, raw,
558 ds_cfg.sizeof_rec[ds_bts]);
Markus Metzger93fa7632008-04-08 11:01:58 +0200559}
Markus Metzgereee3af42008-01-30 13:31:09 +0100560
Markus Metzgerc2724772008-12-11 13:49:59 +0100561
562static void ds_write_config(struct ds_context *context,
563 struct ds_trace *cfg, enum ds_qualifier qual)
Markus Metzger93fa7632008-04-08 11:01:58 +0200564{
Markus Metzgerc2724772008-12-11 13:49:59 +0100565 unsigned char *ds = context->ds;
Markus Metzger93fa7632008-04-08 11:01:58 +0200566
Markus Metzgerc2724772008-12-11 13:49:59 +0100567 ds_set(ds, qual, ds_buffer_base, (unsigned long)cfg->begin);
568 ds_set(ds, qual, ds_index, (unsigned long)cfg->top);
569 ds_set(ds, qual, ds_absolute_maximum, (unsigned long)cfg->end);
570 ds_set(ds, qual, ds_interrupt_threshold, (unsigned long)cfg->ith);
571}
Markus Metzger93fa7632008-04-08 11:01:58 +0200572
Markus Metzgerc2724772008-12-11 13:49:59 +0100573static void ds_read_config(struct ds_context *context,
574 struct ds_trace *cfg, enum ds_qualifier qual)
575{
576 unsigned char *ds = context->ds;
Markus Metzger93fa7632008-04-08 11:01:58 +0200577
Markus Metzgerc2724772008-12-11 13:49:59 +0100578 cfg->begin = (void *)ds_get(ds, qual, ds_buffer_base);
579 cfg->top = (void *)ds_get(ds, qual, ds_index);
580 cfg->end = (void *)ds_get(ds, qual, ds_absolute_maximum);
581 cfg->ith = (void *)ds_get(ds, qual, ds_interrupt_threshold);
582}
583
584static void ds_init_ds_trace(struct ds_trace *trace, enum ds_qualifier qual,
585 void *base, size_t size, size_t ith,
586 unsigned int flags) {
587 unsigned long buffer, adj;
588
Markus Metzgerb8e47192009-03-13 10:46:42 +0100589 /*
590 * Adjust the buffer address and size to meet alignment
Markus Metzgerc2724772008-12-11 13:49:59 +0100591 * constraints:
592 * - buffer is double-word aligned
593 * - size is multiple of record size
594 *
595 * We checked the size at the very beginning; we have enough
596 * space to do the adjustment.
597 */
598 buffer = (unsigned long)base;
599
600 adj = ALIGN(buffer, DS_ALIGNMENT) - buffer;
601 buffer += adj;
602 size -= adj;
603
604 trace->n = size / ds_cfg.sizeof_rec[qual];
605 trace->size = ds_cfg.sizeof_rec[qual];
606
607 size = (trace->n * trace->size);
608
609 trace->begin = (void *)buffer;
610 trace->top = trace->begin;
611 trace->end = (void *)(buffer + size);
Markus Metzgerb8e47192009-03-13 10:46:42 +0100612 /*
613 * The value for 'no threshold' is -1, which will set the
Markus Metzgerc2724772008-12-11 13:49:59 +0100614 * threshold outside of the buffer, just like we want it.
615 */
616 trace->ith = (void *)(buffer + size - ith);
617
618 trace->flags = flags;
619}
620
621
622static int ds_request(struct ds_tracer *tracer, struct ds_trace *trace,
623 enum ds_qualifier qual, struct task_struct *task,
624 void *base, size_t size, size_t th, unsigned int flags)
625{
626 struct ds_context *context;
627 int error;
628
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100629 error = -EOPNOTSUPP;
630 if (!ds_cfg.sizeof_rec[qual])
631 goto out;
632
Markus Metzgerc2724772008-12-11 13:49:59 +0100633 error = -EINVAL;
634 if (!base)
635 goto out;
636
Markus Metzgerb8e47192009-03-13 10:46:42 +0100637 /* We require some space to do alignment adjustments below. */
Markus Metzgerc2724772008-12-11 13:49:59 +0100638 error = -EINVAL;
639 if (size < (DS_ALIGNMENT + ds_cfg.sizeof_rec[qual]))
640 goto out;
641
642 if (th != (size_t)-1) {
643 th *= ds_cfg.sizeof_rec[qual];
644
645 error = -EINVAL;
646 if (size <= th)
647 goto out;
648 }
649
650 tracer->buffer = base;
651 tracer->size = size;
652
653 error = -ENOMEM;
654 context = ds_get_context(task);
655 if (!context)
656 goto out;
657 tracer->context = context;
658
659 ds_init_ds_trace(trace, qual, base, size, th, flags);
660
661 error = 0;
662 out:
663 return error;
664}
665
666struct bts_tracer *ds_request_bts(struct task_struct *task,
667 void *base, size_t size,
668 bts_ovfl_callback_t ovfl, size_t th,
669 unsigned int flags)
670{
671 struct bts_tracer *tracer;
672 unsigned long irq;
673 int error;
674
Markus Metzgerb8e47192009-03-13 10:46:42 +0100675 /* Buffer overflow notification is not yet implemented. */
Markus Metzgerc2724772008-12-11 13:49:59 +0100676 error = -EOPNOTSUPP;
677 if (ovfl)
678 goto out;
679
Markus Metzgerc78a3952009-03-18 19:27:00 +0100680 /*
681 * Per-cpu tracing is typically requested using smp_call_function().
682 * We must not sleep.
683 */
Markus Metzgerc2724772008-12-11 13:49:59 +0100684 error = -ENOMEM;
Markus Metzgerc78a3952009-03-18 19:27:00 +0100685 tracer = kzalloc(sizeof(*tracer), GFP_ATOMIC);
Markus Metzgerc2724772008-12-11 13:49:59 +0100686 if (!tracer)
687 goto out;
688 tracer->ovfl = ovfl;
689
690 error = ds_request(&tracer->ds, &tracer->trace.ds,
691 ds_bts, task, base, size, th, flags);
692 if (error < 0)
693 goto out_tracer;
694
695
696 spin_lock_irqsave(&ds_lock, irq);
697
698 error = -EPERM;
699 if (!check_tracer(task))
700 goto out_unlock;
701 get_tracer(task);
702
703 error = -EPERM;
704 if (tracer->ds.context->bts_master)
705 goto out_put_tracer;
706 tracer->ds.context->bts_master = tracer;
707
708 spin_unlock_irqrestore(&ds_lock, irq);
709
710
711 tracer->trace.read = bts_read;
712 tracer->trace.write = bts_write;
713
714 ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
715 ds_resume_bts(tracer);
716
717 return tracer;
718
719 out_put_tracer:
720 put_tracer(task);
721 out_unlock:
722 spin_unlock_irqrestore(&ds_lock, irq);
723 ds_put_context(tracer->ds.context);
724 out_tracer:
725 kfree(tracer);
726 out:
727 return ERR_PTR(error);
728}
729
730struct pebs_tracer *ds_request_pebs(struct task_struct *task,
731 void *base, size_t size,
732 pebs_ovfl_callback_t ovfl, size_t th,
733 unsigned int flags)
734{
735 struct pebs_tracer *tracer;
736 unsigned long irq;
737 int error;
738
Markus Metzgerb8e47192009-03-13 10:46:42 +0100739 /* Buffer overflow notification is not yet implemented. */
Markus Metzgerc2724772008-12-11 13:49:59 +0100740 error = -EOPNOTSUPP;
741 if (ovfl)
742 goto out;
743
Markus Metzgerc78a3952009-03-18 19:27:00 +0100744 /*
745 * Per-cpu tracing is typically requested using smp_call_function().
746 * We must not sleep.
747 */
Markus Metzgerc2724772008-12-11 13:49:59 +0100748 error = -ENOMEM;
Markus Metzgerc78a3952009-03-18 19:27:00 +0100749 tracer = kzalloc(sizeof(*tracer), GFP_ATOMIC);
Markus Metzgerc2724772008-12-11 13:49:59 +0100750 if (!tracer)
751 goto out;
752 tracer->ovfl = ovfl;
753
754 error = ds_request(&tracer->ds, &tracer->trace.ds,
755 ds_pebs, task, base, size, th, flags);
756 if (error < 0)
757 goto out_tracer;
758
759 spin_lock_irqsave(&ds_lock, irq);
760
761 error = -EPERM;
762 if (!check_tracer(task))
763 goto out_unlock;
764 get_tracer(task);
765
766 error = -EPERM;
767 if (tracer->ds.context->pebs_master)
768 goto out_put_tracer;
769 tracer->ds.context->pebs_master = tracer;
770
771 spin_unlock_irqrestore(&ds_lock, irq);
772
Markus Metzger73bf1b62009-03-05 08:57:21 +0100773 ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
Markus Metzgerc2724772008-12-11 13:49:59 +0100774 ds_resume_pebs(tracer);
775
776 return tracer;
777
778 out_put_tracer:
779 put_tracer(task);
780 out_unlock:
781 spin_unlock_irqrestore(&ds_lock, irq);
782 ds_put_context(tracer->ds.context);
783 out_tracer:
784 kfree(tracer);
785 out:
786 return ERR_PTR(error);
787}
788
789void ds_release_bts(struct bts_tracer *tracer)
790{
Markus Metzger8d99b3a2009-04-03 16:43:36 +0200791 struct task_struct *task;
792
Markus Metzgerc2724772008-12-11 13:49:59 +0100793 if (!tracer)
794 return;
795
Markus Metzger8d99b3a2009-04-03 16:43:36 +0200796 task = tracer->ds.context->task;
797
Markus Metzgerc2724772008-12-11 13:49:59 +0100798 ds_suspend_bts(tracer);
799
800 WARN_ON_ONCE(tracer->ds.context->bts_master != tracer);
801 tracer->ds.context->bts_master = NULL;
802
Markus Metzger8d99b3a2009-04-03 16:43:36 +0200803 /* Make sure tracing stopped and the tracer is not in use. */
804 if (task && (task != current))
805 wait_task_context_switch(task);
806
807 put_tracer(task);
Markus Metzgerc2724772008-12-11 13:49:59 +0100808 ds_put_context(tracer->ds.context);
809
810 kfree(tracer);
811}
812
813void ds_suspend_bts(struct bts_tracer *tracer)
814{
815 struct task_struct *task;
816
817 if (!tracer)
818 return;
819
Markus Metzgercac94f92009-04-03 16:43:33 +0200820 tracer->flags = 0;
821
Markus Metzgerc2724772008-12-11 13:49:59 +0100822 task = tracer->ds.context->task;
823
824 if (!task || (task == current))
825 update_debugctlmsr(get_debugctlmsr() & ~BTS_CONTROL);
826
827 if (task) {
828 task->thread.debugctlmsr &= ~BTS_CONTROL;
829
830 if (!task->thread.debugctlmsr)
831 clear_tsk_thread_flag(task, TIF_DEBUGCTLMSR);
832 }
833}
834
835void ds_resume_bts(struct bts_tracer *tracer)
836{
837 struct task_struct *task;
838 unsigned long control;
839
840 if (!tracer)
841 return;
842
Markus Metzgercac94f92009-04-03 16:43:33 +0200843 tracer->flags = tracer->trace.ds.flags;
844
Markus Metzgerc2724772008-12-11 13:49:59 +0100845 task = tracer->ds.context->task;
846
847 control = ds_cfg.ctl[dsf_bts];
848 if (!(tracer->trace.ds.flags & BTS_KERNEL))
849 control |= ds_cfg.ctl[dsf_bts_kernel];
850 if (!(tracer->trace.ds.flags & BTS_USER))
851 control |= ds_cfg.ctl[dsf_bts_user];
852
853 if (task) {
854 task->thread.debugctlmsr |= control;
855 set_tsk_thread_flag(task, TIF_DEBUGCTLMSR);
856 }
857
858 if (!task || (task == current))
859 update_debugctlmsr(get_debugctlmsr() | control);
860}
861
862void ds_release_pebs(struct pebs_tracer *tracer)
863{
864 if (!tracer)
865 return;
866
867 ds_suspend_pebs(tracer);
868
869 WARN_ON_ONCE(tracer->ds.context->pebs_master != tracer);
870 tracer->ds.context->pebs_master = NULL;
871
872 put_tracer(tracer->ds.context->task);
873 ds_put_context(tracer->ds.context);
874
875 kfree(tracer);
876}
877
878void ds_suspend_pebs(struct pebs_tracer *tracer)
879{
880
881}
882
883void ds_resume_pebs(struct pebs_tracer *tracer)
884{
885
886}
887
888const struct bts_trace *ds_read_bts(struct bts_tracer *tracer)
889{
890 if (!tracer)
891 return NULL;
892
893 ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
894 return &tracer->trace;
895}
896
897const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer)
898{
899 if (!tracer)
900 return NULL;
901
902 ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
903 tracer->trace.reset_value =
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100904 *(u64 *)(tracer->ds.context->ds +
905 (ds_cfg.sizeof_ptr_field * 8));
Markus Metzgerc2724772008-12-11 13:49:59 +0100906
907 return &tracer->trace;
Markus Metzger93fa7632008-04-08 11:01:58 +0200908}
909
Markus Metzgerca0002a2008-11-25 09:01:25 +0100910int ds_reset_bts(struct bts_tracer *tracer)
Markus Metzger93fa7632008-04-08 11:01:58 +0200911{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100912 if (!tracer)
913 return -EINVAL;
914
Markus Metzgerc2724772008-12-11 13:49:59 +0100915 tracer->trace.ds.top = tracer->trace.ds.begin;
916
917 ds_set(tracer->ds.context->ds, ds_bts, ds_index,
918 (unsigned long)tracer->trace.ds.top);
Markus Metzgerca0002a2008-11-25 09:01:25 +0100919
920 return 0;
Markus Metzger93fa7632008-04-08 11:01:58 +0200921}
922
Markus Metzgerca0002a2008-11-25 09:01:25 +0100923int ds_reset_pebs(struct pebs_tracer *tracer)
Markus Metzger93fa7632008-04-08 11:01:58 +0200924{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100925 if (!tracer)
926 return -EINVAL;
927
Markus Metzgerc2724772008-12-11 13:49:59 +0100928 tracer->trace.ds.top = tracer->trace.ds.begin;
Markus Metzgerca0002a2008-11-25 09:01:25 +0100929
Markus Metzgerc2724772008-12-11 13:49:59 +0100930 ds_set(tracer->ds.context->ds, ds_bts, ds_index,
931 (unsigned long)tracer->trace.ds.top);
Markus Metzger93fa7632008-04-08 11:01:58 +0200932
Markus Metzgerca0002a2008-11-25 09:01:25 +0100933 return 0;
Markus Metzger93fa7632008-04-08 11:01:58 +0200934}
935
Markus Metzgerca0002a2008-11-25 09:01:25 +0100936int ds_set_pebs_reset(struct pebs_tracer *tracer, u64 value)
Markus Metzger93fa7632008-04-08 11:01:58 +0200937{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100938 if (!tracer)
939 return -EINVAL;
Markus Metzger93fa7632008-04-08 11:01:58 +0200940
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100941 *(u64 *)(tracer->ds.context->ds +
942 (ds_cfg.sizeof_ptr_field * 8)) = value;
Markus Metzger93fa7632008-04-08 11:01:58 +0200943
Markus Metzgerca0002a2008-11-25 09:01:25 +0100944 return 0;
Markus Metzger93fa7632008-04-08 11:01:58 +0200945}
946
Markus Metzgerc2724772008-12-11 13:49:59 +0100947static const struct ds_configuration ds_cfg_netburst = {
Markus Metzgerba2607f2009-01-19 10:38:35 +0100948 .name = "Netburst",
Markus Metzgerc2724772008-12-11 13:49:59 +0100949 .ctl[dsf_bts] = (1 << 2) | (1 << 3),
950 .ctl[dsf_bts_kernel] = (1 << 5),
951 .ctl[dsf_bts_user] = (1 << 6),
Markus Metzger93fa7632008-04-08 11:01:58 +0200952};
Markus Metzgerc2724772008-12-11 13:49:59 +0100953static const struct ds_configuration ds_cfg_pentium_m = {
Markus Metzgerba2607f2009-01-19 10:38:35 +0100954 .name = "Pentium M",
Markus Metzgerc2724772008-12-11 13:49:59 +0100955 .ctl[dsf_bts] = (1 << 6) | (1 << 7),
Markus Metzgereee3af42008-01-30 13:31:09 +0100956};
Markus Metzgerba2607f2009-01-19 10:38:35 +0100957static const struct ds_configuration ds_cfg_core2_atom = {
958 .name = "Core 2/Atom",
Markus Metzgerc2724772008-12-11 13:49:59 +0100959 .ctl[dsf_bts] = (1 << 6) | (1 << 7),
960 .ctl[dsf_bts_kernel] = (1 << 9),
961 .ctl[dsf_bts_user] = (1 << 10),
Markus Metzgerc2724772008-12-11 13:49:59 +0100962};
Markus Metzgereee3af42008-01-30 13:31:09 +0100963
Markus Metzgerc2724772008-12-11 13:49:59 +0100964static void
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100965ds_configure(const struct ds_configuration *cfg,
966 struct cpuinfo_x86 *cpu)
Markus Metzgereee3af42008-01-30 13:31:09 +0100967{
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100968 unsigned long nr_pebs_fields = 0;
969
970 printk(KERN_INFO "[ds] using %s configuration\n", cfg->name);
971
972#ifdef __i386__
973 nr_pebs_fields = 10;
974#else
975 nr_pebs_fields = 18;
976#endif
977
Markus Metzgerc2724772008-12-11 13:49:59 +0100978 memset(&ds_cfg, 0, sizeof(ds_cfg));
Markus Metzgereee3af42008-01-30 13:31:09 +0100979 ds_cfg = *cfg;
Markus Metzgerca0002a2008-11-25 09:01:25 +0100980
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100981 ds_cfg.sizeof_ptr_field =
982 (cpu_has(cpu, X86_FEATURE_DTES64) ? 8 : 4);
Markus Metzgerca0002a2008-11-25 09:01:25 +0100983
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100984 ds_cfg.sizeof_rec[ds_bts] = ds_cfg.sizeof_ptr_field * 3;
985 ds_cfg.sizeof_rec[ds_pebs] = ds_cfg.sizeof_ptr_field * nr_pebs_fields;
986
987 if (!cpu_has(cpu, X86_FEATURE_BTS)) {
988 ds_cfg.sizeof_rec[ds_bts] = 0;
Markus Metzgerc2724772008-12-11 13:49:59 +0100989 printk(KERN_INFO "[ds] bts not available\n");
990 }
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100991 if (!cpu_has(cpu, X86_FEATURE_PEBS)) {
992 ds_cfg.sizeof_rec[ds_pebs] = 0;
Markus Metzgerc2724772008-12-11 13:49:59 +0100993 printk(KERN_INFO "[ds] pebs not available\n");
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100994 }
995
Markus Metzger8a327f62009-03-13 10:45:07 +0100996 if (ds_cfg.sizeof_rec[ds_bts]) {
997 int error;
998
999 error = ds_selftest_bts();
1000 if (error) {
1001 WARN(1, "[ds] selftest failed. disabling bts.\n");
1002 ds_cfg.sizeof_rec[ds_bts] = 0;
1003 }
1004 }
1005
1006 if (ds_cfg.sizeof_rec[ds_pebs]) {
1007 int error;
1008
1009 error = ds_selftest_pebs();
1010 if (error) {
1011 WARN(1, "[ds] selftest failed. disabling pebs.\n");
1012 ds_cfg.sizeof_rec[ds_pebs] = 0;
1013 }
1014 }
1015
Markus Metzgerbc44fb52009-03-13 10:42:18 +01001016 printk(KERN_INFO "[ds] sizes: address: %u bit, ",
1017 8 * ds_cfg.sizeof_ptr_field);
1018 printk("bts/pebs record: %u/%u bytes\n",
1019 ds_cfg.sizeof_rec[ds_bts], ds_cfg.sizeof_rec[ds_pebs]);
Markus Metzgerc2724772008-12-11 13:49:59 +01001020
Ingo Molnar79258a32009-03-13 12:02:08 +01001021 WARN_ON_ONCE(MAX_SIZEOF_DS < (12 * ds_cfg.sizeof_ptr_field));
Markus Metzgereee3af42008-01-30 13:31:09 +01001022}
1023
1024void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
1025{
1026 switch (c->x86) {
1027 case 0x6:
1028 switch (c->x86_model) {
Markus Metzgerba2607f2009-01-19 10:38:35 +01001029 case 0x9:
1030 case 0xd: /* Pentium M */
Markus Metzgerbc44fb52009-03-13 10:42:18 +01001031 ds_configure(&ds_cfg_pentium_m, c);
Markus Metzgereee3af42008-01-30 13:31:09 +01001032 break;
Markus Metzgerba2607f2009-01-19 10:38:35 +01001033 case 0xf:
1034 case 0x17: /* Core2 */
1035 case 0x1c: /* Atom */
Markus Metzgerbc44fb52009-03-13 10:42:18 +01001036 ds_configure(&ds_cfg_core2_atom, c);
Markus Metzgerba2607f2009-01-19 10:38:35 +01001037 break;
Markus Metzgerb8e47192009-03-13 10:46:42 +01001038 case 0x1a: /* Core i7 */
Markus Metzgerba2607f2009-01-19 10:38:35 +01001039 default:
Markus Metzgerb8e47192009-03-13 10:46:42 +01001040 /* Sorry, don't know about them. */
Markus Metzgereee3af42008-01-30 13:31:09 +01001041 break;
Markus Metzgereee3af42008-01-30 13:31:09 +01001042 }
1043 break;
Markus Metzgerba2607f2009-01-19 10:38:35 +01001044 case 0xf:
Markus Metzgereee3af42008-01-30 13:31:09 +01001045 switch (c->x86_model) {
Markus Metzgereee3af42008-01-30 13:31:09 +01001046 case 0x0:
1047 case 0x1:
1048 case 0x2: /* Netburst */
Markus Metzgerbc44fb52009-03-13 10:42:18 +01001049 ds_configure(&ds_cfg_netburst, c);
Markus Metzgereee3af42008-01-30 13:31:09 +01001050 break;
Markus Metzgereee3af42008-01-30 13:31:09 +01001051 default:
Markus Metzgerb8e47192009-03-13 10:46:42 +01001052 /* Sorry, don't know about them. */
Markus Metzgereee3af42008-01-30 13:31:09 +01001053 break;
1054 }
1055 break;
1056 default:
Markus Metzgerb8e47192009-03-13 10:46:42 +01001057 /* Sorry, don't know about them. */
Markus Metzgereee3af42008-01-30 13:31:09 +01001058 break;
1059 }
1060}
Markus Metzger93fa7632008-04-08 11:01:58 +02001061
Markus Metzgercac94f92009-04-03 16:43:33 +02001062static inline void ds_take_timestamp(struct ds_context *context,
1063 enum bts_qualifier qualifier,
1064 struct task_struct *task)
1065{
1066 struct bts_tracer *tracer = context->bts_master;
1067 struct bts_struct ts;
1068
1069 /* Prevent compilers from reading the tracer pointer twice. */
1070 barrier();
1071
1072 if (!tracer || !(tracer->flags & BTS_TIMESTAMPS))
1073 return;
1074
1075 memset(&ts, 0, sizeof(ts));
1076 ts.qualifier = qualifier;
1077 ts.variant.timestamp.jiffies = jiffies_64;
1078 ts.variant.timestamp.pid = task->pid;
1079
1080 bts_write(tracer, &ts);
1081}
1082
Markus Metzgerc2724772008-12-11 13:49:59 +01001083/*
1084 * Change the DS configuration from tracing prev to tracing next.
1085 */
1086void ds_switch_to(struct task_struct *prev, struct task_struct *next)
Markus Metzger93fa7632008-04-08 11:01:58 +02001087{
Markus Metzgercac94f92009-04-03 16:43:33 +02001088 struct ds_context *prev_ctx = prev->thread.ds_ctx;
1089 struct ds_context *next_ctx = next->thread.ds_ctx;
1090 unsigned long debugctlmsr = next->thread.debugctlmsr;
1091
1092 /* Make sure all data is read before we start. */
1093 barrier();
Markus Metzgerc2724772008-12-11 13:49:59 +01001094
1095 if (prev_ctx) {
1096 update_debugctlmsr(0);
1097
Markus Metzgercac94f92009-04-03 16:43:33 +02001098 ds_take_timestamp(prev_ctx, bts_task_departs, prev);
Markus Metzgerca0002a2008-11-25 09:01:25 +01001099 }
Markus Metzgerc2724772008-12-11 13:49:59 +01001100
1101 if (next_ctx) {
Markus Metzgercac94f92009-04-03 16:43:33 +02001102 ds_take_timestamp(next_ctx, bts_task_arrives, next);
Markus Metzgerc2724772008-12-11 13:49:59 +01001103
1104 wrmsrl(MSR_IA32_DS_AREA, (unsigned long)next_ctx->ds);
1105 }
1106
Markus Metzgercac94f92009-04-03 16:43:33 +02001107 update_debugctlmsr(debugctlmsr);
Markus Metzger93fa7632008-04-08 11:01:58 +02001108}
Markus Metzgerbf53de92008-12-19 15:10:24 +01001109
1110void ds_copy_thread(struct task_struct *tsk, struct task_struct *father)
1111{
1112 clear_tsk_thread_flag(tsk, TIF_DS_AREA_MSR);
1113 tsk->thread.ds_ctx = NULL;
1114}
1115
1116void ds_exit_thread(struct task_struct *tsk)
1117{
Markus Metzgerbf53de92008-12-19 15:10:24 +01001118}