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 unsigned long hw_breakpoint_addr(struct perf_event *bp) 24 { 25 return bp->attr.bp_addr; 26 } 27 28 static inline int hw_breakpoint_type(struct perf_event *bp) 29 { 30 return bp->attr.bp_type; 31 } 32 33 static inline int hw_breakpoint_len(struct perf_event *bp) 34 { 35 return bp->attr.bp_len; 36 } 37 38 extern struct perf_event * 39 register_user_hw_breakpoint(unsigned long addr, 40 int len, 41 int type, 42 perf_callback_t triggered, 43 struct task_struct *tsk, 44 bool active); 45 46 /* FIXME: only change from the attr, and don't unregister */ 47 extern struct perf_event * 48 modify_user_hw_breakpoint(struct perf_event *bp, 49 unsigned long addr, 50 int len, 51 int type, 52 perf_callback_t triggered, 53 struct task_struct *tsk, 54 bool active); 55 56 /* 57 * Kernel breakpoints are not associated with any particular thread. 58 */ 59 extern struct perf_event * 60 register_wide_hw_breakpoint_cpu(unsigned long addr, 61 int len, 62 int type, 63 perf_callback_t triggered, 64 int cpu, 65 bool active); 66 67 extern struct perf_event ** 68 register_wide_hw_breakpoint(unsigned long addr, 69 int len, 70 int type, 71 perf_callback_t triggered, 72 bool active); 73 74 extern int register_perf_hw_breakpoint(struct perf_event *bp); 75 extern int __register_perf_hw_breakpoint(struct perf_event *bp); 76 extern void unregister_hw_breakpoint(struct perf_event *bp); 77 extern void unregister_wide_hw_breakpoint(struct perf_event **cpu_events); 78 79 extern int reserve_bp_slot(struct perf_event *bp); 80 extern void release_bp_slot(struct perf_event *bp); 81 82 extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk); 83 84 static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) 85 { 86 return &bp->hw.info; 87 } 88 89 #else /* !CONFIG_HAVE_HW_BREAKPOINT */ 90 91 static inline struct perf_event * 92 register_user_hw_breakpoint(unsigned long addr, 93 int len, 94 int type, 95 perf_callback_t triggered, 96 struct task_struct *tsk, 97 bool active) { return NULL; } 98 static inline struct perf_event * 99 modify_user_hw_breakpoint(struct perf_event *bp, 100 unsigned long addr, 101 int len, 102 int type, 103 perf_callback_t triggered, 104 struct task_struct *tsk, 105 bool active) { return NULL; } 106 static inline struct perf_event * 107 register_wide_hw_breakpoint_cpu(unsigned long addr, 108 int len, 109 int type, 110 perf_callback_t triggered, 111 int cpu, 112 bool active) { return NULL; } 113 static inline struct perf_event ** 114 register_wide_hw_breakpoint(unsigned long addr, 115 int len, 116 int type, 117 perf_callback_t triggered, 118 bool active) { return NULL; } 119 static inline int 120 register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } 121 static inline int 122 __register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } 123 static inline void unregister_hw_breakpoint(struct perf_event *bp) { } 124 static inline void 125 unregister_wide_hw_breakpoint(struct perf_event **cpu_events) { } 126 static inline int 127 reserve_bp_slot(struct perf_event *bp) {return -ENOSYS; } 128 static inline void release_bp_slot(struct perf_event *bp) { } 129 130 static inline void flush_ptrace_hw_breakpoint(struct task_struct *tsk) { } 131 132 static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) 133 { 134 return NULL; 135 } 136 137 #endif /* CONFIG_HAVE_HW_BREAKPOINT */ 138 #endif /* __KERNEL__ */ 139 140 #endif /* _LINUX_HW_BREAKPOINT_H */ 141