]>
Commit | Line | Data |
---|---|---|
2da3e160 FW |
1 | #ifndef _LINUX_HW_BREAKPOINT_H |
2 | #define _LINUX_HW_BREAKPOINT_H | |
b332828c | 3 | |
e6db4876 | 4 | #include <linux/perf_event.h> |
d2709c7c | 5 | #include <uapi/linux/hw_breakpoint.h> |
e6db4876 | 6 | |
fa7c27ee FW |
7 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
8 | ||
3c502e7a JW |
9 | extern int __init init_hw_breakpoint(void); |
10 | ||
dd1853c3 FW |
11 | static inline void hw_breakpoint_init(struct perf_event_attr *attr) |
12 | { | |
ed872d09 FW |
13 | memset(attr, 0, sizeof(*attr)); |
14 | ||
dd1853c3 FW |
15 | attr->type = PERF_TYPE_BREAKPOINT; |
16 | attr->size = sizeof(*attr); | |
b326e956 FW |
17 | /* |
18 | * As it's for in-kernel or ptrace use, we want it to be pinned | |
19 | * and to call its callback every hits. | |
20 | */ | |
dd1853c3 | 21 | attr->pinned = 1; |
b326e956 | 22 | attr->sample_period = 1; |
73266fc1 FW |
23 | } |
24 | ||
25 | static inline void ptrace_breakpoint_init(struct perf_event_attr *attr) | |
26 | { | |
27 | hw_breakpoint_init(attr); | |
28 | attr->exclude_kernel = 1; | |
dd1853c3 FW |
29 | } |
30 | ||
24f1e32c FW |
31 | static inline unsigned long hw_breakpoint_addr(struct perf_event *bp) |
32 | { | |
33 | return bp->attr.bp_addr; | |
34 | } | |
35 | ||
36 | static inline int hw_breakpoint_type(struct perf_event *bp) | |
37 | { | |
38 | return bp->attr.bp_type; | |
39 | } | |
40 | ||
cd757645 | 41 | static inline unsigned long hw_breakpoint_len(struct perf_event *bp) |
24f1e32c FW |
42 | { |
43 | return bp->attr.bp_len; | |
44 | } | |
45 | ||
24f1e32c | 46 | extern struct perf_event * |
5fa10b28 | 47 | register_user_hw_breakpoint(struct perf_event_attr *attr, |
b326e956 | 48 | perf_overflow_handler_t triggered, |
4dc0da86 | 49 | void *context, |
5fa10b28 | 50 | struct task_struct *tsk); |
24f1e32c FW |
51 | |
52 | /* FIXME: only change from the attr, and don't unregister */ | |
44234adc | 53 | extern int |
2f0993e0 | 54 | modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr); |
b332828c | 55 | |
b332828c P |
56 | /* |
57 | * Kernel breakpoints are not associated with any particular thread. | |
58 | */ | |
24f1e32c | 59 | extern struct perf_event * |
dd1853c3 | 60 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, |
b326e956 | 61 | perf_overflow_handler_t triggered, |
4dc0da86 | 62 | void *context, |
dd1853c3 | 63 | int cpu); |
24f1e32c | 64 | |
44ee6358 | 65 | extern struct perf_event * __percpu * |
dd1853c3 | 66 | register_wide_hw_breakpoint(struct perf_event_attr *attr, |
4dc0da86 AK |
67 | perf_overflow_handler_t triggered, |
68 | void *context); | |
24f1e32c FW |
69 | |
70 | extern int register_perf_hw_breakpoint(struct perf_event *bp); | |
71 | extern int __register_perf_hw_breakpoint(struct perf_event *bp); | |
72 | extern void unregister_hw_breakpoint(struct perf_event *bp); | |
44ee6358 | 73 | extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events); |
24f1e32c | 74 | |
5352ae63 JW |
75 | extern int dbg_reserve_bp_slot(struct perf_event *bp); |
76 | extern int dbg_release_bp_slot(struct perf_event *bp); | |
24f1e32c FW |
77 | extern int reserve_bp_slot(struct perf_event *bp); |
78 | extern void release_bp_slot(struct perf_event *bp); | |
79 | ||
80 | extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk); | |
81 | ||
687b16fb FW |
82 | static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) |
83 | { | |
84 | return &bp->hw.info; | |
85 | } | |
86 | ||
24f1e32c FW |
87 | #else /* !CONFIG_HAVE_HW_BREAKPOINT */ |
88 | ||
3c502e7a JW |
89 | static inline int __init init_hw_breakpoint(void) { return 0; } |
90 | ||
24f1e32c | 91 | static inline struct perf_event * |
5fa10b28 | 92 | register_user_hw_breakpoint(struct perf_event_attr *attr, |
b326e956 | 93 | perf_overflow_handler_t triggered, |
4dc0da86 | 94 | void *context, |
5fa10b28 | 95 | struct task_struct *tsk) { return NULL; } |
44234adc | 96 | static inline int |
24f1e32c | 97 | modify_user_hw_breakpoint(struct perf_event *bp, |
99ac64c8 | 98 | struct perf_event_attr *attr) { return -ENOSYS; } |
24f1e32c | 99 | static inline struct perf_event * |
dd1853c3 | 100 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, |
b326e956 | 101 | perf_overflow_handler_t triggered, |
4dc0da86 | 102 | void *context, |
dd1853c3 | 103 | int cpu) { return NULL; } |
44ee6358 | 104 | static inline struct perf_event * __percpu * |
dd1853c3 | 105 | register_wide_hw_breakpoint(struct perf_event_attr *attr, |
4dc0da86 AK |
106 | perf_overflow_handler_t triggered, |
107 | void *context) { return NULL; } | |
24f1e32c FW |
108 | static inline int |
109 | register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } | |
110 | static inline int | |
111 | __register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } | |
112 | static inline void unregister_hw_breakpoint(struct perf_event *bp) { } | |
113 | static inline void | |
44ee6358 | 114 | unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events) { } |
24f1e32c FW |
115 | static inline int |
116 | reserve_bp_slot(struct perf_event *bp) {return -ENOSYS; } | |
117 | static inline void release_bp_slot(struct perf_event *bp) { } | |
118 | ||
119 | static inline void flush_ptrace_hw_breakpoint(struct task_struct *tsk) { } | |
b332828c | 120 | |
687b16fb FW |
121 | static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) |
122 | { | |
123 | return NULL; | |
124 | } | |
125 | ||
24f1e32c | 126 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ |
24f1e32c | 127 | #endif /* _LINUX_HW_BREAKPOINT_H */ |