Branch data Line data Source code
1 : : #ifndef _LINUX_HW_BREAKPOINT_H
2 : : #define _LINUX_HW_BREAKPOINT_H
3 : :
4 : : #include <linux/perf_event.h>
5 : : #include <uapi/linux/hw_breakpoint.h>
6 : :
7 : : #ifdef CONFIG_HAVE_HW_BREAKPOINT
8 : :
9 : : extern int __init init_hw_breakpoint(void);
10 : :
11 : : static inline void hw_breakpoint_init(struct perf_event_attr *attr)
12 : : {
13 : 0 : memset(attr, 0, sizeof(*attr));
14 : :
15 : 0 : attr->type = PERF_TYPE_BREAKPOINT;
16 : 0 : attr->size = sizeof(*attr);
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 : : */
21 : 0 : attr->pinned = 1;
22 : 0 : attr->sample_period = 1;
23 : : }
24 : :
25 : : static inline void ptrace_breakpoint_init(struct perf_event_attr *attr)
26 : : {
27 : : hw_breakpoint_init(attr);
28 : 0 : attr->exclude_kernel = 1;
29 : : }
30 : :
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 : :
41 : : static inline unsigned long hw_breakpoint_len(struct perf_event *bp)
42 : : {
43 : : return bp->attr.bp_len;
44 : : }
45 : :
46 : : extern struct perf_event *
47 : : register_user_hw_breakpoint(struct perf_event_attr *attr,
48 : : perf_overflow_handler_t triggered,
49 : : void *context,
50 : : struct task_struct *tsk);
51 : :
52 : : /* FIXME: only change from the attr, and don't unregister */
53 : : extern int
54 : : modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr);
55 : :
56 : : /*
57 : : * Kernel breakpoints are not associated with any particular thread.
58 : : */
59 : : extern struct perf_event *
60 : : register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
61 : : perf_overflow_handler_t triggered,
62 : : void *context,
63 : : int cpu);
64 : :
65 : : extern struct perf_event * __percpu *
66 : : register_wide_hw_breakpoint(struct perf_event_attr *attr,
67 : : perf_overflow_handler_t triggered,
68 : : void *context);
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);
73 : : extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events);
74 : :
75 : : extern int dbg_reserve_bp_slot(struct perf_event *bp);
76 : : extern int dbg_release_bp_slot(struct perf_event *bp);
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 : :
82 : : static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
83 : : {
84 : : return &bp->hw.info;
85 : : }
86 : :
87 : : #else /* !CONFIG_HAVE_HW_BREAKPOINT */
88 : :
89 : : static inline int __init init_hw_breakpoint(void) { return 0; }
90 : :
91 : : static inline struct perf_event *
92 : : register_user_hw_breakpoint(struct perf_event_attr *attr,
93 : : perf_overflow_handler_t triggered,
94 : : void *context,
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 : : void *context,
103 : : int cpu) { return NULL; }
104 : : static inline struct perf_event * __percpu *
105 : : register_wide_hw_breakpoint(struct perf_event_attr *attr,
106 : : perf_overflow_handler_t triggered,
107 : : void *context) { return NULL; }
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
114 : : unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events) { }
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) { }
120 : :
121 : : static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
122 : : {
123 : : return NULL;
124 : : }
125 : :
126 : : #endif /* CONFIG_HAVE_HW_BREAKPOINT */
127 : : #endif /* _LINUX_HW_BREAKPOINT_H */
|