Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / arch / x86 / include / asm / ds.h
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 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 memory allocation (optional)
11  * - buffer overflow handling
12  * - buffer access
13  *
14  * It assumes:
15  * - get_task_struct on all parameter tasks
16  * - current is allowed to trace parameter tasks
17  *
18  *
19  * Copyright (C) 2007-2008 Intel Corporation.
20  * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008
21  */
22
23 #ifndef _ASM_X86_DS_H
24 #define _ASM_X86_DS_H
25
26
27 #include <linux/types.h>
28 #include <linux/init.h>
29
30
31 #ifdef CONFIG_X86_DS
32
33 struct task_struct;
34
35 /*
36  * Request BTS or PEBS
37  *
38  * Due to alignement constraints, the actual buffer may be slightly
39  * smaller than the requested or provided buffer.
40  *
41  * Returns 0 on success; -Eerrno otherwise
42  *
43  * task: the task to request recording for;
44  *       NULL for per-cpu recording on the current cpu
45  * base: the base pointer for the (non-pageable) buffer;
46  *       NULL if buffer allocation requested
47  * size: the size of the requested or provided buffer
48  * ovfl: pointer to a function to be called on buffer overflow;
49  *       NULL if cyclic buffer requested
50  */
51 typedef void (*ds_ovfl_callback_t)(struct task_struct *);
52 extern int ds_request_bts(struct task_struct *task, void *base, size_t size,
53                           ds_ovfl_callback_t ovfl);
54 extern int ds_request_pebs(struct task_struct *task, void *base, size_t size,
55                            ds_ovfl_callback_t ovfl);
56
57 /*
58  * Release BTS or PEBS resources
59  *
60  * Frees buffers allocated on ds_request.
61  *
62  * Returns 0 on success; -Eerrno otherwise
63  *
64  * task: the task to release resources for;
65  *       NULL to release resources for the current cpu
66  */
67 extern int ds_release_bts(struct task_struct *task);
68 extern int ds_release_pebs(struct task_struct *task);
69
70 /*
71  * Return the (array) index of the write pointer.
72  * (assuming an array of BTS/PEBS records)
73  *
74  * Returns -Eerrno on error
75  *
76  * task: the task to access;
77  *       NULL to access the current cpu
78  * pos (out): if not NULL, will hold the result
79  */
80 extern int ds_get_bts_index(struct task_struct *task, size_t *pos);
81 extern int ds_get_pebs_index(struct task_struct *task, size_t *pos);
82
83 /*
84  * Return the (array) index one record beyond the end of the array.
85  * (assuming an array of BTS/PEBS records)
86  *
87  * Returns -Eerrno on error
88  *
89  * task: the task to access;
90  *       NULL to access the current cpu
91  * pos (out): if not NULL, will hold the result
92  */
93 extern int ds_get_bts_end(struct task_struct *task, size_t *pos);
94 extern int ds_get_pebs_end(struct task_struct *task, size_t *pos);
95
96 /*
97  * Provide a pointer to the BTS/PEBS record at parameter index.
98  * (assuming an array of BTS/PEBS records)
99  *
100  * The pointer points directly into the buffer. The user is
101  * responsible for copying the record.
102  *
103  * Returns the size of a single record on success; -Eerrno on error
104  *
105  * task: the task to access;
106  *       NULL to access the current cpu
107  * index: the index of the requested record
108  * record (out): pointer to the requested record
109  */
110 extern int ds_access_bts(struct task_struct *task,
111                          size_t index, const void **record);
112 extern int ds_access_pebs(struct task_struct *task,
113                           size_t index, const void **record);
114
115 /*
116  * Write one or more BTS/PEBS records at the write pointer index and
117  * advance the write pointer.
118  *
119  * If size is not a multiple of the record size, trailing bytes are
120  * zeroed out.
121  *
122  * May result in one or more overflow notifications.
123  *
124  * If called during overflow handling, that is, with index >=
125  * interrupt threshold, the write will wrap around.
126  *
127  * An overflow notification is given if and when the interrupt
128  * threshold is reached during or after the write.
129  *
130  * Returns the number of bytes written or -Eerrno.
131  *
132  * task: the task to access;
133  *       NULL to access the current cpu
134  * buffer: the buffer to write
135  * size: the size of the buffer
136  */
137 extern int ds_write_bts(struct task_struct *task,
138                         const void *buffer, size_t size);
139 extern int ds_write_pebs(struct task_struct *task,
140                          const void *buffer, size_t size);
141
142 /*
143  * Same as ds_write_bts/pebs, but omit ownership checks.
144  *
145  * This is needed to have some other task than the owner of the
146  * BTS/PEBS buffer or the parameter task itself write into the
147  * respective buffer.
148  */
149 extern int ds_unchecked_write_bts(struct task_struct *task,
150                                   const void *buffer, size_t size);
151 extern int ds_unchecked_write_pebs(struct task_struct *task,
152                                    const void *buffer, size_t size);
153
154 /*
155  * Reset the write pointer of the BTS/PEBS buffer.
156  *
157  * Returns 0 on success; -Eerrno on error
158  *
159  * task: the task to access;
160  *       NULL to access the current cpu
161  */
162 extern int ds_reset_bts(struct task_struct *task);
163 extern int ds_reset_pebs(struct task_struct *task);
164
165 /*
166  * Clear the BTS/PEBS buffer and reset the write pointer.
167  * The entire buffer will be zeroed out.
168  *
169  * Returns 0 on success; -Eerrno on error
170  *
171  * task: the task to access;
172  *       NULL to access the current cpu
173  */
174 extern int ds_clear_bts(struct task_struct *task);
175 extern int ds_clear_pebs(struct task_struct *task);
176
177 /*
178  * Provide the PEBS counter reset value.
179  *
180  * Returns 0 on success; -Eerrno on error
181  *
182  * task: the task to access;
183  *       NULL to access the current cpu
184  * value (out): the counter reset value
185  */
186 extern int ds_get_pebs_reset(struct task_struct *task, u64 *value);
187
188 /*
189  * Set the PEBS counter reset value.
190  *
191  * Returns 0 on success; -Eerrno on error
192  *
193  * task: the task to access;
194  *       NULL to access the current cpu
195  * value: the new counter reset value
196  */
197 extern int ds_set_pebs_reset(struct task_struct *task, u64 value);
198
199 /*
200  * Initialization
201  */
202 struct cpuinfo_x86;
203 extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
204
205
206
207 /*
208  * The DS context - part of struct thread_struct.
209  */
210 struct ds_context {
211         /* pointer to the DS configuration; goes into MSR_IA32_DS_AREA */
212         unsigned char *ds;
213         /* the owner of the BTS and PEBS configuration, respectively */
214         struct task_struct *owner[2];
215         /* buffer overflow notification function for BTS and PEBS */
216         ds_ovfl_callback_t callback[2];
217         /* the original buffer address */
218         void *buffer[2];
219         /* the number of allocated pages for on-request allocated buffers */
220         unsigned int pages[2];
221         /* use count */
222         unsigned long count;
223         /* a pointer to the context location inside the thread_struct
224          * or the per_cpu context array */
225         struct ds_context **this;
226         /* a pointer to the task owning this context, or NULL, if the
227          * context is owned by a cpu */
228         struct task_struct *task;
229 };
230
231 /* called by exit_thread() to free leftover contexts */
232 extern void ds_free(struct ds_context *context);
233
234 #else /* CONFIG_X86_DS */
235
236 struct cpuinfo_x86;
237 static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {}
238
239 #endif /* CONFIG_X86_DS */
240 #endif /* _ASM_X86_DS_H */