blob: c730155bf54d38fa41210e463d7e1d2ff0bd470f [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 Metzgerde90add2008-11-25 08:52:56 +0100302 unsigned long irq;
303
Markus Metzger93fa7632008-04-08 11:01:58 +0200304 if (!context)
305 return;
306
Markus Metzgerde90add2008-11-25 08:52:56 +0100307 spin_lock_irqsave(&ds_lock, irq);
Markus Metzger93fa7632008-04-08 11:01:58 +0200308
Markus Metzgerc2724772008-12-11 13:49:59 +0100309 if (--context->count) {
310 spin_unlock_irqrestore(&ds_lock, irq);
311 return;
312 }
Markus Metzger93fa7632008-04-08 11:01:58 +0200313
Cyrill Gorcunov573da422008-04-28 23:15:04 +0400314 *(context->this) = NULL;
Markus Metzger93fa7632008-04-08 11:01:58 +0200315
316 if (context->task)
317 clear_tsk_thread_flag(context->task, TIF_DS_AREA_MSR);
318
319 if (!context->task || (context->task == current))
320 wrmsrl(MSR_IA32_DS_AREA, 0);
321
Markus Metzgerde90add2008-11-25 08:52:56 +0100322 spin_unlock_irqrestore(&ds_lock, irq);
Markus Metzgerc2724772008-12-11 13:49:59 +0100323
324 kfree(context);
Markus Metzger93fa7632008-04-08 11:01:58 +0200325}
326
327
328/*
Markus Metzgerc2724772008-12-11 13:49:59 +0100329 * Call the tracer's callback on a buffer overflow.
Markus Metzger93fa7632008-04-08 11:01:58 +0200330 *
Markus Metzger93fa7632008-04-08 11:01:58 +0200331 * context: the ds context
332 * qual: the buffer type
333 */
Markus Metzgerca0002a2008-11-25 09:01:25 +0100334static void ds_overflow(struct ds_context *context, enum ds_qualifier qual)
Markus Metzger93fa7632008-04-08 11:01:58 +0200335{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100336 switch (qual) {
Markus Metzgerc2724772008-12-11 13:49:59 +0100337 case ds_bts:
338 if (context->bts_master &&
339 context->bts_master->ovfl)
340 context->bts_master->ovfl(context->bts_master);
Markus Metzgerca0002a2008-11-25 09:01:25 +0100341 break;
Markus Metzgerc2724772008-12-11 13:49:59 +0100342 case ds_pebs:
343 if (context->pebs_master &&
344 context->pebs_master->ovfl)
345 context->pebs_master->ovfl(context->pebs_master);
Markus Metzgerca0002a2008-11-25 09:01:25 +0100346 break;
347 }
Markus Metzger93fa7632008-04-08 11:01:58 +0200348}
349
350
Markus Metzgerc2724772008-12-11 13:49:59 +0100351/*
352 * Write raw data into the BTS or PEBS buffer.
353 *
354 * The remainder of any partially written record is zeroed out.
355 *
356 * context: the DS context
Ingo Molnare9a22d12009-03-13 11:54:40 +0100357 * qual: the buffer type
358 * record: the data to write
359 * size: the size of the data
Markus Metzgerc2724772008-12-11 13:49:59 +0100360 */
Markus Metzgerca0002a2008-11-25 09:01:25 +0100361static int ds_write(struct ds_context *context, enum ds_qualifier qual,
362 const void *record, size_t size)
Markus Metzger93fa7632008-04-08 11:01:58 +0200363{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100364 int bytes_written = 0;
Markus Metzger93fa7632008-04-08 11:01:58 +0200365
366 if (!record)
367 return -EINVAL;
368
Markus Metzger93fa7632008-04-08 11:01:58 +0200369 while (size) {
370 unsigned long base, index, end, write_end, int_th;
371 unsigned long write_size, adj_write_size;
Markus Metzgereee3af42008-01-30 13:31:09 +0100372
Markus Metzger93fa7632008-04-08 11:01:58 +0200373 /*
Markus Metzgerb8e47192009-03-13 10:46:42 +0100374 * Write as much as possible without producing an
Markus Metzger93fa7632008-04-08 11:01:58 +0200375 * overflow interrupt.
376 *
Markus Metzgerb8e47192009-03-13 10:46:42 +0100377 * Interrupt_threshold must either be
Markus Metzger93fa7632008-04-08 11:01:58 +0200378 * - bigger than absolute_maximum or
379 * - point to a record between buffer_base and absolute_maximum
380 *
Markus Metzgerb8e47192009-03-13 10:46:42 +0100381 * Index points to a valid record.
Markus Metzger93fa7632008-04-08 11:01:58 +0200382 */
383 base = ds_get(context->ds, qual, ds_buffer_base);
384 index = ds_get(context->ds, qual, ds_index);
385 end = ds_get(context->ds, qual, ds_absolute_maximum);
386 int_th = ds_get(context->ds, qual, ds_interrupt_threshold);
387
388 write_end = min(end, int_th);
389
Markus Metzgerb8e47192009-03-13 10:46:42 +0100390 /*
391 * If we are already beyond the interrupt threshold,
392 * we fill the entire buffer.
393 */
Markus Metzger93fa7632008-04-08 11:01:58 +0200394 if (write_end <= index)
395 write_end = end;
396
397 if (write_end <= index)
Markus Metzgerca0002a2008-11-25 09:01:25 +0100398 break;
Markus Metzger93fa7632008-04-08 11:01:58 +0200399
400 write_size = min((unsigned long) size, write_end - index);
401 memcpy((void *)index, record, write_size);
402
403 record = (const char *)record + write_size;
Markus Metzgerca0002a2008-11-25 09:01:25 +0100404 size -= write_size;
405 bytes_written += write_size;
Markus Metzger93fa7632008-04-08 11:01:58 +0200406
407 adj_write_size = write_size / ds_cfg.sizeof_rec[qual];
408 adj_write_size *= ds_cfg.sizeof_rec[qual];
409
Markus Metzgerb8e47192009-03-13 10:46:42 +0100410 /* Zero out trailing bytes. */
Markus Metzger93fa7632008-04-08 11:01:58 +0200411 memset((char *)index + write_size, 0,
412 adj_write_size - write_size);
413 index += adj_write_size;
414
415 if (index >= end)
416 index = base;
417 ds_set(context->ds, qual, ds_index, index);
418
419 if (index >= int_th)
Markus Metzgerca0002a2008-11-25 09:01:25 +0100420 ds_overflow(context, qual);
Markus Metzger93fa7632008-04-08 11:01:58 +0200421 }
422
Markus Metzgerca0002a2008-11-25 09:01:25 +0100423 return bytes_written;
Markus Metzgereee3af42008-01-30 13:31:09 +0100424}
425
Markus Metzgerc2724772008-12-11 13:49:59 +0100426
427/*
428 * Branch Trace Store (BTS) uses the following format. Different
429 * architectures vary in the size of those fields.
430 * - source linear address
431 * - destination linear address
432 * - flags
433 *
434 * Later architectures use 64bit pointers throughout, whereas earlier
435 * architectures use 32bit pointers in 32bit mode.
436 *
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100437 * We compute the base address for the fields based on:
Markus Metzgerc2724772008-12-11 13:49:59 +0100438 * - the field size stored in the DS configuration
439 * - the relative field position
440 *
441 * In order to store additional information in the BTS buffer, we use
442 * a special source address to indicate that the record requires
443 * special interpretation.
444 *
445 * Netburst indicated via a bit in the flags field whether the branch
446 * was predicted; this is ignored.
447 *
448 * We use two levels of abstraction:
449 * - the raw data level defined here
450 * - an arch-independent level defined in ds.h
451 */
452
453enum bts_field {
454 bts_from,
455 bts_to,
456 bts_flags,
457
Ingo Molnare9a22d12009-03-13 11:54:40 +0100458 bts_qual = bts_from,
459 bts_jiffies = bts_to,
460 bts_pid = bts_flags,
Markus Metzgerc2724772008-12-11 13:49:59 +0100461
Ingo Molnare9a22d12009-03-13 11:54:40 +0100462 bts_qual_mask = (bts_qual_max - 1),
463 bts_escape = ((unsigned long)-1 & ~bts_qual_mask)
Markus Metzgerc2724772008-12-11 13:49:59 +0100464};
465
466static inline unsigned long bts_get(const char *base, enum bts_field field)
467{
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100468 base += (ds_cfg.sizeof_ptr_field * field);
Markus Metzgerc2724772008-12-11 13:49:59 +0100469 return *(unsigned long *)base;
470}
471
472static inline void bts_set(char *base, enum bts_field field, unsigned long val)
473{
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100474 base += (ds_cfg.sizeof_ptr_field * field);;
Markus Metzgerc2724772008-12-11 13:49:59 +0100475 (*(unsigned long *)base) = val;
476}
477
478
479/*
480 * The raw BTS data is architecture dependent.
481 *
482 * For higher-level users, we give an arch-independent view.
483 * - ds.h defines struct bts_struct
484 * - bts_read translates one raw bts record into a bts_struct
485 * - bts_write translates one bts_struct into the raw format and
486 * writes it into the top of the parameter tracer's buffer.
487 *
488 * return: bytes read/written on success; -Eerrno, otherwise
489 */
Ingo Molnare9a22d12009-03-13 11:54:40 +0100490static int
491bts_read(struct bts_tracer *tracer, const void *at, struct bts_struct *out)
Markus Metzgereee3af42008-01-30 13:31:09 +0100492{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100493 if (!tracer)
494 return -EINVAL;
495
Markus Metzgerc2724772008-12-11 13:49:59 +0100496 if (at < tracer->trace.ds.begin)
497 return -EINVAL;
498
499 if (tracer->trace.ds.end < (at + tracer->trace.ds.size))
500 return -EINVAL;
501
502 memset(out, 0, sizeof(*out));
503 if ((bts_get(at, bts_qual) & ~bts_qual_mask) == bts_escape) {
504 out->qualifier = (bts_get(at, bts_qual) & bts_qual_mask);
505 out->variant.timestamp.jiffies = bts_get(at, bts_jiffies);
506 out->variant.timestamp.pid = bts_get(at, bts_pid);
507 } else {
508 out->qualifier = bts_branch;
509 out->variant.lbr.from = bts_get(at, bts_from);
510 out->variant.lbr.to = bts_get(at, bts_to);
Markus Metzgerd072c252008-12-16 15:53:11 +0100511
512 if (!out->variant.lbr.from && !out->variant.lbr.to)
513 out->qualifier = bts_invalid;
Markus Metzgerc2724772008-12-11 13:49:59 +0100514 }
515
516 return ds_cfg.sizeof_rec[ds_bts];
Markus Metzgereee3af42008-01-30 13:31:09 +0100517}
518
Markus Metzgerc2724772008-12-11 13:49:59 +0100519static int bts_write(struct bts_tracer *tracer, const struct bts_struct *in)
Markus Metzger93fa7632008-04-08 11:01:58 +0200520{
Markus Metzgerc2724772008-12-11 13:49:59 +0100521 unsigned char raw[MAX_SIZEOF_BTS];
522
Markus Metzgerca0002a2008-11-25 09:01:25 +0100523 if (!tracer)
524 return -EINVAL;
525
Markus Metzgerc2724772008-12-11 13:49:59 +0100526 if (MAX_SIZEOF_BTS < ds_cfg.sizeof_rec[ds_bts])
527 return -EOVERFLOW;
528
529 switch (in->qualifier) {
530 case bts_invalid:
531 bts_set(raw, bts_from, 0);
532 bts_set(raw, bts_to, 0);
533 bts_set(raw, bts_flags, 0);
534 break;
535 case bts_branch:
536 bts_set(raw, bts_from, in->variant.lbr.from);
537 bts_set(raw, bts_to, in->variant.lbr.to);
538 bts_set(raw, bts_flags, 0);
539 break;
540 case bts_task_arrives:
541 case bts_task_departs:
542 bts_set(raw, bts_qual, (bts_escape | in->qualifier));
543 bts_set(raw, bts_jiffies, in->variant.timestamp.jiffies);
544 bts_set(raw, bts_pid, in->variant.timestamp.pid);
545 break;
546 default:
547 return -EINVAL;
548 }
549
550 return ds_write(tracer->ds.context, ds_bts, raw,
551 ds_cfg.sizeof_rec[ds_bts]);
Markus Metzger93fa7632008-04-08 11:01:58 +0200552}
Markus Metzgereee3af42008-01-30 13:31:09 +0100553
Markus Metzgerc2724772008-12-11 13:49:59 +0100554
555static void ds_write_config(struct ds_context *context,
556 struct ds_trace *cfg, enum ds_qualifier qual)
Markus Metzger93fa7632008-04-08 11:01:58 +0200557{
Markus Metzgerc2724772008-12-11 13:49:59 +0100558 unsigned char *ds = context->ds;
Markus Metzger93fa7632008-04-08 11:01:58 +0200559
Markus Metzgerc2724772008-12-11 13:49:59 +0100560 ds_set(ds, qual, ds_buffer_base, (unsigned long)cfg->begin);
561 ds_set(ds, qual, ds_index, (unsigned long)cfg->top);
562 ds_set(ds, qual, ds_absolute_maximum, (unsigned long)cfg->end);
563 ds_set(ds, qual, ds_interrupt_threshold, (unsigned long)cfg->ith);
564}
Markus Metzger93fa7632008-04-08 11:01:58 +0200565
Markus Metzgerc2724772008-12-11 13:49:59 +0100566static void ds_read_config(struct ds_context *context,
567 struct ds_trace *cfg, enum ds_qualifier qual)
568{
569 unsigned char *ds = context->ds;
Markus Metzger93fa7632008-04-08 11:01:58 +0200570
Markus Metzgerc2724772008-12-11 13:49:59 +0100571 cfg->begin = (void *)ds_get(ds, qual, ds_buffer_base);
572 cfg->top = (void *)ds_get(ds, qual, ds_index);
573 cfg->end = (void *)ds_get(ds, qual, ds_absolute_maximum);
574 cfg->ith = (void *)ds_get(ds, qual, ds_interrupt_threshold);
575}
576
577static void ds_init_ds_trace(struct ds_trace *trace, enum ds_qualifier qual,
578 void *base, size_t size, size_t ith,
579 unsigned int flags) {
580 unsigned long buffer, adj;
581
Markus Metzgerb8e47192009-03-13 10:46:42 +0100582 /*
583 * Adjust the buffer address and size to meet alignment
Markus Metzgerc2724772008-12-11 13:49:59 +0100584 * constraints:
585 * - buffer is double-word aligned
586 * - size is multiple of record size
587 *
588 * We checked the size at the very beginning; we have enough
589 * space to do the adjustment.
590 */
591 buffer = (unsigned long)base;
592
593 adj = ALIGN(buffer, DS_ALIGNMENT) - buffer;
594 buffer += adj;
595 size -= adj;
596
597 trace->n = size / ds_cfg.sizeof_rec[qual];
598 trace->size = ds_cfg.sizeof_rec[qual];
599
600 size = (trace->n * trace->size);
601
602 trace->begin = (void *)buffer;
603 trace->top = trace->begin;
604 trace->end = (void *)(buffer + size);
Markus Metzgerb8e47192009-03-13 10:46:42 +0100605 /*
606 * The value for 'no threshold' is -1, which will set the
Markus Metzgerc2724772008-12-11 13:49:59 +0100607 * threshold outside of the buffer, just like we want it.
608 */
609 trace->ith = (void *)(buffer + size - ith);
610
611 trace->flags = flags;
612}
613
614
615static int ds_request(struct ds_tracer *tracer, struct ds_trace *trace,
616 enum ds_qualifier qual, struct task_struct *task,
617 void *base, size_t size, size_t th, unsigned int flags)
618{
619 struct ds_context *context;
620 int error;
621
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100622 error = -EOPNOTSUPP;
623 if (!ds_cfg.sizeof_rec[qual])
624 goto out;
625
Markus Metzgerc2724772008-12-11 13:49:59 +0100626 error = -EINVAL;
627 if (!base)
628 goto out;
629
Markus Metzgerb8e47192009-03-13 10:46:42 +0100630 /* We require some space to do alignment adjustments below. */
Markus Metzgerc2724772008-12-11 13:49:59 +0100631 error = -EINVAL;
632 if (size < (DS_ALIGNMENT + ds_cfg.sizeof_rec[qual]))
633 goto out;
634
635 if (th != (size_t)-1) {
636 th *= ds_cfg.sizeof_rec[qual];
637
638 error = -EINVAL;
639 if (size <= th)
640 goto out;
641 }
642
643 tracer->buffer = base;
644 tracer->size = size;
645
646 error = -ENOMEM;
647 context = ds_get_context(task);
648 if (!context)
649 goto out;
650 tracer->context = context;
651
652 ds_init_ds_trace(trace, qual, base, size, th, flags);
653
654 error = 0;
655 out:
656 return error;
657}
658
659struct bts_tracer *ds_request_bts(struct task_struct *task,
660 void *base, size_t size,
661 bts_ovfl_callback_t ovfl, size_t th,
662 unsigned int flags)
663{
664 struct bts_tracer *tracer;
665 unsigned long irq;
666 int error;
667
Markus Metzgerb8e47192009-03-13 10:46:42 +0100668 /* Buffer overflow notification is not yet implemented. */
Markus Metzgerc2724772008-12-11 13:49:59 +0100669 error = -EOPNOTSUPP;
670 if (ovfl)
671 goto out;
672
Markus Metzgerc78a3952009-03-18 19:27:00 +0100673 /*
674 * Per-cpu tracing is typically requested using smp_call_function().
675 * We must not sleep.
676 */
Markus Metzgerc2724772008-12-11 13:49:59 +0100677 error = -ENOMEM;
Markus Metzgerc78a3952009-03-18 19:27:00 +0100678 tracer = kzalloc(sizeof(*tracer), GFP_ATOMIC);
Markus Metzgerc2724772008-12-11 13:49:59 +0100679 if (!tracer)
680 goto out;
681 tracer->ovfl = ovfl;
682
683 error = ds_request(&tracer->ds, &tracer->trace.ds,
684 ds_bts, task, base, size, th, flags);
685 if (error < 0)
686 goto out_tracer;
687
688
689 spin_lock_irqsave(&ds_lock, irq);
690
691 error = -EPERM;
692 if (!check_tracer(task))
693 goto out_unlock;
694 get_tracer(task);
695
696 error = -EPERM;
697 if (tracer->ds.context->bts_master)
698 goto out_put_tracer;
699 tracer->ds.context->bts_master = tracer;
700
701 spin_unlock_irqrestore(&ds_lock, irq);
702
703
704 tracer->trace.read = bts_read;
705 tracer->trace.write = bts_write;
706
707 ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
708 ds_resume_bts(tracer);
709
710 return tracer;
711
712 out_put_tracer:
713 put_tracer(task);
714 out_unlock:
715 spin_unlock_irqrestore(&ds_lock, irq);
716 ds_put_context(tracer->ds.context);
717 out_tracer:
718 kfree(tracer);
719 out:
720 return ERR_PTR(error);
721}
722
723struct pebs_tracer *ds_request_pebs(struct task_struct *task,
724 void *base, size_t size,
725 pebs_ovfl_callback_t ovfl, size_t th,
726 unsigned int flags)
727{
728 struct pebs_tracer *tracer;
729 unsigned long irq;
730 int error;
731
Markus Metzgerb8e47192009-03-13 10:46:42 +0100732 /* Buffer overflow notification is not yet implemented. */
Markus Metzgerc2724772008-12-11 13:49:59 +0100733 error = -EOPNOTSUPP;
734 if (ovfl)
735 goto out;
736
Markus Metzgerc78a3952009-03-18 19:27:00 +0100737 /*
738 * Per-cpu tracing is typically requested using smp_call_function().
739 * We must not sleep.
740 */
Markus Metzgerc2724772008-12-11 13:49:59 +0100741 error = -ENOMEM;
Markus Metzgerc78a3952009-03-18 19:27:00 +0100742 tracer = kzalloc(sizeof(*tracer), GFP_ATOMIC);
Markus Metzgerc2724772008-12-11 13:49:59 +0100743 if (!tracer)
744 goto out;
745 tracer->ovfl = ovfl;
746
747 error = ds_request(&tracer->ds, &tracer->trace.ds,
748 ds_pebs, task, base, size, th, flags);
749 if (error < 0)
750 goto out_tracer;
751
752 spin_lock_irqsave(&ds_lock, irq);
753
754 error = -EPERM;
755 if (!check_tracer(task))
756 goto out_unlock;
757 get_tracer(task);
758
759 error = -EPERM;
760 if (tracer->ds.context->pebs_master)
761 goto out_put_tracer;
762 tracer->ds.context->pebs_master = tracer;
763
764 spin_unlock_irqrestore(&ds_lock, irq);
765
Markus Metzger73bf1b62009-03-05 08:57:21 +0100766 ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
Markus Metzgerc2724772008-12-11 13:49:59 +0100767 ds_resume_pebs(tracer);
768
769 return tracer;
770
771 out_put_tracer:
772 put_tracer(task);
773 out_unlock:
774 spin_unlock_irqrestore(&ds_lock, irq);
775 ds_put_context(tracer->ds.context);
776 out_tracer:
777 kfree(tracer);
778 out:
779 return ERR_PTR(error);
780}
781
782void ds_release_bts(struct bts_tracer *tracer)
783{
784 if (!tracer)
785 return;
786
787 ds_suspend_bts(tracer);
788
789 WARN_ON_ONCE(tracer->ds.context->bts_master != tracer);
790 tracer->ds.context->bts_master = NULL;
791
792 put_tracer(tracer->ds.context->task);
793 ds_put_context(tracer->ds.context);
794
795 kfree(tracer);
796}
797
798void ds_suspend_bts(struct bts_tracer *tracer)
799{
800 struct task_struct *task;
801
802 if (!tracer)
803 return;
804
Markus Metzgercac94f92009-04-03 16:43:33 +0200805 tracer->flags = 0;
806
Markus Metzgerc2724772008-12-11 13:49:59 +0100807 task = tracer->ds.context->task;
808
809 if (!task || (task == current))
810 update_debugctlmsr(get_debugctlmsr() & ~BTS_CONTROL);
811
812 if (task) {
813 task->thread.debugctlmsr &= ~BTS_CONTROL;
814
815 if (!task->thread.debugctlmsr)
816 clear_tsk_thread_flag(task, TIF_DEBUGCTLMSR);
817 }
818}
819
820void ds_resume_bts(struct bts_tracer *tracer)
821{
822 struct task_struct *task;
823 unsigned long control;
824
825 if (!tracer)
826 return;
827
Markus Metzgercac94f92009-04-03 16:43:33 +0200828 tracer->flags = tracer->trace.ds.flags;
829
Markus Metzgerc2724772008-12-11 13:49:59 +0100830 task = tracer->ds.context->task;
831
832 control = ds_cfg.ctl[dsf_bts];
833 if (!(tracer->trace.ds.flags & BTS_KERNEL))
834 control |= ds_cfg.ctl[dsf_bts_kernel];
835 if (!(tracer->trace.ds.flags & BTS_USER))
836 control |= ds_cfg.ctl[dsf_bts_user];
837
838 if (task) {
839 task->thread.debugctlmsr |= control;
840 set_tsk_thread_flag(task, TIF_DEBUGCTLMSR);
841 }
842
843 if (!task || (task == current))
844 update_debugctlmsr(get_debugctlmsr() | control);
845}
846
847void ds_release_pebs(struct pebs_tracer *tracer)
848{
849 if (!tracer)
850 return;
851
852 ds_suspend_pebs(tracer);
853
854 WARN_ON_ONCE(tracer->ds.context->pebs_master != tracer);
855 tracer->ds.context->pebs_master = NULL;
856
857 put_tracer(tracer->ds.context->task);
858 ds_put_context(tracer->ds.context);
859
860 kfree(tracer);
861}
862
863void ds_suspend_pebs(struct pebs_tracer *tracer)
864{
865
866}
867
868void ds_resume_pebs(struct pebs_tracer *tracer)
869{
870
871}
872
873const struct bts_trace *ds_read_bts(struct bts_tracer *tracer)
874{
875 if (!tracer)
876 return NULL;
877
878 ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
879 return &tracer->trace;
880}
881
882const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer)
883{
884 if (!tracer)
885 return NULL;
886
887 ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
888 tracer->trace.reset_value =
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100889 *(u64 *)(tracer->ds.context->ds +
890 (ds_cfg.sizeof_ptr_field * 8));
Markus Metzgerc2724772008-12-11 13:49:59 +0100891
892 return &tracer->trace;
Markus Metzger93fa7632008-04-08 11:01:58 +0200893}
894
Markus Metzgerca0002a2008-11-25 09:01:25 +0100895int ds_reset_bts(struct bts_tracer *tracer)
Markus Metzger93fa7632008-04-08 11:01:58 +0200896{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100897 if (!tracer)
898 return -EINVAL;
899
Markus Metzgerc2724772008-12-11 13:49:59 +0100900 tracer->trace.ds.top = tracer->trace.ds.begin;
901
902 ds_set(tracer->ds.context->ds, ds_bts, ds_index,
903 (unsigned long)tracer->trace.ds.top);
Markus Metzgerca0002a2008-11-25 09:01:25 +0100904
905 return 0;
Markus Metzger93fa7632008-04-08 11:01:58 +0200906}
907
Markus Metzgerca0002a2008-11-25 09:01:25 +0100908int ds_reset_pebs(struct pebs_tracer *tracer)
Markus Metzger93fa7632008-04-08 11:01:58 +0200909{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100910 if (!tracer)
911 return -EINVAL;
912
Markus Metzgerc2724772008-12-11 13:49:59 +0100913 tracer->trace.ds.top = tracer->trace.ds.begin;
Markus Metzgerca0002a2008-11-25 09:01:25 +0100914
Markus Metzgerc2724772008-12-11 13:49:59 +0100915 ds_set(tracer->ds.context->ds, ds_bts, ds_index,
916 (unsigned long)tracer->trace.ds.top);
Markus Metzger93fa7632008-04-08 11:01:58 +0200917
Markus Metzgerca0002a2008-11-25 09:01:25 +0100918 return 0;
Markus Metzger93fa7632008-04-08 11:01:58 +0200919}
920
Markus Metzgerca0002a2008-11-25 09:01:25 +0100921int ds_set_pebs_reset(struct pebs_tracer *tracer, u64 value)
Markus Metzger93fa7632008-04-08 11:01:58 +0200922{
Markus Metzgerca0002a2008-11-25 09:01:25 +0100923 if (!tracer)
924 return -EINVAL;
Markus Metzger93fa7632008-04-08 11:01:58 +0200925
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100926 *(u64 *)(tracer->ds.context->ds +
927 (ds_cfg.sizeof_ptr_field * 8)) = value;
Markus Metzger93fa7632008-04-08 11:01:58 +0200928
Markus Metzgerca0002a2008-11-25 09:01:25 +0100929 return 0;
Markus Metzger93fa7632008-04-08 11:01:58 +0200930}
931
Markus Metzgerc2724772008-12-11 13:49:59 +0100932static const struct ds_configuration ds_cfg_netburst = {
Markus Metzgerba2607f2009-01-19 10:38:35 +0100933 .name = "Netburst",
Markus Metzgerc2724772008-12-11 13:49:59 +0100934 .ctl[dsf_bts] = (1 << 2) | (1 << 3),
935 .ctl[dsf_bts_kernel] = (1 << 5),
936 .ctl[dsf_bts_user] = (1 << 6),
Markus Metzger93fa7632008-04-08 11:01:58 +0200937};
Markus Metzgerc2724772008-12-11 13:49:59 +0100938static const struct ds_configuration ds_cfg_pentium_m = {
Markus Metzgerba2607f2009-01-19 10:38:35 +0100939 .name = "Pentium M",
Markus Metzgerc2724772008-12-11 13:49:59 +0100940 .ctl[dsf_bts] = (1 << 6) | (1 << 7),
Markus Metzgereee3af42008-01-30 13:31:09 +0100941};
Markus Metzgerba2607f2009-01-19 10:38:35 +0100942static const struct ds_configuration ds_cfg_core2_atom = {
943 .name = "Core 2/Atom",
Markus Metzgerc2724772008-12-11 13:49:59 +0100944 .ctl[dsf_bts] = (1 << 6) | (1 << 7),
945 .ctl[dsf_bts_kernel] = (1 << 9),
946 .ctl[dsf_bts_user] = (1 << 10),
Markus Metzgerc2724772008-12-11 13:49:59 +0100947};
Markus Metzgereee3af42008-01-30 13:31:09 +0100948
Markus Metzgerc2724772008-12-11 13:49:59 +0100949static void
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100950ds_configure(const struct ds_configuration *cfg,
951 struct cpuinfo_x86 *cpu)
Markus Metzgereee3af42008-01-30 13:31:09 +0100952{
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100953 unsigned long nr_pebs_fields = 0;
954
955 printk(KERN_INFO "[ds] using %s configuration\n", cfg->name);
956
957#ifdef __i386__
958 nr_pebs_fields = 10;
959#else
960 nr_pebs_fields = 18;
961#endif
962
Markus Metzgerc2724772008-12-11 13:49:59 +0100963 memset(&ds_cfg, 0, sizeof(ds_cfg));
Markus Metzgereee3af42008-01-30 13:31:09 +0100964 ds_cfg = *cfg;
Markus Metzgerca0002a2008-11-25 09:01:25 +0100965
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100966 ds_cfg.sizeof_ptr_field =
967 (cpu_has(cpu, X86_FEATURE_DTES64) ? 8 : 4);
Markus Metzgerca0002a2008-11-25 09:01:25 +0100968
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100969 ds_cfg.sizeof_rec[ds_bts] = ds_cfg.sizeof_ptr_field * 3;
970 ds_cfg.sizeof_rec[ds_pebs] = ds_cfg.sizeof_ptr_field * nr_pebs_fields;
971
972 if (!cpu_has(cpu, X86_FEATURE_BTS)) {
973 ds_cfg.sizeof_rec[ds_bts] = 0;
Markus Metzgerc2724772008-12-11 13:49:59 +0100974 printk(KERN_INFO "[ds] bts not available\n");
975 }
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100976 if (!cpu_has(cpu, X86_FEATURE_PEBS)) {
977 ds_cfg.sizeof_rec[ds_pebs] = 0;
Markus Metzgerc2724772008-12-11 13:49:59 +0100978 printk(KERN_INFO "[ds] pebs not available\n");
Markus Metzgerbc44fb52009-03-13 10:42:18 +0100979 }
980
Markus Metzger8a327f62009-03-13 10:45:07 +0100981 if (ds_cfg.sizeof_rec[ds_bts]) {
982 int error;
983
984 error = ds_selftest_bts();
985 if (error) {
986 WARN(1, "[ds] selftest failed. disabling bts.\n");
987 ds_cfg.sizeof_rec[ds_bts] = 0;
988 }
989 }
990
991 if (ds_cfg.sizeof_rec[ds_pebs]) {
992 int error;
993
994 error = ds_selftest_pebs();
995 if (error) {
996 WARN(1, "[ds] selftest failed. disabling pebs.\n");
997 ds_cfg.sizeof_rec[ds_pebs] = 0;
998 }
999 }
1000
Markus Metzgerbc44fb52009-03-13 10:42:18 +01001001 printk(KERN_INFO "[ds] sizes: address: %u bit, ",
1002 8 * ds_cfg.sizeof_ptr_field);
1003 printk("bts/pebs record: %u/%u bytes\n",
1004 ds_cfg.sizeof_rec[ds_bts], ds_cfg.sizeof_rec[ds_pebs]);
Markus Metzgerc2724772008-12-11 13:49:59 +01001005
Ingo Molnar79258a32009-03-13 12:02:08 +01001006 WARN_ON_ONCE(MAX_SIZEOF_DS < (12 * ds_cfg.sizeof_ptr_field));
Markus Metzgereee3af42008-01-30 13:31:09 +01001007}
1008
1009void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
1010{
1011 switch (c->x86) {
1012 case 0x6:
1013 switch (c->x86_model) {
Markus Metzgerba2607f2009-01-19 10:38:35 +01001014 case 0x9:
1015 case 0xd: /* Pentium M */
Markus Metzgerbc44fb52009-03-13 10:42:18 +01001016 ds_configure(&ds_cfg_pentium_m, c);
Markus Metzgereee3af42008-01-30 13:31:09 +01001017 break;
Markus Metzgerba2607f2009-01-19 10:38:35 +01001018 case 0xf:
1019 case 0x17: /* Core2 */
1020 case 0x1c: /* Atom */
Markus Metzgerbc44fb52009-03-13 10:42:18 +01001021 ds_configure(&ds_cfg_core2_atom, c);
Markus Metzgerba2607f2009-01-19 10:38:35 +01001022 break;
Markus Metzgerb8e47192009-03-13 10:46:42 +01001023 case 0x1a: /* Core i7 */
Markus Metzgerba2607f2009-01-19 10:38:35 +01001024 default:
Markus Metzgerb8e47192009-03-13 10:46:42 +01001025 /* Sorry, don't know about them. */
Markus Metzgereee3af42008-01-30 13:31:09 +01001026 break;
Markus Metzgereee3af42008-01-30 13:31:09 +01001027 }
1028 break;
Markus Metzgerba2607f2009-01-19 10:38:35 +01001029 case 0xf:
Markus Metzgereee3af42008-01-30 13:31:09 +01001030 switch (c->x86_model) {
Markus Metzgereee3af42008-01-30 13:31:09 +01001031 case 0x0:
1032 case 0x1:
1033 case 0x2: /* Netburst */
Markus Metzgerbc44fb52009-03-13 10:42:18 +01001034 ds_configure(&ds_cfg_netburst, c);
Markus Metzgereee3af42008-01-30 13:31:09 +01001035 break;
Markus Metzgereee3af42008-01-30 13:31:09 +01001036 default:
Markus Metzgerb8e47192009-03-13 10:46:42 +01001037 /* Sorry, don't know about them. */
Markus Metzgereee3af42008-01-30 13:31:09 +01001038 break;
1039 }
1040 break;
1041 default:
Markus Metzgerb8e47192009-03-13 10:46:42 +01001042 /* Sorry, don't know about them. */
Markus Metzgereee3af42008-01-30 13:31:09 +01001043 break;
1044 }
1045}
Markus Metzger93fa7632008-04-08 11:01:58 +02001046
Markus Metzgercac94f92009-04-03 16:43:33 +02001047static inline void ds_take_timestamp(struct ds_context *context,
1048 enum bts_qualifier qualifier,
1049 struct task_struct *task)
1050{
1051 struct bts_tracer *tracer = context->bts_master;
1052 struct bts_struct ts;
1053
1054 /* Prevent compilers from reading the tracer pointer twice. */
1055 barrier();
1056
1057 if (!tracer || !(tracer->flags & BTS_TIMESTAMPS))
1058 return;
1059
1060 memset(&ts, 0, sizeof(ts));
1061 ts.qualifier = qualifier;
1062 ts.variant.timestamp.jiffies = jiffies_64;
1063 ts.variant.timestamp.pid = task->pid;
1064
1065 bts_write(tracer, &ts);
1066}
1067
Markus Metzgerc2724772008-12-11 13:49:59 +01001068/*
1069 * Change the DS configuration from tracing prev to tracing next.
1070 */
1071void ds_switch_to(struct task_struct *prev, struct task_struct *next)
Markus Metzger93fa7632008-04-08 11:01:58 +02001072{
Markus Metzgercac94f92009-04-03 16:43:33 +02001073 struct ds_context *prev_ctx = prev->thread.ds_ctx;
1074 struct ds_context *next_ctx = next->thread.ds_ctx;
1075 unsigned long debugctlmsr = next->thread.debugctlmsr;
1076
1077 /* Make sure all data is read before we start. */
1078 barrier();
Markus Metzgerc2724772008-12-11 13:49:59 +01001079
1080 if (prev_ctx) {
1081 update_debugctlmsr(0);
1082
Markus Metzgercac94f92009-04-03 16:43:33 +02001083 ds_take_timestamp(prev_ctx, bts_task_departs, prev);
Markus Metzgerca0002a2008-11-25 09:01:25 +01001084 }
Markus Metzgerc2724772008-12-11 13:49:59 +01001085
1086 if (next_ctx) {
Markus Metzgercac94f92009-04-03 16:43:33 +02001087 ds_take_timestamp(next_ctx, bts_task_arrives, next);
Markus Metzgerc2724772008-12-11 13:49:59 +01001088
1089 wrmsrl(MSR_IA32_DS_AREA, (unsigned long)next_ctx->ds);
1090 }
1091
Markus Metzgercac94f92009-04-03 16:43:33 +02001092 update_debugctlmsr(debugctlmsr);
Markus Metzger93fa7632008-04-08 11:01:58 +02001093}
Markus Metzgerbf53de92008-12-19 15:10:24 +01001094
1095void ds_copy_thread(struct task_struct *tsk, struct task_struct *father)
1096{
1097 clear_tsk_thread_flag(tsk, TIF_DS_AREA_MSR);
1098 tsk->thread.ds_ctx = NULL;
1099}
1100
1101void ds_exit_thread(struct task_struct *tsk)
1102{
Markus Metzgerbf53de92008-12-19 15:10:24 +01001103}