diff options
Diffstat (limited to 'include/linux/hw_breakpoint.h')
-rw-r--r-- | include/linux/hw_breakpoint.h | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h new file mode 100644 index 000000000000..c70d27af03f9 --- /dev/null +++ b/include/linux/hw_breakpoint.h | |||
@@ -0,0 +1,127 @@ | |||
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 unsigned long 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 * __percpu * | ||
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 * __percpu *cpu_events); | ||
77 | |||
78 | extern int dbg_reserve_bp_slot(struct perf_event *bp); | ||
79 | extern int dbg_release_bp_slot(struct perf_event *bp); | ||
80 | extern int reserve_bp_slot(struct perf_event *bp); | ||
81 | extern void release_bp_slot(struct perf_event *bp); | ||
82 | |||
83 | extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk); | ||
84 | |||
85 | static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) | ||
86 | { | ||
87 | return &bp->hw.info; | ||
88 | } | ||
89 | |||
90 | #else /* !CONFIG_HAVE_HW_BREAKPOINT */ | ||
91 | |||
92 | static inline struct perf_event * | ||
93 | register_user_hw_breakpoint(struct perf_event_attr *attr, | ||
94 | perf_overflow_handler_t triggered, | ||
95 | struct task_struct *tsk) { return NULL; } | ||
96 | static inline int | ||
97 | modify_user_hw_breakpoint(struct perf_event *bp, | ||
98 | struct perf_event_attr *attr) { return -ENOSYS; } | ||
99 | static inline struct perf_event * | ||
100 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, | ||
101 | perf_overflow_handler_t triggered, | ||
102 | int cpu) { return NULL; } | ||
103 | static inline struct perf_event * __percpu * | ||
104 | register_wide_hw_breakpoint(struct perf_event_attr *attr, | ||
105 | perf_overflow_handler_t triggered) { return NULL; } | ||
106 | static inline int | ||
107 | register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } | ||
108 | static inline int | ||
109 | __register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } | ||
110 | static inline void unregister_hw_breakpoint(struct perf_event *bp) { } | ||
111 | static inline void | ||
112 | unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events) { } | ||
113 | static inline int | ||
114 | reserve_bp_slot(struct perf_event *bp) {return -ENOSYS; } | ||
115 | static inline void release_bp_slot(struct perf_event *bp) { } | ||
116 | |||
117 | static inline void flush_ptrace_hw_breakpoint(struct task_struct *tsk) { } | ||
118 | |||
119 | static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) | ||
120 | { | ||
121 | return NULL; | ||
122 | } | ||
123 | |||
124 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
125 | #endif /* __KERNEL__ */ | ||
126 | |||
127 | #endif /* _LINUX_HW_BREAKPOINT_H */ | ||