diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2008-01-30 07:31:09 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:31:09 -0500 |
commit | eee3af4a2c83a97fff107ddc445d9df6fded9ce4 (patch) | |
tree | a7e9179b82b4df9e4cf6e810c54309324589395b /include/asm-x86 | |
parent | 7796931f542518092d1fd2fb7cf1f1d96e0cd4b5 (diff) |
x86, ptrace: support for branch trace store(BTS)
Resend using different mail client
Changes to the last version:
- split implementation into two layers: ds/bts and ptrace
- renamed TIF's
- save/restore ds save area msr in __switch_to_xtra()
- make block-stepping only look at BTF bit
Signed-off-by: Markus Metzger <markus.t.metzger@intel.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/asm-x86')
-rw-r--r-- | include/asm-x86/ds.h | 65 | ||||
-rw-r--r-- | include/asm-x86/processor_32.h | 3 | ||||
-rw-r--r-- | include/asm-x86/processor_64.h | 3 | ||||
-rw-r--r-- | include/asm-x86/ptrace-abi.h | 52 | ||||
-rw-r--r-- | include/asm-x86/ptrace.h | 11 | ||||
-rw-r--r-- | include/asm-x86/thread_info_32.h | 12 | ||||
-rw-r--r-- | include/asm-x86/thread_info_64.h | 9 |
7 files changed, 152 insertions, 3 deletions
diff --git a/include/asm-x86/ds.h b/include/asm-x86/ds.h new file mode 100644 index 000000000000..edd8467740a6 --- /dev/null +++ b/include/asm-x86/ds.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Debug Store (DS) support | ||
3 | * | ||
4 | * This provides a low-level interface to the hardware's Debug Store | ||
5 | * feature that is used for last branch recording (LBR) and | ||
6 | * precise-event based sampling (PEBS). | ||
7 | * | ||
8 | * Different architectures use a different DS layout/pointer size. | ||
9 | * The below functions therefore work on a void*. | ||
10 | * | ||
11 | * | ||
12 | * Since there is no user for PEBS, yet, only LBR (or branch | ||
13 | * trace store, BTS) is supported. | ||
14 | * | ||
15 | * | ||
16 | * Copyright (C) 2007 Intel Corporation. | ||
17 | * Markus Metzger <markus.t.metzger@intel.com>, Dec 2007 | ||
18 | */ | ||
19 | |||
20 | #ifndef _ASM_X86_DS_H | ||
21 | #define _ASM_X86_DS_H | ||
22 | |||
23 | #include <linux/types.h> | ||
24 | #include <linux/init.h> | ||
25 | |||
26 | struct cpuinfo_x86; | ||
27 | |||
28 | |||
29 | /* a branch trace record entry | ||
30 | * | ||
31 | * In order to unify the interface between various processor versions, | ||
32 | * we use the below data structure for all processors. | ||
33 | */ | ||
34 | enum bts_qualifier { | ||
35 | BTS_INVALID = 0, | ||
36 | BTS_BRANCH, | ||
37 | BTS_TASK_ARRIVES, | ||
38 | BTS_TASK_DEPARTS | ||
39 | }; | ||
40 | |||
41 | struct bts_struct { | ||
42 | enum bts_qualifier qualifier; | ||
43 | union { | ||
44 | /* BTS_BRANCH */ | ||
45 | struct { | ||
46 | long from_ip; | ||
47 | long to_ip; | ||
48 | } lbr; | ||
49 | /* BTS_TASK_ARRIVES or | ||
50 | BTS_TASK_DEPARTS */ | ||
51 | unsigned long long timestamp; | ||
52 | } variant; | ||
53 | }; | ||
54 | |||
55 | |||
56 | extern int ds_allocate(void **, size_t); | ||
57 | extern int ds_free(void **); | ||
58 | extern int ds_get_bts_size(void *); | ||
59 | extern int ds_get_bts_index(void *); | ||
60 | extern int ds_read_bts(void *, size_t, struct bts_struct *); | ||
61 | extern int ds_write_bts(void *, const struct bts_struct *); | ||
62 | extern unsigned long ds_debugctl_mask(void); | ||
63 | extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *c); | ||
64 | |||
65 | #endif /* _ASM_X86_DS_H */ | ||
diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 0d83da198127..9c0ab7f26bd9 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h | |||
@@ -360,6 +360,9 @@ struct thread_struct { | |||
360 | unsigned long io_bitmap_max; | 360 | unsigned long io_bitmap_max; |
361 | /* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ | 361 | /* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ |
362 | unsigned long debugctlmsr; | 362 | unsigned long debugctlmsr; |
363 | /* Debug Store - if not 0 points to a DS Save Area configuration; | ||
364 | * goes into MSR_IA32_DS_AREA */ | ||
365 | unsigned long ds_area_msr; | ||
363 | }; | 366 | }; |
364 | 367 | ||
365 | #define INIT_THREAD { \ | 368 | #define INIT_THREAD { \ |
diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 0780f3e3fdfe..7b7f8a142e20 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h | |||
@@ -240,6 +240,9 @@ struct thread_struct { | |||
240 | unsigned io_bitmap_max; | 240 | unsigned io_bitmap_max; |
241 | /* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ | 241 | /* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ |
242 | unsigned long debugctlmsr; | 242 | unsigned long debugctlmsr; |
243 | /* Debug Store - if not 0 points to a DS Save Area configuration; | ||
244 | * goes into MSR_IA32_DS_AREA */ | ||
245 | unsigned long ds_area_msr; | ||
243 | /* cached TLS descriptors. */ | 246 | /* cached TLS descriptors. */ |
244 | u64 tls_array[GDT_ENTRY_TLS_ENTRIES]; | 247 | u64 tls_array[GDT_ENTRY_TLS_ENTRIES]; |
245 | } __attribute__((aligned(16))); | 248 | } __attribute__((aligned(16))); |
diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index adce6b51df2e..6fadc5214e14 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h | |||
@@ -80,4 +80,56 @@ | |||
80 | 80 | ||
81 | #define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ | 81 | #define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ |
82 | 82 | ||
83 | /* Return maximal BTS buffer size in number of records, | ||
84 | if successuf; -1, otherwise. | ||
85 | EOPNOTSUPP...processor does not support bts tracing */ | ||
86 | #define PTRACE_BTS_MAX_BUFFER_SIZE 40 | ||
87 | |||
88 | /* Allocate new bts buffer (free old one, if exists) of size DATA bts records; | ||
89 | parameter ADDR is ignored. | ||
90 | Return 0, if successful; -1, otherwise. | ||
91 | EOPNOTSUPP...processor does not support bts tracing | ||
92 | EINVAL.......invalid size in records | ||
93 | ENOMEM.......out of memory */ | ||
94 | #define PTRACE_BTS_ALLOCATE_BUFFER 41 | ||
95 | |||
96 | /* Return the size of the bts buffer in number of bts records, | ||
97 | if successful; -1, otherwise. | ||
98 | EOPNOTSUPP...processor does not support bts tracing | ||
99 | ENXIO........no buffer allocated */ | ||
100 | #define PTRACE_BTS_GET_BUFFER_SIZE 42 | ||
101 | |||
102 | /* Return the index of the next bts record to be written, | ||
103 | if successful; -1, otherwise. | ||
104 | EOPNOTSUPP...processor does not support bts tracing | ||
105 | ENXIO........no buffer allocated | ||
106 | After the first warp-around, this is the start of the circular bts buffer. */ | ||
107 | #define PTRACE_BTS_GET_INDEX 43 | ||
108 | |||
109 | /* Read the DATA'th bts record into a ptrace_bts_record buffer provided in ADDR. | ||
110 | Return 0, if successful; -1, otherwise | ||
111 | EOPNOTSUPP...processor does not support bts tracing | ||
112 | ENXIO........no buffer allocated | ||
113 | EINVAL.......invalid index */ | ||
114 | #define PTRACE_BTS_READ_RECORD 44 | ||
115 | |||
116 | /* Configure last branch trace; the configuration is given as a bit-mask of | ||
117 | PTRACE_BTS_O_* options in DATA; parameter ADDR is ignored. | ||
118 | Return 0, if successful; -1, otherwise | ||
119 | EOPNOTSUPP...processor does not support bts tracing | ||
120 | ENXIO........no buffer allocated */ | ||
121 | #define PTRACE_BTS_CONFIG 45 | ||
122 | |||
123 | /* Return the configuration as bit-mask of PTRACE_BTS_O_* options | ||
124 | if successful; -1, otherwise. | ||
125 | EOPNOTSUPP...processor does not support bts tracing | ||
126 | ENXIO........no buffer allocated */ | ||
127 | #define PTRACE_BTS_STATUS 46 | ||
128 | |||
129 | /* Trace configuration options */ | ||
130 | /* Collect last branch trace */ | ||
131 | #define PTRACE_BTS_O_TRACE_TASK 0x1 | ||
132 | /* Take timestamps when the task arrives and departs */ | ||
133 | #define PTRACE_BTS_O_TIMESTAMPS 0x2 | ||
134 | |||
83 | #endif | 135 | #endif |
diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 9228870f6157..a9a1bab1451a 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h | |||
@@ -4,8 +4,19 @@ | |||
4 | #include <linux/compiler.h> /* For __user */ | 4 | #include <linux/compiler.h> /* For __user */ |
5 | #include <asm/ptrace-abi.h> | 5 | #include <asm/ptrace-abi.h> |
6 | 6 | ||
7 | |||
7 | #ifndef __ASSEMBLY__ | 8 | #ifndef __ASSEMBLY__ |
8 | 9 | ||
10 | #ifdef __KERNEL__ | ||
11 | |||
12 | #include <asm/ds.h> | ||
13 | |||
14 | struct task_struct; | ||
15 | extern void ptrace_bts_take_timestamp(struct task_struct *, enum bts_qualifier); | ||
16 | |||
17 | #endif /* __KERNEL__ */ | ||
18 | |||
19 | |||
9 | #ifdef __i386__ | 20 | #ifdef __i386__ |
10 | /* this struct defines the way the registers are stored on the | 21 | /* this struct defines the way the registers are stored on the |
11 | stack during a system call. */ | 22 | stack during a system call. */ |
diff --git a/include/asm-x86/thread_info_32.h b/include/asm-x86/thread_info_32.h index 306fc80800e1..5bd508260ffb 100644 --- a/include/asm-x86/thread_info_32.h +++ b/include/asm-x86/thread_info_32.h | |||
@@ -140,6 +140,8 @@ static inline struct thread_info *current_thread_info(void) | |||
140 | #define TIF_NOTSC 20 /* TSC is not accessible in userland */ | 140 | #define TIF_NOTSC 20 /* TSC is not accessible in userland */ |
141 | #define TIF_FORCED_TF 21 /* true if TF in eflags artificially */ | 141 | #define TIF_FORCED_TF 21 /* true if TF in eflags artificially */ |
142 | #define TIF_DEBUGCTLMSR 22 /* uses thread_struct.debugctlmsr */ | 142 | #define TIF_DEBUGCTLMSR 22 /* uses thread_struct.debugctlmsr */ |
143 | #define TIF_DS_AREA_MSR 23 /* uses thread_struct.ds_area_msr */ | ||
144 | #define TIF_BTS_TRACE_TS 24 /* record scheduling event timestamps */ | ||
143 | 145 | ||
144 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 146 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
145 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | 147 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) |
@@ -157,6 +159,8 @@ static inline struct thread_info *current_thread_info(void) | |||
157 | #define _TIF_NOTSC (1<<TIF_NOTSC) | 159 | #define _TIF_NOTSC (1<<TIF_NOTSC) |
158 | #define _TIF_FORCED_TF (1<<TIF_FORCED_TF) | 160 | #define _TIF_FORCED_TF (1<<TIF_FORCED_TF) |
159 | #define _TIF_DEBUGCTLMSR (1<<TIF_DEBUGCTLMSR) | 161 | #define _TIF_DEBUGCTLMSR (1<<TIF_DEBUGCTLMSR) |
162 | #define _TIF_DS_AREA_MSR (1<<TIF_DS_AREA_MSR) | ||
163 | #define _TIF_BTS_TRACE_TS (1<<TIF_BTS_TRACE_TS) | ||
160 | 164 | ||
161 | /* work to do on interrupt/exception return */ | 165 | /* work to do on interrupt/exception return */ |
162 | #define _TIF_WORK_MASK \ | 166 | #define _TIF_WORK_MASK \ |
@@ -166,8 +170,12 @@ static inline struct thread_info *current_thread_info(void) | |||
166 | #define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP) | 170 | #define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP) |
167 | 171 | ||
168 | /* flags to check in __switch_to() */ | 172 | /* flags to check in __switch_to() */ |
169 | #define _TIF_WORK_CTXSW_NEXT (_TIF_IO_BITMAP | _TIF_NOTSC | _TIF_DEBUG | _TIF_DEBUGCTLMSR) | 173 | #define _TIF_WORK_CTXSW \ |
170 | #define _TIF_WORK_CTXSW_PREV (_TIF_IO_BITMAP | _TIF_NOTSC | _TIF_DEBUGCTLMSR) | 174 | (_TIF_IO_BITMAP | _TIF_NOTSC | _TIF_DEBUGCTLMSR | \ |
175 | _TIF_DS_AREA_MSR | _TIF_BTS_TRACE_TS) | ||
176 | #define _TIF_WORK_CTXSW_PREV _TIF_WORK_CTXSW | ||
177 | #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW | _TIF_DEBUG) | ||
178 | |||
171 | 179 | ||
172 | /* | 180 | /* |
173 | * Thread-synchronous status. | 181 | * Thread-synchronous status. |
diff --git a/include/asm-x86/thread_info_64.h b/include/asm-x86/thread_info_64.h index ee35fd12b541..c2911a99cc32 100644 --- a/include/asm-x86/thread_info_64.h +++ b/include/asm-x86/thread_info_64.h | |||
@@ -123,6 +123,8 @@ static inline struct thread_info *stack_thread_info(void) | |||
123 | #define TIF_FREEZE 23 /* is freezing for suspend */ | 123 | #define TIF_FREEZE 23 /* is freezing for suspend */ |
124 | #define TIF_FORCED_TF 24 /* true if TF in eflags artificially */ | 124 | #define TIF_FORCED_TF 24 /* true if TF in eflags artificially */ |
125 | #define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */ | 125 | #define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */ |
126 | #define TIF_DS_AREA_MSR 25 /* uses thread_struct.ds_area_msr */ | ||
127 | #define TIF_BTS_TRACE_TS 26 /* record scheduling event timestamps */ | ||
126 | 128 | ||
127 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 129 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
128 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | 130 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) |
@@ -142,6 +144,8 @@ static inline struct thread_info *stack_thread_info(void) | |||
142 | #define _TIF_FREEZE (1<<TIF_FREEZE) | 144 | #define _TIF_FREEZE (1<<TIF_FREEZE) |
143 | #define _TIF_FORCED_TF (1<<TIF_FORCED_TF) | 145 | #define _TIF_FORCED_TF (1<<TIF_FORCED_TF) |
144 | #define _TIF_DEBUGCTLMSR (1<<TIF_DEBUGCTLMSR) | 146 | #define _TIF_DEBUGCTLMSR (1<<TIF_DEBUGCTLMSR) |
147 | #define _TIF_DS_AREA_MSR (1<<TIF_DS_AREA_MSR) | ||
148 | #define _TIF_BTS_TRACE_TS (1<<TIF_BTS_TRACE_TS) | ||
145 | 149 | ||
146 | /* work to do on interrupt/exception return */ | 150 | /* work to do on interrupt/exception return */ |
147 | #define _TIF_WORK_MASK \ | 151 | #define _TIF_WORK_MASK \ |
@@ -153,7 +157,10 @@ static inline struct thread_info *stack_thread_info(void) | |||
153 | (_TIF_SIGPENDING|_TIF_SINGLESTEP|_TIF_MCE_NOTIFY|_TIF_HRTICK_RESCHED) | 157 | (_TIF_SIGPENDING|_TIF_SINGLESTEP|_TIF_MCE_NOTIFY|_TIF_HRTICK_RESCHED) |
154 | 158 | ||
155 | /* flags to check in __switch_to() */ | 159 | /* flags to check in __switch_to() */ |
156 | #define _TIF_WORK_CTXSW (_TIF_DEBUG|_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR) | 160 | #define _TIF_WORK_CTXSW \ |
161 | (_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR|_TIF_DS_AREA_MSR|_TIF_BTS_TRACE_TS) | ||
162 | #define _TIF_WORK_CTXSW_PREV _TIF_WORK_CTXSW | ||
163 | #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG) | ||
157 | 164 | ||
158 | #define PREEMPT_ACTIVE 0x10000000 | 165 | #define PREEMPT_ACTIVE 0x10000000 |
159 | 166 | ||