2 * Debug Store (DS) support
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).
9 * - per-thread and per-cpu allocation of BTS and PEBS
10 * - buffer overflow handling (to be done)
14 * - get_task_struct on all traced tasks
15 * - current is allowed to trace tasks
18 * Copyright (C) 2007-2008 Intel Corporation.
19 * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008
26 #include <linux/types.h>
27 #include <linux/init.h>
28 #include <linux/err.h>
38 typedef void (*bts_ovfl_callback_t)(struct bts_tracer *);
39 typedef void (*pebs_ovfl_callback_t)(struct pebs_tracer *);
44 * Due to alignement constraints, the actual buffer may be slightly
45 * smaller than the requested or provided buffer.
47 * Returns a pointer to a tracer structure on success, or
48 * ERR_PTR(errcode) on failure.
50 * The interrupt threshold is independent from the overflow callback
51 * to allow users to use their own overflow interrupt handling mechanism.
53 * task: the task to request recording for;
54 * NULL for per-cpu recording on the current cpu
55 * base: the base pointer for the (non-pageable) buffer;
56 * size: the size of the provided buffer in bytes
57 * ovfl: pointer to a function to be called on buffer overflow;
58 * NULL if cyclic buffer requested
59 * th: the interrupt threshold in records from the end of the buffer;
60 * -1 if no interrupt threshold is requested.
62 extern struct bts_tracer *ds_request_bts(struct task_struct *task,
63 void *base, size_t size,
64 bts_ovfl_callback_t ovfl, size_t th);
65 extern struct pebs_tracer *ds_request_pebs(struct task_struct *task,
66 void *base, size_t size,
67 pebs_ovfl_callback_t ovfl,
71 * Release BTS or PEBS resources
73 * Returns 0 on success; -Eerrno otherwise
75 * tracer: the tracer handle returned from ds_request_~()
77 extern int ds_release_bts(struct bts_tracer *tracer);
78 extern int ds_release_pebs(struct pebs_tracer *tracer);
81 * Get the (array) index of the write pointer.
82 * (assuming an array of BTS/PEBS records)
84 * Returns 0 on success; -Eerrno on error
86 * tracer: the tracer handle returned from ds_request_~()
87 * pos (out): will hold the result
89 extern int ds_get_bts_index(struct bts_tracer *tracer, size_t *pos);
90 extern int ds_get_pebs_index(struct pebs_tracer *tracer, size_t *pos);
93 * Get the (array) index one record beyond the end of the array.
94 * (assuming an array of BTS/PEBS records)
96 * Returns 0 on success; -Eerrno on error
98 * tracer: the tracer handle returned from ds_request_~()
99 * pos (out): will hold the result
101 extern int ds_get_bts_end(struct bts_tracer *tracer, size_t *pos);
102 extern int ds_get_pebs_end(struct pebs_tracer *tracer, size_t *pos);
105 * Provide a pointer to the BTS/PEBS record at parameter index.
106 * (assuming an array of BTS/PEBS records)
108 * The pointer points directly into the buffer. The user is
109 * responsible for copying the record.
111 * Returns the size of a single record on success; -Eerrno on error
113 * tracer: the tracer handle returned from ds_request_~()
114 * index: the index of the requested record
115 * record (out): pointer to the requested record
117 extern int ds_access_bts(struct bts_tracer *tracer,
118 size_t index, const void **record);
119 extern int ds_access_pebs(struct pebs_tracer *tracer,
120 size_t index, const void **record);
123 * Write one or more BTS/PEBS records at the write pointer index and
124 * advance the write pointer.
126 * If size is not a multiple of the record size, trailing bytes are
129 * May result in one or more overflow notifications.
131 * If called during overflow handling, that is, with index >=
132 * interrupt threshold, the write will wrap around.
134 * An overflow notification is given if and when the interrupt
135 * threshold is reached during or after the write.
137 * Returns the number of bytes written or -Eerrno.
139 * tracer: the tracer handle returned from ds_request_~()
140 * buffer: the buffer to write
141 * size: the size of the buffer
143 extern int ds_write_bts(struct bts_tracer *tracer,
144 const void *buffer, size_t size);
145 extern int ds_write_pebs(struct pebs_tracer *tracer,
146 const void *buffer, size_t size);
149 * Reset the write pointer of the BTS/PEBS buffer.
151 * Returns 0 on success; -Eerrno on error
153 * tracer: the tracer handle returned from ds_request_~()
155 extern int ds_reset_bts(struct bts_tracer *tracer);
156 extern int ds_reset_pebs(struct pebs_tracer *tracer);
159 * Clear the BTS/PEBS buffer and reset the write pointer.
160 * The entire buffer will be zeroed out.
162 * Returns 0 on success; -Eerrno on error
164 * tracer: the tracer handle returned from ds_request_~()
166 extern int ds_clear_bts(struct bts_tracer *tracer);
167 extern int ds_clear_pebs(struct pebs_tracer *tracer);
170 * Provide the PEBS counter reset value.
172 * Returns 0 on success; -Eerrno on error
174 * tracer: the tracer handle returned from ds_request_pebs()
175 * value (out): the counter reset value
177 extern int ds_get_pebs_reset(struct pebs_tracer *tracer, u64 *value);
180 * Set the PEBS counter reset value.
182 * Returns 0 on success; -Eerrno on error
184 * tracer: the tracer handle returned from ds_request_pebs()
185 * value: the new counter reset value
187 extern int ds_set_pebs_reset(struct pebs_tracer *tracer, u64 value);
193 extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
198 * The DS context - part of struct thread_struct.
200 #define MAX_SIZEOF_DS (12 * 8)
203 /* pointer to the DS configuration; goes into MSR_IA32_DS_AREA */
204 unsigned char ds[MAX_SIZEOF_DS];
205 /* the owner of the BTS and PEBS configuration, respectively */
206 struct ds_tracer *owner[2];
209 /* a pointer to the context location inside the thread_struct
210 * or the per_cpu context array */
211 struct ds_context **this;
212 /* a pointer to the task owning this context, or NULL, if the
213 * context is owned by a cpu */
214 struct task_struct *task;
217 /* called by exit_thread() to free leftover contexts */
218 extern void ds_free(struct ds_context *context);
220 #else /* CONFIG_X86_DS */
223 static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {}
225 #endif /* CONFIG_X86_DS */
226 #endif /* _ASM_X86_DS_H */