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 * - DS and BTS hardware configuration
10 * - buffer overflow handling (to be done)
14 * - security checking (is the caller allowed to trace the task)
15 * - buffer allocation (memory accounting)
18 * Copyright (C) 2007-2009 Intel Corporation.
19 * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
26 #include <linux/types.h>
27 #include <linux/init.h>
28 #include <linux/err.h>
39 typedef void (*bts_ovfl_callback_t
)(struct bts_tracer
*);
40 typedef void (*pebs_ovfl_callback_t
)(struct pebs_tracer
*);
44 * A list of features plus corresponding macros to talk about them in
45 * the ds_request function's flags parameter.
47 * We use the enum to index an array of corresponding control bits;
48 * we use the macro to index a flags bit-vector.
53 #define BTS_KERNEL (1 << dsf_bts_kernel)
54 /* trace kernel-mode branches */
57 #define BTS_USER (1 << dsf_bts_user)
58 /* trace user-mode branches */
62 dsf_pebs
= dsf_bts_max
,
65 dsf_ctl_max
= dsf_pebs_max
,
66 dsf_bts_timestamps
= dsf_ctl_max
,
67 #define BTS_TIMESTAMPS (1 << dsf_bts_timestamps)
68 /* add timestamps into BTS trace */
70 #define BTS_USER_FLAGS (BTS_KERNEL | BTS_USER | BTS_TIMESTAMPS)
77 * Due to alignement constraints, the actual buffer may be slightly
78 * smaller than the requested or provided buffer.
80 * Returns a pointer to a tracer structure on success, or
81 * ERR_PTR(errcode) on failure.
83 * The interrupt threshold is independent from the overflow callback
84 * to allow users to use their own overflow interrupt handling mechanism.
86 * The function might sleep.
88 * task: the task to request recording for
89 * cpu: the cpu to request recording for
90 * base: the base pointer for the (non-pageable) buffer;
91 * size: the size of the provided buffer in bytes
92 * ovfl: pointer to a function to be called on buffer overflow;
93 * NULL if cyclic buffer requested
94 * th: the interrupt threshold in records from the end of the buffer;
95 * -1 if no interrupt threshold is requested.
96 * flags: a bit-mask of the above flags
98 extern struct bts_tracer
*ds_request_bts_task(struct task_struct
*task
,
99 void *base
, size_t size
,
100 bts_ovfl_callback_t ovfl
,
101 size_t th
, unsigned int flags
);
102 extern struct bts_tracer
*ds_request_bts_cpu(int cpu
, void *base
, size_t size
,
103 bts_ovfl_callback_t ovfl
,
104 size_t th
, unsigned int flags
);
105 extern struct pebs_tracer
*ds_request_pebs_task(struct task_struct
*task
,
106 void *base
, size_t size
,
107 pebs_ovfl_callback_t ovfl
,
108 size_t th
, unsigned int flags
);
109 extern struct pebs_tracer
*ds_request_pebs_cpu(int cpu
,
110 void *base
, size_t size
,
111 pebs_ovfl_callback_t ovfl
,
112 size_t th
, unsigned int flags
);
115 * Release BTS or PEBS resources
116 * Suspend and resume BTS or PEBS tracing
118 * Must be called with irq's enabled.
120 * tracer: the tracer handle returned from ds_request_~()
122 extern void ds_release_bts(struct bts_tracer
*tracer
);
123 extern void ds_suspend_bts(struct bts_tracer
*tracer
);
124 extern void ds_resume_bts(struct bts_tracer
*tracer
);
125 extern void ds_release_pebs(struct pebs_tracer
*tracer
);
126 extern void ds_suspend_pebs(struct pebs_tracer
*tracer
);
127 extern void ds_resume_pebs(struct pebs_tracer
*tracer
);
130 * Release BTS or PEBS resources
131 * Suspend and resume BTS or PEBS tracing
133 * Cpu tracers must call this on the traced cpu.
134 * Task tracers must call ds_release_~_noirq() for themselves.
136 * May be called with irq's disabled.
138 * Returns 0 if successful;
139 * -EPERM if the cpu tracer does not trace the current cpu.
140 * -EPERM if the task tracer does not trace itself.
142 * tracer: the tracer handle returned from ds_request_~()
144 extern int ds_release_bts_noirq(struct bts_tracer
*tracer
);
145 extern int ds_suspend_bts_noirq(struct bts_tracer
*tracer
);
146 extern int ds_resume_bts_noirq(struct bts_tracer
*tracer
);
147 extern int ds_release_pebs_noirq(struct pebs_tracer
*tracer
);
148 extern int ds_suspend_pebs_noirq(struct pebs_tracer
*tracer
);
149 extern int ds_resume_pebs_noirq(struct pebs_tracer
*tracer
);
153 * The raw DS buffer state as it is used for BTS and PEBS recording.
155 * This is the low-level, arch-dependent interface for working
156 * directly on the raw trace data.
159 /* the number of bts/pebs records */
161 /* the size of a bts/pebs record in bytes */
163 /* pointers into the raw buffer:
164 - to the first entry */
166 /* - one beyond the last entry */
168 /* - one beyond the newest entry */
170 /* - the interrupt threshold */
172 /* flags given on ds_request() */
177 * An arch-independent view on branch trace data.
181 #define BTS_INVALID bts_invalid
184 #define BTS_BRANCH bts_branch
187 #define BTS_TASK_ARRIVES bts_task_arrives
190 #define BTS_TASK_DEPARTS bts_task_departs
192 bts_qual_bit_size
= 4,
193 bts_qual_max
= (1 << bts_qual_bit_size
),
204 /* BTS_TASK_ARRIVES or BTS_TASK_DEPARTS */
216 * This gives access to the raw DS state and adds functions to provide
217 * an arch-independent view of the BTS data.
222 int (*read
)(struct bts_tracer
*tracer
, const void *at
,
223 struct bts_struct
*out
);
224 int (*write
)(struct bts_tracer
*tracer
, const struct bts_struct
*in
);
231 * This gives access to the raw DS state and the PEBS-specific counter
237 /* the number of valid counters in the below array */
238 unsigned int counters
;
240 #define MAX_PEBS_COUNTERS 4
241 /* the counter reset value */
242 unsigned long long counter_reset
[MAX_PEBS_COUNTERS
];
247 * Read the BTS or PEBS trace.
249 * Returns a view on the trace collected for the parameter tracer.
251 * The view remains valid as long as the traced task is not running or
252 * the tracer is suspended.
253 * Writes into the trace buffer are not reflected.
255 * tracer: the tracer handle returned from ds_request_~()
257 extern const struct bts_trace
*ds_read_bts(struct bts_tracer
*tracer
);
258 extern const struct pebs_trace
*ds_read_pebs(struct pebs_tracer
*tracer
);
262 * Reset the write pointer of the BTS/PEBS buffer.
264 * Returns 0 on success; -Eerrno on error
266 * tracer: the tracer handle returned from ds_request_~()
268 extern int ds_reset_bts(struct bts_tracer
*tracer
);
269 extern int ds_reset_pebs(struct pebs_tracer
*tracer
);
272 * Set the PEBS counter reset value.
274 * Returns 0 on success; -Eerrno on error
276 * tracer: the tracer handle returned from ds_request_pebs()
277 * counter: the index of the counter
278 * value: the new counter reset value
280 extern int ds_set_pebs_reset(struct pebs_tracer
*tracer
,
281 unsigned int counter
, u64 value
);
287 extern void __cpuinit
ds_init_intel(struct cpuinfo_x86
*);
290 * Context switch work
292 extern void ds_switch_to(struct task_struct
*prev
, struct task_struct
*next
);
294 #else /* CONFIG_X86_DS */
297 static inline void __cpuinit
ds_init_intel(struct cpuinfo_x86
*ignored
) {}
298 static inline void ds_switch_to(struct task_struct
*prev
,
299 struct task_struct
*next
) {}
301 #endif /* CONFIG_X86_DS */
302 #endif /* _ASM_X86_DS_H */