aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/Kconfig.debug9
-rw-r--r--arch/x86/kernel/Makefile1
-rw-r--r--arch/x86/kernel/ds.c311
-rw-r--r--arch/x86/kernel/ds_selftest.c241
-rw-r--r--arch/x86/kernel/ds_selftest.h15
5 files changed, 449 insertions, 128 deletions
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index d8359e73317f..22b752e09487 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -167,6 +167,15 @@ config IOMMU_LEAK
167 Add a simple leak tracer to the IOMMU code. This is useful when you 167 Add a simple leak tracer to the IOMMU code. This is useful when you
168 are debugging a buggy device driver that leaks IOMMU mappings. 168 are debugging a buggy device driver that leaks IOMMU mappings.
169 169
170config X86_DS_SELFTEST
171 bool "DS selftest"
172 default y
173 depends on DEBUG_KERNEL
174 depends on X86_DS
175 ---help---
176 Perform Debug Store selftests at boot time.
177 If in doubt, say "N".
178
170config HAVE_MMIOTRACE_SUPPORT 179config HAVE_MMIOTRACE_SUPPORT
171 def_bool y 180 def_bool y
172 181
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 145cce75cda7..77df4d654ff9 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -44,6 +44,7 @@ obj-y += process.o
44obj-y += i387.o xsave.o 44obj-y += i387.o xsave.o
45obj-y += ptrace.o 45obj-y += ptrace.o
46obj-$(CONFIG_X86_DS) += ds.o 46obj-$(CONFIG_X86_DS) += ds.o
47obj-$(CONFIG_X86_DS_SELFTEST) += ds_selftest.o
47obj-$(CONFIG_X86_32) += tls.o 48obj-$(CONFIG_X86_32) += tls.o
48obj-$(CONFIG_IA32_EMULATION) += tls.o 49obj-$(CONFIG_IA32_EMULATION) += tls.o
49obj-y += step.o 50obj-y += step.o
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c
index 87b67e3a765a..b1d6e1f502fa 100644
--- a/arch/x86/kernel/ds.c
+++ b/arch/x86/kernel/ds.c
@@ -19,45 +19,52 @@
19 * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009 19 * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
20 */ 20 */
21 21
22 22#include <linux/kernel.h>
23#include <asm/ds.h>
24
25#include <linux/errno.h>
26#include <linux/string.h> 23#include <linux/string.h>
27#include <linux/slab.h> 24#include <linux/errno.h>
28#include <linux/sched.h> 25#include <linux/sched.h>
26#include <linux/slab.h>
29#include <linux/mm.h> 27#include <linux/mm.h>
30#include <linux/kernel.h>
31 28
29#include <asm/ds.h>
30
31#include "ds_selftest.h"
32 32
33/* 33/*
34 * The configuration for a particular DS hardware implementation. 34 * The configuration for a particular DS hardware implementation:
35 */ 35 */
36struct ds_configuration { 36struct ds_configuration {
37 /* the name of the configuration */ 37 /* The name of the configuration: */
38 const char *name; 38 const char *name;
39 /* the size of one pointer-typed field in the DS structure and 39
40 in the BTS and PEBS buffers in bytes; 40 /* The size of pointer-typed fields in DS, BTS, and PEBS: */
41 this covers the first 8 DS fields related to buffer management. */ 41 unsigned char sizeof_ptr_field;
42 unsigned char sizeof_field; 42
43 /* the size of a BTS/PEBS record in bytes */ 43 /* The size of a BTS/PEBS record in bytes: */
44 unsigned char sizeof_rec[2]; 44 unsigned char sizeof_rec[2];
45 /* a series of bit-masks to control various features indexed 45
46 * by enum ds_feature */ 46 /* Control bit-masks indexed by enum ds_feature: */
47 unsigned long ctl[dsf_ctl_max]; 47 unsigned long ctl[dsf_ctl_max];
48}; 48};
49static DEFINE_PER_CPU(struct ds_configuration, ds_cfg_array); 49static DEFINE_PER_CPU(struct ds_configuration, ds_cfg_array);
50 50
51#define ds_cfg per_cpu(ds_cfg_array, smp_processor_id()) 51#define ds_cfg per_cpu(ds_cfg_array, smp_processor_id())
52 52
53#define MAX_SIZEOF_DS (12 * 8) /* maximal size of a DS configuration */ 53/* Maximal size of a DS configuration: */
54#define MAX_SIZEOF_BTS (3 * 8) /* maximal size of a BTS record */ 54#define MAX_SIZEOF_DS (12 * 8)
55#define DS_ALIGNMENT (1 << 3) /* BTS and PEBS buffer alignment */ 55
56/* Maximal size of a BTS record: */
57#define MAX_SIZEOF_BTS (3 * 8)
56 58
57#define BTS_CONTROL \ 59/* BTS and PEBS buffer alignment: */
58 (ds_cfg.ctl[dsf_bts] | ds_cfg.ctl[dsf_bts_kernel] | ds_cfg.ctl[dsf_bts_user] |\ 60#define DS_ALIGNMENT (1 << 3)
59 ds_cfg.ctl[dsf_bts_overflow])
60 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] )
61 68
62/* 69/*
63 * A BTS or PEBS tracer. 70 * A BTS or PEBS tracer.
@@ -66,29 +73,33 @@ static DEFINE_PER_CPU(struct ds_configuration, ds_cfg_array);
66 * to identify tracers. 73 * to identify tracers.
67 */ 74 */
68struct ds_tracer { 75struct ds_tracer {
69 /* the DS context (partially) owned by this tracer */ 76 /* The DS context (partially) owned by this tracer. */
70 struct ds_context *context; 77 struct ds_context *context;
71 /* the buffer provided on ds_request() and its size in bytes */ 78 /* The buffer provided on ds_request() and its size in bytes. */
72 void *buffer; 79 void *buffer;
73 size_t size; 80 size_t size;
74}; 81};
75 82
76struct bts_tracer { 83struct bts_tracer {
77 /* the common DS part */ 84 /* The common DS part: */
78 struct ds_tracer ds; 85 struct ds_tracer ds;
79 /* the trace including the DS configuration */ 86
80 struct bts_trace trace; 87 /* The trace including the DS configuration: */
81 /* buffer overflow notification function */ 88 struct bts_trace trace;
82 bts_ovfl_callback_t ovfl; 89
90 /* Buffer overflow notification function: */
91 bts_ovfl_callback_t ovfl;
83}; 92};
84 93
85struct pebs_tracer { 94struct pebs_tracer {
86 /* the common DS part */ 95 /* The common DS part: */
87 struct ds_tracer ds; 96 struct ds_tracer ds;
88 /* the trace including the DS configuration */ 97
89 struct pebs_trace trace; 98 /* The trace including the DS configuration: */
90 /* buffer overflow notification function */ 99 struct pebs_trace trace;
91 pebs_ovfl_callback_t ovfl; 100
101 /* Buffer overflow notification function: */
102 pebs_ovfl_callback_t ovfl;
92}; 103};
93 104
94/* 105/*
@@ -97,6 +108,7 @@ struct pebs_tracer {
97 * 108 *
98 * The DS configuration consists of the following fields; different 109 * The DS configuration consists of the following fields; different
99 * architetures vary in the size of those fields. 110 * architetures vary in the size of those fields.
111 *
100 * - double-word aligned base linear address of the BTS buffer 112 * - double-word aligned base linear address of the BTS buffer
101 * - write pointer into the BTS buffer 113 * - write pointer into the BTS buffer
102 * - end linear address of the BTS buffer (one byte beyond the end of 114 * - end linear address of the BTS buffer (one byte beyond the end of
@@ -135,21 +147,22 @@ enum ds_field {
135}; 147};
136 148
137enum ds_qualifier { 149enum ds_qualifier {
138 ds_bts = 0, 150 ds_bts = 0,
139 ds_pebs 151 ds_pebs
140}; 152};
141 153
142static inline unsigned long ds_get(const unsigned char *base, 154static inline unsigned long
143 enum ds_qualifier qual, enum ds_field field) 155ds_get(const unsigned char *base, enum ds_qualifier qual, enum ds_field field)
144{ 156{
145 base += (ds_cfg.sizeof_field * (field + (4 * qual))); 157 base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
146 return *(unsigned long *)base; 158 return *(unsigned long *)base;
147} 159}
148 160
149static inline void ds_set(unsigned char *base, enum ds_qualifier qual, 161static inline void
150 enum ds_field field, unsigned long value) 162ds_set(unsigned char *base, enum ds_qualifier qual, enum ds_field field,
163 unsigned long value)
151{ 164{
152 base += (ds_cfg.sizeof_field * (field + (4 * qual))); 165 base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
153 (*(unsigned long *)base) = value; 166 (*(unsigned long *)base) = value;
154} 167}
155 168
@@ -159,7 +172,6 @@ static inline void ds_set(unsigned char *base, enum ds_qualifier qual,
159 */ 172 */
160static DEFINE_SPINLOCK(ds_lock); 173static DEFINE_SPINLOCK(ds_lock);
161 174
162
163/* 175/*
164 * We either support (system-wide) per-cpu or per-thread allocation. 176 * We either support (system-wide) per-cpu or per-thread allocation.
165 * We distinguish the two based on the task_struct pointer, where a 177 * We distinguish the two based on the task_struct pointer, where a
@@ -213,19 +225,21 @@ static inline int check_tracer(struct task_struct *task)
213 * deallocated when the last user puts the context. 225 * deallocated when the last user puts the context.
214 */ 226 */
215struct ds_context { 227struct ds_context {
216 /* pointer to the DS configuration; goes into MSR_IA32_DS_AREA */ 228 /* The DS configuration; goes into MSR_IA32_DS_AREA: */
217 unsigned char ds[MAX_SIZEOF_DS]; 229 unsigned char ds[MAX_SIZEOF_DS];
218 /* the owner of the BTS and PEBS configuration, respectively */ 230
219 struct bts_tracer *bts_master; 231 /* The owner of the BTS and PEBS configuration, respectively: */
220 struct pebs_tracer *pebs_master; 232 struct bts_tracer *bts_master;
221 /* use count */ 233 struct pebs_tracer *pebs_master;
234
235 /* Use count: */
222 unsigned long count; 236 unsigned long count;
223 /* a pointer to the context location inside the thread_struct 237
224 * or the per_cpu context array */ 238 /* Pointer to the context pointer field: */
225 struct ds_context **this; 239 struct ds_context **this;
226 /* a pointer to the task owning this context, or NULL, if the 240
227 * context is owned by a cpu */ 241 /* The traced task; NULL for current cpu: */
228 struct task_struct *task; 242 struct task_struct *task;
229}; 243};
230 244
231static DEFINE_PER_CPU(struct ds_context *, system_context_array); 245static DEFINE_PER_CPU(struct ds_context *, system_context_array);
@@ -241,8 +255,13 @@ static inline struct ds_context *ds_get_context(struct task_struct *task)
241 struct ds_context *new_context = NULL; 255 struct ds_context *new_context = NULL;
242 unsigned long irq; 256 unsigned long irq;
243 257
244 /* Chances are small that we already have a context. */ 258 /*
245 new_context = kzalloc(sizeof(*new_context), GFP_KERNEL); 259 * Chances are small that we already have a context.
260 *
261 * Contexts for per-cpu tracing are allocated using
262 * smp_call_function(). We must not sleep.
263 */
264 new_context = kzalloc(sizeof(*new_context), GFP_ATOMIC);
246 if (!new_context) 265 if (!new_context)
247 return NULL; 266 return NULL;
248 267
@@ -332,9 +351,9 @@ static void ds_overflow(struct ds_context *context, enum ds_qualifier qual)
332 * The remainder of any partially written record is zeroed out. 351 * The remainder of any partially written record is zeroed out.
333 * 352 *
334 * context: the DS context 353 * context: the DS context
335 * qual: the buffer type 354 * qual: the buffer type
336 * record: the data to write 355 * record: the data to write
337 * size: the size of the data 356 * size: the size of the data
338 */ 357 */
339static int ds_write(struct ds_context *context, enum ds_qualifier qual, 358static int ds_write(struct ds_context *context, enum ds_qualifier qual,
340 const void *record, size_t size) 359 const void *record, size_t size)
@@ -349,14 +368,14 @@ static int ds_write(struct ds_context *context, enum ds_qualifier qual,
349 unsigned long write_size, adj_write_size; 368 unsigned long write_size, adj_write_size;
350 369
351 /* 370 /*
352 * write as much as possible without producing an 371 * Write as much as possible without producing an
353 * overflow interrupt. 372 * overflow interrupt.
354 * 373 *
355 * interrupt_threshold must either be 374 * Interrupt_threshold must either be
356 * - bigger than absolute_maximum or 375 * - bigger than absolute_maximum or
357 * - point to a record between buffer_base and absolute_maximum 376 * - point to a record between buffer_base and absolute_maximum
358 * 377 *
359 * index points to a valid record. 378 * Index points to a valid record.
360 */ 379 */
361 base = ds_get(context->ds, qual, ds_buffer_base); 380 base = ds_get(context->ds, qual, ds_buffer_base);
362 index = ds_get(context->ds, qual, ds_index); 381 index = ds_get(context->ds, qual, ds_index);
@@ -365,8 +384,10 @@ static int ds_write(struct ds_context *context, enum ds_qualifier qual,
365 384
366 write_end = min(end, int_th); 385 write_end = min(end, int_th);
367 386
368 /* if we are already beyond the interrupt threshold, 387 /*
369 * we fill the entire buffer */ 388 * If we are already beyond the interrupt threshold,
389 * we fill the entire buffer.
390 */
370 if (write_end <= index) 391 if (write_end <= index)
371 write_end = end; 392 write_end = end;
372 393
@@ -383,7 +404,7 @@ static int ds_write(struct ds_context *context, enum ds_qualifier qual,
383 adj_write_size = write_size / ds_cfg.sizeof_rec[qual]; 404 adj_write_size = write_size / ds_cfg.sizeof_rec[qual];
384 adj_write_size *= ds_cfg.sizeof_rec[qual]; 405 adj_write_size *= ds_cfg.sizeof_rec[qual];
385 406
386 /* zero out trailing bytes */ 407 /* Zero out trailing bytes. */
387 memset((char *)index + write_size, 0, 408 memset((char *)index + write_size, 0,
388 adj_write_size - write_size); 409 adj_write_size - write_size);
389 index += adj_write_size; 410 index += adj_write_size;
@@ -410,7 +431,7 @@ static int ds_write(struct ds_context *context, enum ds_qualifier qual,
410 * Later architectures use 64bit pointers throughout, whereas earlier 431 * Later architectures use 64bit pointers throughout, whereas earlier
411 * architectures use 32bit pointers in 32bit mode. 432 * architectures use 32bit pointers in 32bit mode.
412 * 433 *
413 * We compute the base address for the first 8 fields based on: 434 * We compute the base address for the fields based on:
414 * - the field size stored in the DS configuration 435 * - the field size stored in the DS configuration
415 * - the relative field position 436 * - the relative field position
416 * 437 *
@@ -431,23 +452,23 @@ enum bts_field {
431 bts_to, 452 bts_to,
432 bts_flags, 453 bts_flags,
433 454
434 bts_qual = bts_from, 455 bts_qual = bts_from,
435 bts_jiffies = bts_to, 456 bts_jiffies = bts_to,
436 bts_pid = bts_flags, 457 bts_pid = bts_flags,
437 458
438 bts_qual_mask = (bts_qual_max - 1), 459 bts_qual_mask = (bts_qual_max - 1),
439 bts_escape = ((unsigned long)-1 & ~bts_qual_mask) 460 bts_escape = ((unsigned long)-1 & ~bts_qual_mask)
440}; 461};
441 462
442static inline unsigned long bts_get(const char *base, enum bts_field field) 463static inline unsigned long bts_get(const char *base, enum bts_field field)
443{ 464{
444 base += (ds_cfg.sizeof_field * field); 465 base += (ds_cfg.sizeof_ptr_field * field);
445 return *(unsigned long *)base; 466 return *(unsigned long *)base;
446} 467}
447 468
448static inline void bts_set(char *base, enum bts_field field, unsigned long val) 469static inline void bts_set(char *base, enum bts_field field, unsigned long val)
449{ 470{
450 base += (ds_cfg.sizeof_field * field);; 471 base += (ds_cfg.sizeof_ptr_field * field);;
451 (*(unsigned long *)base) = val; 472 (*(unsigned long *)base) = val;
452} 473}
453 474
@@ -463,8 +484,8 @@ static inline void bts_set(char *base, enum bts_field field, unsigned long val)
463 * 484 *
464 * return: bytes read/written on success; -Eerrno, otherwise 485 * return: bytes read/written on success; -Eerrno, otherwise
465 */ 486 */
466static int bts_read(struct bts_tracer *tracer, const void *at, 487static int
467 struct bts_struct *out) 488bts_read(struct bts_tracer *tracer, const void *at, struct bts_struct *out)
468{ 489{
469 if (!tracer) 490 if (!tracer)
470 return -EINVAL; 491 return -EINVAL;
@@ -555,7 +576,8 @@ static void ds_init_ds_trace(struct ds_trace *trace, enum ds_qualifier qual,
555 unsigned int flags) { 576 unsigned int flags) {
556 unsigned long buffer, adj; 577 unsigned long buffer, adj;
557 578
558 /* adjust the buffer address and size to meet alignment 579 /*
580 * Adjust the buffer address and size to meet alignment
559 * constraints: 581 * constraints:
560 * - buffer is double-word aligned 582 * - buffer is double-word aligned
561 * - size is multiple of record size 583 * - size is multiple of record size
@@ -577,7 +599,8 @@ static void ds_init_ds_trace(struct ds_trace *trace, enum ds_qualifier qual,
577 trace->begin = (void *)buffer; 599 trace->begin = (void *)buffer;
578 trace->top = trace->begin; 600 trace->top = trace->begin;
579 trace->end = (void *)(buffer + size); 601 trace->end = (void *)(buffer + size);
580 /* The value for 'no threshold' is -1, which will set the 602 /*
603 * The value for 'no threshold' is -1, which will set the
581 * threshold outside of the buffer, just like we want it. 604 * threshold outside of the buffer, just like we want it.
582 */ 605 */
583 trace->ith = (void *)(buffer + size - ith); 606 trace->ith = (void *)(buffer + size - ith);
@@ -593,11 +616,15 @@ static int ds_request(struct ds_tracer *tracer, struct ds_trace *trace,
593 struct ds_context *context; 616 struct ds_context *context;
594 int error; 617 int error;
595 618
619 error = -EOPNOTSUPP;
620 if (!ds_cfg.sizeof_rec[qual])
621 goto out;
622
596 error = -EINVAL; 623 error = -EINVAL;
597 if (!base) 624 if (!base)
598 goto out; 625 goto out;
599 626
600 /* we require some space to do alignment adjustments below */ 627 /* We require some space to do alignment adjustments below. */
601 error = -EINVAL; 628 error = -EINVAL;
602 if (size < (DS_ALIGNMENT + ds_cfg.sizeof_rec[qual])) 629 if (size < (DS_ALIGNMENT + ds_cfg.sizeof_rec[qual]))
603 goto out; 630 goto out;
@@ -635,17 +662,17 @@ struct bts_tracer *ds_request_bts(struct task_struct *task,
635 unsigned long irq; 662 unsigned long irq;
636 int error; 663 int error;
637 664
638 error = -EOPNOTSUPP; 665 /* Buffer overflow notification is not yet implemented. */
639 if (!ds_cfg.ctl[dsf_bts])
640 goto out;
641
642 /* buffer overflow notification is not yet implemented */
643 error = -EOPNOTSUPP; 666 error = -EOPNOTSUPP;
644 if (ovfl) 667 if (ovfl)
645 goto out; 668 goto out;
646 669
670 /*
671 * Per-cpu tracing is typically requested using smp_call_function().
672 * We must not sleep.
673 */
647 error = -ENOMEM; 674 error = -ENOMEM;
648 tracer = kzalloc(sizeof(*tracer), GFP_KERNEL); 675 tracer = kzalloc(sizeof(*tracer), GFP_ATOMIC);
649 if (!tracer) 676 if (!tracer)
650 goto out; 677 goto out;
651 tracer->ovfl = ovfl; 678 tracer->ovfl = ovfl;
@@ -699,13 +726,17 @@ struct pebs_tracer *ds_request_pebs(struct task_struct *task,
699 unsigned long irq; 726 unsigned long irq;
700 int error; 727 int error;
701 728
702 /* buffer overflow notification is not yet implemented */ 729 /* Buffer overflow notification is not yet implemented. */
703 error = -EOPNOTSUPP; 730 error = -EOPNOTSUPP;
704 if (ovfl) 731 if (ovfl)
705 goto out; 732 goto out;
706 733
734 /*
735 * Per-cpu tracing is typically requested using smp_call_function().
736 * We must not sleep.
737 */
707 error = -ENOMEM; 738 error = -ENOMEM;
708 tracer = kzalloc(sizeof(*tracer), GFP_KERNEL); 739 tracer = kzalloc(sizeof(*tracer), GFP_ATOMIC);
709 if (!tracer) 740 if (!tracer)
710 goto out; 741 goto out;
711 tracer->ovfl = ovfl; 742 tracer->ovfl = ovfl;
@@ -848,7 +879,8 @@ const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer)
848 879
849 ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_pebs); 880 ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
850 tracer->trace.reset_value = 881 tracer->trace.reset_value =
851 *(u64 *)(tracer->ds.context->ds + (ds_cfg.sizeof_field * 8)); 882 *(u64 *)(tracer->ds.context->ds +
883 (ds_cfg.sizeof_ptr_field * 8));
852 884
853 return &tracer->trace; 885 return &tracer->trace;
854} 886}
@@ -884,7 +916,8 @@ int ds_set_pebs_reset(struct pebs_tracer *tracer, u64 value)
884 if (!tracer) 916 if (!tracer)
885 return -EINVAL; 917 return -EINVAL;
886 918
887 *(u64 *)(tracer->ds.context->ds + (ds_cfg.sizeof_field * 8)) = value; 919 *(u64 *)(tracer->ds.context->ds +
920 (ds_cfg.sizeof_ptr_field * 8)) = value;
888 921
889 return 0; 922 return 0;
890} 923}
@@ -894,54 +927,76 @@ static const struct ds_configuration ds_cfg_netburst = {
894 .ctl[dsf_bts] = (1 << 2) | (1 << 3), 927 .ctl[dsf_bts] = (1 << 2) | (1 << 3),
895 .ctl[dsf_bts_kernel] = (1 << 5), 928 .ctl[dsf_bts_kernel] = (1 << 5),
896 .ctl[dsf_bts_user] = (1 << 6), 929 .ctl[dsf_bts_user] = (1 << 6),
897
898 .sizeof_field = sizeof(long),
899 .sizeof_rec[ds_bts] = sizeof(long) * 3,
900#ifdef __i386__
901 .sizeof_rec[ds_pebs] = sizeof(long) * 10,
902#else
903 .sizeof_rec[ds_pebs] = sizeof(long) * 18,
904#endif
905}; 930};
906static const struct ds_configuration ds_cfg_pentium_m = { 931static const struct ds_configuration ds_cfg_pentium_m = {
907 .name = "Pentium M", 932 .name = "Pentium M",
908 .ctl[dsf_bts] = (1 << 6) | (1 << 7), 933 .ctl[dsf_bts] = (1 << 6) | (1 << 7),
909
910 .sizeof_field = sizeof(long),
911 .sizeof_rec[ds_bts] = sizeof(long) * 3,
912#ifdef __i386__
913 .sizeof_rec[ds_pebs] = sizeof(long) * 10,
914#else
915 .sizeof_rec[ds_pebs] = sizeof(long) * 18,
916#endif
917}; 934};
918static const struct ds_configuration ds_cfg_core2_atom = { 935static const struct ds_configuration ds_cfg_core2_atom = {
919 .name = "Core 2/Atom", 936 .name = "Core 2/Atom",
920 .ctl[dsf_bts] = (1 << 6) | (1 << 7), 937 .ctl[dsf_bts] = (1 << 6) | (1 << 7),
921 .ctl[dsf_bts_kernel] = (1 << 9), 938 .ctl[dsf_bts_kernel] = (1 << 9),
922 .ctl[dsf_bts_user] = (1 << 10), 939 .ctl[dsf_bts_user] = (1 << 10),
923
924 .sizeof_field = 8,
925 .sizeof_rec[ds_bts] = 8 * 3,
926 .sizeof_rec[ds_pebs] = 8 * 18,
927}; 940};
928 941
929static void 942static void
930ds_configure(const struct ds_configuration *cfg) 943ds_configure(const struct ds_configuration *cfg,
944 struct cpuinfo_x86 *cpu)
931{ 945{
946 unsigned long nr_pebs_fields = 0;
947
948 printk(KERN_INFO "[ds] using %s configuration\n", cfg->name);
949
950#ifdef __i386__
951 nr_pebs_fields = 10;
952#else
953 nr_pebs_fields = 18;
954#endif
955
932 memset(&ds_cfg, 0, sizeof(ds_cfg)); 956 memset(&ds_cfg, 0, sizeof(ds_cfg));
933 ds_cfg = *cfg; 957 ds_cfg = *cfg;
934 958
935 printk(KERN_INFO "[ds] using %s configuration\n", ds_cfg.name); 959 ds_cfg.sizeof_ptr_field =
960 (cpu_has(cpu, X86_FEATURE_DTES64) ? 8 : 4);
961
962 ds_cfg.sizeof_rec[ds_bts] = ds_cfg.sizeof_ptr_field * 3;
963 ds_cfg.sizeof_rec[ds_pebs] = ds_cfg.sizeof_ptr_field * nr_pebs_fields;
936 964
937 if (!cpu_has_bts) { 965 if (!cpu_has(cpu, X86_FEATURE_BTS)) {
938 ds_cfg.ctl[dsf_bts] = 0; 966 ds_cfg.sizeof_rec[ds_bts] = 0;
939 printk(KERN_INFO "[ds] bts not available\n"); 967 printk(KERN_INFO "[ds] bts not available\n");
940 } 968 }
941 if (!cpu_has_pebs) 969 if (!cpu_has(cpu, X86_FEATURE_PEBS)) {
970 ds_cfg.sizeof_rec[ds_pebs] = 0;
942 printk(KERN_INFO "[ds] pebs not available\n"); 971 printk(KERN_INFO "[ds] pebs not available\n");
972 }
973
974 if (ds_cfg.sizeof_rec[ds_bts]) {
975 int error;
976
977 error = ds_selftest_bts();
978 if (error) {
979 WARN(1, "[ds] selftest failed. disabling bts.\n");
980 ds_cfg.sizeof_rec[ds_bts] = 0;
981 }
982 }
983
984 if (ds_cfg.sizeof_rec[ds_pebs]) {
985 int error;
986
987 error = ds_selftest_pebs();
988 if (error) {
989 WARN(1, "[ds] selftest failed. disabling pebs.\n");
990 ds_cfg.sizeof_rec[ds_pebs] = 0;
991 }
992 }
993
994 printk(KERN_INFO "[ds] sizes: address: %u bit, ",
995 8 * ds_cfg.sizeof_ptr_field);
996 printk("bts/pebs record: %u/%u bytes\n",
997 ds_cfg.sizeof_rec[ds_bts], ds_cfg.sizeof_rec[ds_pebs]);
943 998
944 WARN_ON_ONCE(MAX_SIZEOF_DS < (12 * ds_cfg.sizeof_field)); 999 WARN_ON_ONCE(MAX_SIZEOF_DS < (12 * ds_cfg.sizeof_ptr_field));
945} 1000}
946 1001
947void __cpuinit ds_init_intel(struct cpuinfo_x86 *c) 1002void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
@@ -951,16 +1006,16 @@ void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
951 switch (c->x86_model) { 1006 switch (c->x86_model) {
952 case 0x9: 1007 case 0x9:
953 case 0xd: /* Pentium M */ 1008 case 0xd: /* Pentium M */
954 ds_configure(&ds_cfg_pentium_m); 1009 ds_configure(&ds_cfg_pentium_m, c);
955 break; 1010 break;
956 case 0xf: 1011 case 0xf:
957 case 0x17: /* Core2 */ 1012 case 0x17: /* Core2 */
958 case 0x1c: /* Atom */ 1013 case 0x1c: /* Atom */
959 ds_configure(&ds_cfg_core2_atom); 1014 ds_configure(&ds_cfg_core2_atom, c);
960 break; 1015 break;
961 case 0x1a: /* i7 */ 1016 case 0x1a: /* Core i7 */
962 default: 1017 default:
963 /* sorry, don't know about them */ 1018 /* Sorry, don't know about them. */
964 break; 1019 break;
965 } 1020 }
966 break; 1021 break;
@@ -969,15 +1024,15 @@ void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
969 case 0x0: 1024 case 0x0:
970 case 0x1: 1025 case 0x1:
971 case 0x2: /* Netburst */ 1026 case 0x2: /* Netburst */
972 ds_configure(&ds_cfg_netburst); 1027 ds_configure(&ds_cfg_netburst, c);
973 break; 1028 break;
974 default: 1029 default:
975 /* sorry, don't know about them */ 1030 /* Sorry, don't know about them. */
976 break; 1031 break;
977 } 1032 }
978 break; 1033 break;
979 default: 1034 default:
980 /* sorry, don't know about them */ 1035 /* Sorry, don't know about them. */
981 break; 1036 break;
982 } 1037 }
983} 1038}
diff --git a/arch/x86/kernel/ds_selftest.c b/arch/x86/kernel/ds_selftest.c
new file mode 100644
index 000000000000..8c46fbf38c46
--- /dev/null
+++ b/arch/x86/kernel/ds_selftest.c
@@ -0,0 +1,241 @@
1/*
2 * Debug Store support - selftest
3 *
4 *
5 * Copyright (C) 2009 Intel Corporation.
6 * Markus Metzger <markus.t.metzger@intel.com>, 2009
7 */
8
9#include "ds_selftest.h"
10
11#include <linux/kernel.h>
12#include <linux/string.h>
13
14#include <asm/ds.h>
15
16
17#define DS_SELFTEST_BUFFER_SIZE 1021 /* Intentionally chose an odd size. */
18
19
20static int ds_selftest_bts_consistency(const struct bts_trace *trace)
21{
22 int error = 0;
23
24 if (!trace) {
25 printk(KERN_CONT "failed to access trace...");
26 /* Bail out. Other tests are pointless. */
27 return -1;
28 }
29
30 if (!trace->read) {
31 printk(KERN_CONT "bts read not available...");
32 error = -1;
33 }
34
35 /* Do some sanity checks on the trace configuration. */
36 if (!trace->ds.n) {
37 printk(KERN_CONT "empty bts buffer...");
38 error = -1;
39 }
40 if (!trace->ds.size) {
41 printk(KERN_CONT "bad bts trace setup...");
42 error = -1;
43 }
44 if (trace->ds.end !=
45 (char *)trace->ds.begin + (trace->ds.n * trace->ds.size)) {
46 printk(KERN_CONT "bad bts buffer setup...");
47 error = -1;
48 }
49 if ((trace->ds.top < trace->ds.begin) ||
50 (trace->ds.end <= trace->ds.top)) {
51 printk(KERN_CONT "bts top out of bounds...");
52 error = -1;
53 }
54
55 return error;
56}
57
58static int ds_selftest_bts_read(struct bts_tracer *tracer,
59 const struct bts_trace *trace,
60 const void *from, const void *to)
61{
62 const unsigned char *at;
63
64 /*
65 * Check a few things which do not belong to this test.
66 * They should be covered by other tests.
67 */
68 if (!trace)
69 return -1;
70
71 if (!trace->read)
72 return -1;
73
74 if (to < from)
75 return -1;
76
77 if (from < trace->ds.begin)
78 return -1;
79
80 if (trace->ds.end < to)
81 return -1;
82
83 if (!trace->ds.size)
84 return -1;
85
86 /* Now to the test itself. */
87 for (at = from; (void *)at < to; at += trace->ds.size) {
88 struct bts_struct bts;
89 size_t index;
90 int error;
91
92 if (((void *)at - trace->ds.begin) % trace->ds.size) {
93 printk(KERN_CONT
94 "read from non-integer index...");
95 return -1;
96 }
97 index = ((void *)at - trace->ds.begin) / trace->ds.size;
98
99 memset(&bts, 0, sizeof(bts));
100 error = trace->read(tracer, at, &bts);
101 if (error < 0) {
102 printk(KERN_CONT
103 "error reading bts trace at [%lu] (0x%p)...",
104 index, at);
105 return error;
106 }
107
108 switch (bts.qualifier) {
109 case BTS_BRANCH:
110 break;
111 default:
112 printk(KERN_CONT
113 "unexpected bts entry %llu at [%lu] (0x%p)...",
114 bts.qualifier, index, at);
115 return -1;
116 }
117 }
118
119 return 0;
120}
121
122int ds_selftest_bts(void)
123{
124 const struct bts_trace *trace;
125 struct bts_tracer *tracer;
126 int error = 0;
127 void *top;
128 unsigned char buffer[DS_SELFTEST_BUFFER_SIZE];
129
130 printk(KERN_INFO "[ds] bts selftest...");
131
132 tracer = ds_request_bts(NULL, buffer, DS_SELFTEST_BUFFER_SIZE,
133 NULL, (size_t)-1, BTS_KERNEL);
134 if (IS_ERR(tracer)) {
135 error = PTR_ERR(tracer);
136 tracer = NULL;
137
138 printk(KERN_CONT
139 "initialization failed (err: %d)...", error);
140 goto out;
141 }
142
143 /* The return should already give us enough trace. */
144 ds_suspend_bts(tracer);
145
146 /* Let's see if we can access the trace. */
147 trace = ds_read_bts(tracer);
148
149 error = ds_selftest_bts_consistency(trace);
150 if (error < 0)
151 goto out;
152
153 /* If everything went well, we should have a few trace entries. */
154 if (trace->ds.top == trace->ds.begin) {
155 /*
156 * It is possible but highly unlikely that we got a
157 * buffer overflow and end up at exactly the same
158 * position we started from.
159 * Let's issue a warning, but continue.
160 */
161 printk(KERN_CONT "no trace/overflow...");
162 }
163
164 /* Let's try to read the trace we collected. */
165 error = ds_selftest_bts_read(tracer, trace,
166 trace->ds.begin, trace->ds.top);
167 if (error < 0)
168 goto out;
169
170 /*
171 * Let's read the trace again.
172 * Since we suspended tracing, we should get the same result.
173 */
174 top = trace->ds.top;
175
176 trace = ds_read_bts(tracer);
177 error = ds_selftest_bts_consistency(trace);
178 if (error < 0)
179 goto out;
180
181 if (top != trace->ds.top) {
182 printk(KERN_CONT "suspend not working...");
183 error = -1;
184 goto out;
185 }
186
187 /* Let's collect some more trace - see if resume is working. */
188 ds_resume_bts(tracer);
189 ds_suspend_bts(tracer);
190
191 trace = ds_read_bts(tracer);
192
193 error = ds_selftest_bts_consistency(trace);
194 if (error < 0)
195 goto out;
196
197 if (trace->ds.top == top) {
198 /*
199 * It is possible but highly unlikely that we got a
200 * buffer overflow and end up at exactly the same
201 * position we started from.
202 * Let's issue a warning and check the full trace.
203 */
204 printk(KERN_CONT
205 "no resume progress/overflow...");
206
207 error = ds_selftest_bts_read(tracer, trace,
208 trace->ds.begin, trace->ds.end);
209 } else if (trace->ds.top < top) {
210 /*
211 * We had a buffer overflow - the entire buffer should
212 * contain trace records.
213 */
214 error = ds_selftest_bts_read(tracer, trace,
215 trace->ds.begin, trace->ds.end);
216 } else {
217 /*
218 * It is quite likely that the buffer did not overflow.
219 * Let's just check the delta trace.
220 */
221 error = ds_selftest_bts_read(tracer, trace,
222 top, trace->ds.top);
223 }
224 if (error < 0)
225 goto out;
226
227 error = 0;
228
229 /* The final test: release the tracer while tracing is suspended. */
230 out:
231 ds_release_bts(tracer);
232
233 printk(KERN_CONT "%s.\n", (error ? "failed" : "passed"));
234
235 return error;
236}
237
238int ds_selftest_pebs(void)
239{
240 return 0;
241}
diff --git a/arch/x86/kernel/ds_selftest.h b/arch/x86/kernel/ds_selftest.h
new file mode 100644
index 000000000000..2ba8745c6663
--- /dev/null
+++ b/arch/x86/kernel/ds_selftest.h
@@ -0,0 +1,15 @@
1/*
2 * Debug Store support - selftest
3 *
4 *
5 * Copyright (C) 2009 Intel Corporation.
6 * Markus Metzger <markus.t.metzger@intel.com>, 2009
7 */
8
9#ifdef CONFIG_X86_DS_SELFTEST
10extern int ds_selftest_bts(void);
11extern int ds_selftest_pebs(void);
12#else
13static inline int ds_selftest_bts(void) { return 0; }
14static inline int ds_selftest_pebs(void) { return 0; }
15#endif