diff options
Diffstat (limited to 'include/linux/hw_breakpoint.h')
| -rw-r--r-- | include/linux/hw_breakpoint.h | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h new file mode 100644 index 000000000000..69f07a9f1277 --- /dev/null +++ b/include/linux/hw_breakpoint.h | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | #ifndef _LINUX_HW_BREAKPOINT_H | ||
| 2 | #define _LINUX_HW_BREAKPOINT_H | ||
| 3 | |||
| 4 | enum { | ||
| 5 | HW_BREAKPOINT_LEN_1 = 1, | ||
| 6 | HW_BREAKPOINT_LEN_2 = 2, | ||
| 7 | HW_BREAKPOINT_LEN_4 = 4, | ||
| 8 | HW_BREAKPOINT_LEN_8 = 8, | ||
| 9 | }; | ||
| 10 | |||
| 11 | enum { | ||
| 12 | HW_BREAKPOINT_R = 1, | ||
| 13 | HW_BREAKPOINT_W = 2, | ||
| 14 | HW_BREAKPOINT_X = 4, | ||
| 15 | }; | ||
| 16 | |||
| 17 | #ifdef __KERNEL__ | ||
| 18 | |||
| 19 | #include <linux/perf_event.h> | ||
| 20 | |||
| 21 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 22 | |||
| 23 | static inline void hw_breakpoint_init(struct perf_event_attr *attr) | ||
| 24 | { | ||
| 25 | memset(attr, 0, sizeof(*attr)); | ||
| 26 | |||
| 27 | attr->type = PERF_TYPE_BREAKPOINT; | ||
| 28 | attr->size = sizeof(*attr); | ||
| 29 | /* | ||
| 30 | * As it's for in-kernel or ptrace use, we want it to be pinned | ||
| 31 | * and to call its callback every hits. | ||
| 32 | */ | ||
| 33 | attr->pinned = 1; | ||
| 34 | attr->sample_period = 1; | ||
| 35 | } | ||
| 36 | |||
| 37 | static inline unsigned long hw_breakpoint_addr(struct perf_event *bp) | ||
| 38 | { | ||
| 39 | return bp->attr.bp_addr; | ||
| 40 | } | ||
| 41 | |||
| 42 | static inline int hw_breakpoint_type(struct perf_event *bp) | ||
| 43 | { | ||
| 44 | return bp->attr.bp_type; | ||
| 45 | } | ||
| 46 | |||
| 47 | static inline int hw_breakpoint_len(struct perf_event *bp) | ||
| 48 | { | ||
| 49 | return bp->attr.bp_len; | ||
| 50 | } | ||
| 51 | |||
| 52 | extern struct perf_event * | ||
| 53 | register_user_hw_breakpoint(struct perf_event_attr *attr, | ||
| 54 | perf_overflow_handler_t triggered, | ||
| 55 | struct task_struct *tsk); | ||
| 56 | |||
| 57 | /* FIXME: only change from the attr, and don't unregister */ | ||
| 58 | extern int | ||
| 59 | modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr); | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Kernel breakpoints are not associated with any particular thread. | ||
| 63 | */ | ||
| 64 | extern struct perf_event * | ||
| 65 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, | ||
| 66 | perf_overflow_handler_t triggered, | ||
| 67 | int cpu); | ||
| 68 | |||
| 69 | extern struct perf_event ** | ||
| 70 | register_wide_hw_breakpoint(struct perf_event_attr *attr, | ||
| 71 | perf_overflow_handler_t triggered); | ||
| 72 | |||
| 73 | extern int register_perf_hw_breakpoint(struct perf_event *bp); | ||
| 74 | extern int __register_perf_hw_breakpoint(struct perf_event *bp); | ||
| 75 | extern void unregister_hw_breakpoint(struct perf_event *bp); | ||
| 76 | extern void unregister_wide_hw_breakpoint(struct perf_event **cpu_events); | ||
| 77 | |||
| 78 | extern int reserve_bp_slot(struct perf_event *bp); | ||
| 79 | extern void release_bp_slot(struct perf_event *bp); | ||
| 80 | |||
| 81 | extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk); | ||
| 82 | |||
| 83 | static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) | ||
| 84 | { | ||
| 85 | return &bp->hw.info; | ||
| 86 | } | ||
| 87 | |||
| 88 | #else /* !CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 89 | |||
| 90 | static inline struct perf_event * | ||
| 91 | register_user_hw_breakpoint(struct perf_event_attr *attr, | ||
| 92 | perf_overflow_handler_t triggered, | ||
| 93 | struct task_struct *tsk) { return NULL; } | ||
| 94 | static inline int | ||
| 95 | modify_user_hw_breakpoint(struct perf_event *bp, | ||
| 96 | struct perf_event_attr *attr) { return NULL; } | ||
| 97 | static inline struct perf_event * | ||
| 98 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, | ||
| 99 | perf_overflow_handler_t triggered, | ||
| 100 | int cpu) { return NULL; } | ||
| 101 | static inline struct perf_event ** | ||
| 102 | register_wide_hw_breakpoint(struct perf_event_attr *attr, | ||
| 103 | perf_overflow_handler_t triggered) { return NULL; } | ||
| 104 | static inline int | ||
| 105 | register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } | ||
| 106 | static inline int | ||
| 107 | __register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } | ||
| 108 | static inline void unregister_hw_breakpoint(struct perf_event *bp) { } | ||
| 109 | static inline void | ||
| 110 | unregister_wide_hw_breakpoint(struct perf_event **cpu_events) { } | ||
| 111 | static inline int | ||
| 112 | reserve_bp_slot(struct perf_event *bp) {return -ENOSYS; } | ||
| 113 | static inline void release_bp_slot(struct perf_event *bp) { } | ||
| 114 | |||
| 115 | static inline void flush_ptrace_hw_breakpoint(struct task_struct *tsk) { } | ||
| 116 | |||
| 117 | static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) | ||
| 118 | { | ||
| 119 | return NULL; | ||
| 120 | } | ||
| 121 | |||
| 122 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 123 | #endif /* __KERNEL__ */ | ||
| 124 | |||
| 125 | #endif /* _LINUX_HW_BREAKPOINT_H */ | ||
