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 33struct 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 */ 51typedef void (*ds_ovfl_callback_t)(struct task_struct *); 52extern int ds_request_bts(struct task_struct *task, void *base, size_t size, 53 ds_ovfl_callback_t ovfl); 54extern 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 */ 67extern int ds_release_bts(struct task_struct *task); 68extern 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 */ 80extern int ds_get_bts_index(struct task_struct *task, size_t *pos); 81extern 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 */ 93extern int ds_get_bts_end(struct task_struct *task, size_t *pos); 94extern 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 */ 110extern int ds_access_bts(struct task_struct *task, 111 size_t index, const void **record); 112extern 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 */ 137extern int ds_write_bts(struct task_struct *task, 138 const void *buffer, size_t size); 139extern 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 */ 149extern int ds_unchecked_write_bts(struct task_struct *task, 150 const void *buffer, size_t size); 151extern 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 */ 162extern int ds_reset_bts(struct task_struct *task); 163extern 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 */ 174extern int ds_clear_bts(struct task_struct *task); 175extern 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 */ 186extern 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 */ 197extern int ds_set_pebs_reset(struct task_struct *task, u64 value); 198 199/* 200 * Initialization 201 */ 202struct cpuinfo_x86; 203extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *); 204 205 206 207/* 208 * The DS context - part of struct thread_struct. 209 */ 210struct 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 */ 232extern void ds_free(struct ds_context *context); 233 234#else /* CONFIG_X86_DS */ 235 236struct cpuinfo_x86; 237static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {} 238 239#endif /* CONFIG_X86_DS */ 240#endif /* _ASM_X86_DS_H */ 241

