]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/x86/kernel/ds.c
Merge branches 'tracing/hw-branch-tracing' and 'tracing/branch-tracer' into tracing...
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / ds.c
1 /*
2  * Debug Store support
3  *
4  * This provides a low-level interface to the hardware's Debug Store
5  * feature that is used for branch trace store (BTS) and
6  * precise-event based sampling (PEBS).
7  *
8  * It manages:
9  * - per-thread and per-cpu allocation of BTS and PEBS
10  * - buffer overflow handling (to be done)
11  * - buffer access
12  *
13  * It assumes:
14  * - get_task_struct on all traced tasks
15  * - current is allowed to trace tasks
16  *
17  *
18  * Copyright (C) 2007-2008 Intel Corporation.
19  * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008
20  */
21
22
23 #include <asm/ds.h>
24
25 #include <linux/errno.h>
26 #include <linux/string.h>
27 #include <linux/slab.h>
28 #include <linux/sched.h>
29 #include <linux/mm.h>
30 #include <linux/kernel.h>
31
32
33 /*
34  * The configuration for a particular DS hardware implementation.
35  */
36 struct ds_configuration {
37         /* the size of the DS structure in bytes */
38         unsigned char  sizeof_ds;
39         /* the size of one pointer-typed field in the DS structure in bytes;
40            this covers the first 8 fields related to buffer management. */
41         unsigned char  sizeof_field;
42         /* the size of a BTS/PEBS record in bytes */
43         unsigned char  sizeof_rec[2];
44 };
45 static struct ds_configuration ds_cfg;
46
47 /*
48  * A BTS or PEBS tracer.
49  *
50  * This holds the configuration of the tracer and serves as a handle
51  * to identify tracers.
52  */
53 struct ds_tracer {
54         /* the DS context (partially) owned by this tracer */
55         struct ds_context *context;
56         /* the buffer provided on ds_request() and its size in bytes */
57         void *buffer;
58         size_t size;
59 };
60
61 struct bts_tracer {
62         /* the common DS part */
63         struct ds_tracer ds;
64         /* buffer overflow notification function */
65         bts_ovfl_callback_t ovfl;
66 };
67
68 struct pebs_tracer {
69         /* the common DS part */
70         struct ds_tracer ds;
71         /* buffer overflow notification function */
72         pebs_ovfl_callback_t ovfl;
73 };
74
75 /*
76  * Debug Store (DS) save area configuration (see Intel64 and IA32
77  * Architectures Software Developer's Manual, section 18.5)
78  *
79  * The DS configuration consists of the following fields; different
80  * architetures vary in the size of those fields.
81  * - double-word aligned base linear address of the BTS buffer
82  * - write pointer into the BTS buffer
83  * - end linear address of the BTS buffer (one byte beyond the end of
84  *   the buffer)
85  * - interrupt pointer into BTS buffer
86  *   (interrupt occurs when write pointer passes interrupt pointer)
87  * - double-word aligned base linear address of the PEBS buffer
88  * - write pointer into the PEBS buffer
89  * - end linear address of the PEBS buffer (one byte beyond the end of
90  *   the buffer)
91  * - interrupt pointer into PEBS buffer
92  *   (interrupt occurs when write pointer passes interrupt pointer)
93  * - value to which counter is reset following counter overflow
94  *
95  * Later architectures use 64bit pointers throughout, whereas earlier
96  * architectures use 32bit pointers in 32bit mode.
97  *
98  *
99  * We compute the base address for the first 8 fields based on:
100  * - the field size stored in the DS configuration
101  * - the relative field position
102  * - an offset giving the start of the respective region
103  *
104  * This offset is further used to index various arrays holding
105  * information for BTS and PEBS at the respective index.
106  *
107  * On later 32bit processors, we only access the lower 32bit of the
108  * 64bit pointer fields. The upper halves will be zeroed out.
109  */
110
111 enum ds_field {
112         ds_buffer_base = 0,
113         ds_index,
114         ds_absolute_maximum,
115         ds_interrupt_threshold,
116 };
117
118 enum ds_qualifier {
119         ds_bts  = 0,
120         ds_pebs
121 };
122
123 static inline unsigned long ds_get(const unsigned char *base,
124                                    enum ds_qualifier qual, enum ds_field field)
125 {
126         base += (ds_cfg.sizeof_field * (field + (4 * qual)));
127         return *(unsigned long *)base;
128 }
129
130 static inline void ds_set(unsigned char *base, enum ds_qualifier qual,
131                           enum ds_field field, unsigned long value)
132 {
133         base += (ds_cfg.sizeof_field * (field + (4 * qual)));
134         (*(unsigned long *)base) = value;
135 }
136
137 #define DS_ALIGNMENT (1 << 3)   /* BTS and PEBS buffer alignment */
138
139
140 /*
141  * Locking is done only for allocating BTS or PEBS resources.
142  */
143 static spinlock_t ds_lock = __SPIN_LOCK_UNLOCKED(ds_lock);
144
145
146 /*
147  * We either support (system-wide) per-cpu or per-thread allocation.
148  * We distinguish the two based on the task_struct pointer, where a
149  * NULL pointer indicates per-cpu allocation for the current cpu.
150  *
151  * Allocations are use-counted. As soon as resources are allocated,
152  * further allocations must be of the same type (per-cpu or
153  * per-thread). We model this by counting allocations (i.e. the number
154  * of tracers of a certain type) for one type negatively:
155  *   =0  no tracers
156  *   >0  number of per-thread tracers
157  *   <0  number of per-cpu tracers
158  *
159  * The below functions to get and put tracers and to check the
160  * allocation type require the ds_lock to be held by the caller.
161  *
162  * Tracers essentially gives the number of ds contexts for a certain
163  * type of allocation.
164  */
165 static long tracers;
166
167 static inline void get_tracer(struct task_struct *task)
168 {
169         tracers += (task ? 1 : -1);
170 }
171
172 static inline void put_tracer(struct task_struct *task)
173 {
174         tracers -= (task ? 1 : -1);
175 }
176
177 static inline int check_tracer(struct task_struct *task)
178 {
179         return (task ? (tracers >= 0) : (tracers <= 0));
180 }
181
182
183 /*
184  * The DS context is either attached to a thread or to a cpu:
185  * - in the former case, the thread_struct contains a pointer to the
186  *   attached context.
187  * - in the latter case, we use a static array of per-cpu context
188  *   pointers.
189  *
190  * Contexts are use-counted. They are allocated on first access and
191  * deallocated when the last user puts the context.
192  */
193 static DEFINE_PER_CPU(struct ds_context *, system_context);
194
195 #define this_system_context per_cpu(system_context, smp_processor_id())
196
197 static inline struct ds_context *ds_get_context(struct task_struct *task)
198 {
199         struct ds_context **p_context =
200                 (task ? &task->thread.ds_ctx : &this_system_context);
201         struct ds_context *context = *p_context;
202         unsigned long irq;
203
204         if (!context) {
205                 context = kzalloc(sizeof(*context), GFP_KERNEL);
206                 if (!context)
207                         return NULL;
208
209                 spin_lock_irqsave(&ds_lock, irq);
210
211                 if (*p_context) {
212                         kfree(context);
213
214                         context = *p_context;
215                 } else {
216                         *p_context = context;
217
218                         context->this = p_context;
219                         context->task = task;
220
221                         if (task)
222                                 set_tsk_thread_flag(task, TIF_DS_AREA_MSR);
223
224                         if (!task || (task == current))
225                                 wrmsrl(MSR_IA32_DS_AREA,
226                                        (unsigned long)context->ds);
227                 }
228                 spin_unlock_irqrestore(&ds_lock, irq);
229         }
230
231         context->count++;
232
233         return context;
234 }
235
236 static inline void ds_put_context(struct ds_context *context)
237 {
238         unsigned long irq;
239
240         if (!context)
241                 return;
242
243         spin_lock_irqsave(&ds_lock, irq);
244
245         if (--context->count)
246                 goto out;
247
248         *(context->this) = NULL;
249
250         if (context->task)
251                 clear_tsk_thread_flag(context->task, TIF_DS_AREA_MSR);
252
253         if (!context->task || (context->task == current))
254                 wrmsrl(MSR_IA32_DS_AREA, 0);
255
256         kfree(context);
257  out:
258         spin_unlock_irqrestore(&ds_lock, irq);
259 }
260
261
262 /*
263  * Handle a buffer overflow
264  *
265  * context: the ds context
266  * qual: the buffer type
267  */
268 static void ds_overflow(struct ds_context *context, enum ds_qualifier qual)
269 {
270         switch (qual) {
271         case ds_bts: {
272                 struct bts_tracer *tracer =
273                         container_of(context->owner[qual],
274                                      struct bts_tracer, ds);
275                 if (tracer->ovfl)
276                         tracer->ovfl(tracer);
277         }
278                 break;
279         case ds_pebs: {
280                 struct pebs_tracer *tracer =
281                         container_of(context->owner[qual],
282                                      struct pebs_tracer, ds);
283                 if (tracer->ovfl)
284                         tracer->ovfl(tracer);
285         }
286                 break;
287         }
288 }
289
290
291 static void ds_install_ds_config(struct ds_context *context,
292                                  enum ds_qualifier qual,
293                                  void *base, size_t size, size_t ith)
294 {
295         unsigned long buffer, adj;
296
297         /* adjust the buffer address and size to meet alignment
298          * constraints:
299          * - buffer is double-word aligned
300          * - size is multiple of record size
301          *
302          * We checked the size at the very beginning; we have enough
303          * space to do the adjustment.
304          */
305         buffer = (unsigned long)base;
306
307         adj = ALIGN(buffer, DS_ALIGNMENT) - buffer;
308         buffer += adj;
309         size   -= adj;
310
311         size /= ds_cfg.sizeof_rec[qual];
312         size *= ds_cfg.sizeof_rec[qual];
313
314         ds_set(context->ds, qual, ds_buffer_base, buffer);
315         ds_set(context->ds, qual, ds_index, buffer);
316         ds_set(context->ds, qual, ds_absolute_maximum, buffer + size);
317
318         /* The value for 'no threshold' is -1, which will set the
319          * threshold outside of the buffer, just like we want it.
320          */
321         ds_set(context->ds, qual,
322                ds_interrupt_threshold, buffer + size - ith);
323 }
324
325 static int ds_request(struct ds_tracer *tracer, enum ds_qualifier qual,
326                       struct task_struct *task,
327                       void *base, size_t size, size_t th)
328 {
329         struct ds_context *context;
330         unsigned long irq;
331         int error;
332
333         error = -EOPNOTSUPP;
334         if (!ds_cfg.sizeof_ds)
335                 goto out;
336
337         error = -EINVAL;
338         if (!base)
339                 goto out;
340
341         /* we require some space to do alignment adjustments below */
342         error = -EINVAL;
343         if (size < (DS_ALIGNMENT + ds_cfg.sizeof_rec[qual]))
344                 goto out;
345
346         if (th != (size_t)-1) {
347                 th *= ds_cfg.sizeof_rec[qual];
348
349                 error = -EINVAL;
350                 if (size <= th)
351                         goto out;
352         }
353
354         tracer->buffer = base;
355         tracer->size = size;
356
357         error = -ENOMEM;
358         context = ds_get_context(task);
359         if (!context)
360                 goto out;
361         tracer->context = context;
362
363
364         spin_lock_irqsave(&ds_lock, irq);
365
366         error = -EPERM;
367         if (!check_tracer(task))
368                 goto out_unlock;
369         get_tracer(task);
370
371         error = -EPERM;
372         if (context->owner[qual])
373                 goto out_put_tracer;
374         context->owner[qual] = tracer;
375
376         spin_unlock_irqrestore(&ds_lock, irq);
377
378
379         ds_install_ds_config(context, qual, base, size, th);
380
381         return 0;
382
383  out_put_tracer:
384         put_tracer(task);
385  out_unlock:
386         spin_unlock_irqrestore(&ds_lock, irq);
387         ds_put_context(context);
388         tracer->context = NULL;
389  out:
390         return error;
391 }
392
393 struct bts_tracer *ds_request_bts(struct task_struct *task,
394                                   void *base, size_t size,
395                                   bts_ovfl_callback_t ovfl, size_t th)
396 {
397         struct bts_tracer *tracer;
398         int error;
399
400         /* buffer overflow notification is not yet implemented */
401         error = -EOPNOTSUPP;
402         if (ovfl)
403                 goto out;
404
405         error = -ENOMEM;
406         tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
407         if (!tracer)
408                 goto out;
409         tracer->ovfl = ovfl;
410
411         error = ds_request(&tracer->ds, ds_bts, task, base, size, th);
412         if (error < 0)
413                 goto out_tracer;
414
415         return tracer;
416
417  out_tracer:
418         kfree(tracer);
419  out:
420         return ERR_PTR(error);
421 }
422
423 struct pebs_tracer *ds_request_pebs(struct task_struct *task,
424                                     void *base, size_t size,
425                                     pebs_ovfl_callback_t ovfl, size_t th)
426 {
427         struct pebs_tracer *tracer;
428         int error;
429
430         /* buffer overflow notification is not yet implemented */
431         error = -EOPNOTSUPP;
432         if (ovfl)
433                 goto out;
434
435         error = -ENOMEM;
436         tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
437         if (!tracer)
438                 goto out;
439         tracer->ovfl = ovfl;
440
441         error = ds_request(&tracer->ds, ds_pebs, task, base, size, th);
442         if (error < 0)
443                 goto out_tracer;
444
445         return tracer;
446
447  out_tracer:
448         kfree(tracer);
449  out:
450         return ERR_PTR(error);
451 }
452
453 static void ds_release(struct ds_tracer *tracer, enum ds_qualifier qual)
454 {
455         BUG_ON(tracer->context->owner[qual] != tracer);
456         tracer->context->owner[qual] = NULL;
457
458         put_tracer(tracer->context->task);
459         ds_put_context(tracer->context);
460 }
461
462 int ds_release_bts(struct bts_tracer *tracer)
463 {
464         if (!tracer)
465                 return -EINVAL;
466
467         ds_release(&tracer->ds, ds_bts);
468         kfree(tracer);
469
470         return 0;
471 }
472
473 int ds_release_pebs(struct pebs_tracer *tracer)
474 {
475         if (!tracer)
476                 return -EINVAL;
477
478         ds_release(&tracer->ds, ds_pebs);
479         kfree(tracer);
480
481         return 0;
482 }
483
484 static size_t ds_get_index(struct ds_context *context, enum ds_qualifier qual)
485 {
486         unsigned long base, index;
487
488         base  = ds_get(context->ds, qual, ds_buffer_base);
489         index = ds_get(context->ds, qual, ds_index);
490
491         return (index - base) / ds_cfg.sizeof_rec[qual];
492 }
493
494 int ds_get_bts_index(struct bts_tracer *tracer, size_t *pos)
495 {
496         if (!tracer)
497                 return -EINVAL;
498
499         if (!pos)
500                 return -EINVAL;
501
502         *pos = ds_get_index(tracer->ds.context, ds_bts);
503
504         return 0;
505 }
506
507 int ds_get_pebs_index(struct pebs_tracer *tracer, size_t *pos)
508 {
509         if (!tracer)
510                 return -EINVAL;
511
512         if (!pos)
513                 return -EINVAL;
514
515         *pos = ds_get_index(tracer->ds.context, ds_pebs);
516
517         return 0;
518 }
519
520 static size_t ds_get_end(struct ds_context *context, enum ds_qualifier qual)
521 {
522         unsigned long base, max;
523
524         base = ds_get(context->ds, qual, ds_buffer_base);
525         max  = ds_get(context->ds, qual, ds_absolute_maximum);
526
527         return (max - base) / ds_cfg.sizeof_rec[qual];
528 }
529
530 int ds_get_bts_end(struct bts_tracer *tracer, size_t *pos)
531 {
532         if (!tracer)
533                 return -EINVAL;
534
535         if (!pos)
536                 return -EINVAL;
537
538         *pos = ds_get_end(tracer->ds.context, ds_bts);
539
540         return 0;
541 }
542
543 int ds_get_pebs_end(struct pebs_tracer *tracer, size_t *pos)
544 {
545         if (!tracer)
546                 return -EINVAL;
547
548         if (!pos)
549                 return -EINVAL;
550
551         *pos = ds_get_end(tracer->ds.context, ds_pebs);
552
553         return 0;
554 }
555
556 static int ds_access(struct ds_context *context, enum ds_qualifier qual,
557                      size_t index, const void **record)
558 {
559         unsigned long base, idx;
560
561         if (!record)
562                 return -EINVAL;
563
564         base = ds_get(context->ds, qual, ds_buffer_base);
565         idx = base + (index * ds_cfg.sizeof_rec[qual]);
566
567         if (idx > ds_get(context->ds, qual, ds_absolute_maximum))
568                 return -EINVAL;
569
570         *record = (const void *)idx;
571
572         return ds_cfg.sizeof_rec[qual];
573 }
574
575 int ds_access_bts(struct bts_tracer *tracer, size_t index,
576                   const void **record)
577 {
578         if (!tracer)
579                 return -EINVAL;
580
581         return ds_access(tracer->ds.context, ds_bts, index, record);
582 }
583
584 int ds_access_pebs(struct pebs_tracer *tracer, size_t index,
585                    const void **record)
586 {
587         if (!tracer)
588                 return -EINVAL;
589
590         return ds_access(tracer->ds.context, ds_pebs, index, record);
591 }
592
593 static int ds_write(struct ds_context *context, enum ds_qualifier qual,
594                     const void *record, size_t size)
595 {
596         int bytes_written = 0;
597
598         if (!record)
599                 return -EINVAL;
600
601         while (size) {
602                 unsigned long base, index, end, write_end, int_th;
603                 unsigned long write_size, adj_write_size;
604
605                 /*
606                  * write as much as possible without producing an
607                  * overflow interrupt.
608                  *
609                  * interrupt_threshold must either be
610                  * - bigger than absolute_maximum or
611                  * - point to a record between buffer_base and absolute_maximum
612                  *
613                  * index points to a valid record.
614                  */
615                 base   = ds_get(context->ds, qual, ds_buffer_base);
616                 index  = ds_get(context->ds, qual, ds_index);
617                 end    = ds_get(context->ds, qual, ds_absolute_maximum);
618                 int_th = ds_get(context->ds, qual, ds_interrupt_threshold);
619
620                 write_end = min(end, int_th);
621
622                 /* if we are already beyond the interrupt threshold,
623                  * we fill the entire buffer */
624                 if (write_end <= index)
625                         write_end = end;
626
627                 if (write_end <= index)
628                         break;
629
630                 write_size = min((unsigned long) size, write_end - index);
631                 memcpy((void *)index, record, write_size);
632
633                 record = (const char *)record + write_size;
634                 size -= write_size;
635                 bytes_written += write_size;
636
637                 adj_write_size = write_size / ds_cfg.sizeof_rec[qual];
638                 adj_write_size *= ds_cfg.sizeof_rec[qual];
639
640                 /* zero out trailing bytes */
641                 memset((char *)index + write_size, 0,
642                        adj_write_size - write_size);
643                 index += adj_write_size;
644
645                 if (index >= end)
646                         index = base;
647                 ds_set(context->ds, qual, ds_index, index);
648
649                 if (index >= int_th)
650                         ds_overflow(context, qual);
651         }
652
653         return bytes_written;
654 }
655
656 int ds_write_bts(struct bts_tracer *tracer, const void *record, size_t size)
657 {
658         if (!tracer)
659                 return -EINVAL;
660
661         return ds_write(tracer->ds.context, ds_bts, record, size);
662 }
663
664 int ds_write_pebs(struct pebs_tracer *tracer, const void *record, size_t size)
665 {
666         if (!tracer)
667                 return -EINVAL;
668
669         return ds_write(tracer->ds.context, ds_pebs, record, size);
670 }
671
672 static void ds_reset_or_clear(struct ds_context *context,
673                               enum ds_qualifier qual, int clear)
674 {
675         unsigned long base, end;
676
677         base = ds_get(context->ds, qual, ds_buffer_base);
678         end  = ds_get(context->ds, qual, ds_absolute_maximum);
679
680         if (clear)
681                 memset((void *)base, 0, end - base);
682
683         ds_set(context->ds, qual, ds_index, base);
684 }
685
686 int ds_reset_bts(struct bts_tracer *tracer)
687 {
688         if (!tracer)
689                 return -EINVAL;
690
691         ds_reset_or_clear(tracer->ds.context, ds_bts, /* clear = */ 0);
692
693         return 0;
694 }
695
696 int ds_reset_pebs(struct pebs_tracer *tracer)
697 {
698         if (!tracer)
699                 return -EINVAL;
700
701         ds_reset_or_clear(tracer->ds.context, ds_pebs, /* clear = */ 0);
702
703         return 0;
704 }
705
706 int ds_clear_bts(struct bts_tracer *tracer)
707 {
708         if (!tracer)
709                 return -EINVAL;
710
711         ds_reset_or_clear(tracer->ds.context, ds_bts, /* clear = */ 1);
712
713         return 0;
714 }
715
716 int ds_clear_pebs(struct pebs_tracer *tracer)
717 {
718         if (!tracer)
719                 return -EINVAL;
720
721         ds_reset_or_clear(tracer->ds.context, ds_pebs, /* clear = */ 1);
722
723         return 0;
724 }
725
726 int ds_get_pebs_reset(struct pebs_tracer *tracer, u64 *value)
727 {
728         if (!tracer)
729                 return -EINVAL;
730
731         if (!value)
732                 return -EINVAL;
733
734         *value = *(u64 *)(tracer->ds.context->ds + (ds_cfg.sizeof_field * 8));
735
736         return 0;
737 }
738
739 int ds_set_pebs_reset(struct pebs_tracer *tracer, u64 value)
740 {
741         if (!tracer)
742                 return -EINVAL;
743
744         *(u64 *)(tracer->ds.context->ds + (ds_cfg.sizeof_field * 8)) = value;
745
746         return 0;
747 }
748
749 static const struct ds_configuration ds_cfg_var = {
750         .sizeof_ds    = sizeof(long) * 12,
751         .sizeof_field = sizeof(long),
752         .sizeof_rec[ds_bts]   = sizeof(long) * 3,
753 #ifdef __i386__
754         .sizeof_rec[ds_pebs]  = sizeof(long) * 10
755 #else
756         .sizeof_rec[ds_pebs]  = sizeof(long) * 18
757 #endif
758 };
759 static const struct ds_configuration ds_cfg_64 = {
760         .sizeof_ds    = 8 * 12,
761         .sizeof_field = 8,
762         .sizeof_rec[ds_bts]   = 8 * 3,
763 #ifdef __i386__
764         .sizeof_rec[ds_pebs]  = 8 * 10
765 #else
766         .sizeof_rec[ds_pebs]  = 8 * 18
767 #endif
768 };
769
770 static inline void
771 ds_configure(const struct ds_configuration *cfg)
772 {
773         ds_cfg = *cfg;
774
775         printk(KERN_INFO "DS available\n");
776
777         BUG_ON(MAX_SIZEOF_DS < ds_cfg.sizeof_ds);
778 }
779
780 void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
781 {
782         switch (c->x86) {
783         case 0x6:
784                 switch (c->x86_model) {
785                 case 0 ... 0xC:
786                         /* sorry, don't know about them */
787                         break;
788                 case 0xD:
789                 case 0xE: /* Pentium M */
790                         ds_configure(&ds_cfg_var);
791                         break;
792                 default: /* Core2, Atom, ... */
793                         ds_configure(&ds_cfg_64);
794                         break;
795                 }
796                 break;
797         case 0xF:
798                 switch (c->x86_model) {
799                 case 0x0:
800                 case 0x1:
801                 case 0x2: /* Netburst */
802                         ds_configure(&ds_cfg_var);
803                         break;
804                 default:
805                         /* sorry, don't know about them */
806                         break;
807                 }
808                 break;
809         default:
810                 /* sorry, don't know about them */
811                 break;
812         }
813 }
814
815 void ds_free(struct ds_context *context)
816 {
817         /* This is called when the task owning the parameter context
818          * is dying. There should not be any user of that context left
819          * to disturb us, anymore. */
820         unsigned long leftovers = context->count;
821         while (leftovers--) {
822                 put_tracer(context->task);
823                 ds_put_context(context);
824         }
825 }