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