Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _LINUX_HW_BREAKPOINT_H
0003 #define _LINUX_HW_BREAKPOINT_H
0004 
0005 #include <linux/perf_event.h>
0006 #include <uapi/linux/hw_breakpoint.h>
0007 
0008 #ifdef CONFIG_HAVE_HW_BREAKPOINT
0009 
0010 extern int __init init_hw_breakpoint(void);
0011 
0012 static inline void hw_breakpoint_init(struct perf_event_attr *attr)
0013 {
0014     memset(attr, 0, sizeof(*attr));
0015 
0016     attr->type = PERF_TYPE_BREAKPOINT;
0017     attr->size = sizeof(*attr);
0018     /*
0019      * As it's for in-kernel or ptrace use, we want it to be pinned
0020      * and to call its callback every hits.
0021      */
0022     attr->pinned = 1;
0023     attr->sample_period = 1;
0024 }
0025 
0026 static inline void ptrace_breakpoint_init(struct perf_event_attr *attr)
0027 {
0028     hw_breakpoint_init(attr);
0029     attr->exclude_kernel = 1;
0030 }
0031 
0032 static inline unsigned long hw_breakpoint_addr(struct perf_event *bp)
0033 {
0034     return bp->attr.bp_addr;
0035 }
0036 
0037 static inline int hw_breakpoint_type(struct perf_event *bp)
0038 {
0039     return bp->attr.bp_type;
0040 }
0041 
0042 static inline unsigned long hw_breakpoint_len(struct perf_event *bp)
0043 {
0044     return bp->attr.bp_len;
0045 }
0046 
0047 extern struct perf_event *
0048 register_user_hw_breakpoint(struct perf_event_attr *attr,
0049                 perf_overflow_handler_t triggered,
0050                 void *context,
0051                 struct task_struct *tsk);
0052 
0053 /* FIXME: only change from the attr, and don't unregister */
0054 extern int
0055 modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr);
0056 extern int
0057 modify_user_hw_breakpoint_check(struct perf_event *bp, struct perf_event_attr *attr,
0058                 bool check);
0059 
0060 /*
0061  * Kernel breakpoints are not associated with any particular thread.
0062  */
0063 extern struct perf_event *
0064 register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
0065                 perf_overflow_handler_t triggered,
0066                 void *context,
0067                 int cpu);
0068 
0069 extern struct perf_event * __percpu *
0070 register_wide_hw_breakpoint(struct perf_event_attr *attr,
0071                 perf_overflow_handler_t triggered,
0072                 void *context);
0073 
0074 extern int register_perf_hw_breakpoint(struct perf_event *bp);
0075 extern void unregister_hw_breakpoint(struct perf_event *bp);
0076 extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events);
0077 
0078 extern int dbg_reserve_bp_slot(struct perf_event *bp);
0079 extern int dbg_release_bp_slot(struct perf_event *bp);
0080 extern int reserve_bp_slot(struct perf_event *bp);
0081 extern void release_bp_slot(struct perf_event *bp);
0082 int hw_breakpoint_weight(struct perf_event *bp);
0083 int arch_reserve_bp_slot(struct perf_event *bp);
0084 void arch_release_bp_slot(struct perf_event *bp);
0085 void arch_unregister_hw_breakpoint(struct perf_event *bp);
0086 
0087 extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
0088 
0089 static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
0090 {
0091     return &bp->hw.info;
0092 }
0093 
0094 #else /* !CONFIG_HAVE_HW_BREAKPOINT */
0095 
0096 static inline int __init init_hw_breakpoint(void) { return 0; }
0097 
0098 static inline struct perf_event *
0099 register_user_hw_breakpoint(struct perf_event_attr *attr,
0100                 perf_overflow_handler_t triggered,
0101                 void *context,
0102                 struct task_struct *tsk)    { return NULL; }
0103 static inline int
0104 modify_user_hw_breakpoint(struct perf_event *bp,
0105               struct perf_event_attr *attr) { return -ENOSYS; }
0106 static inline int
0107 modify_user_hw_breakpoint_check(struct perf_event *bp, struct perf_event_attr *attr,
0108                 bool check) { return -ENOSYS; }
0109 
0110 static inline struct perf_event *
0111 register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
0112                 perf_overflow_handler_t  triggered,
0113                 void *context,
0114                 int cpu)        { return NULL; }
0115 static inline struct perf_event * __percpu *
0116 register_wide_hw_breakpoint(struct perf_event_attr *attr,
0117                 perf_overflow_handler_t triggered,
0118                 void *context)      { return NULL; }
0119 static inline int
0120 register_perf_hw_breakpoint(struct perf_event *bp)  { return -ENOSYS; }
0121 static inline void unregister_hw_breakpoint(struct perf_event *bp)  { }
0122 static inline void
0123 unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events) { }
0124 static inline int
0125 reserve_bp_slot(struct perf_event *bp)          {return -ENOSYS; }
0126 static inline void release_bp_slot(struct perf_event *bp)       { }
0127 
0128 static inline void flush_ptrace_hw_breakpoint(struct task_struct *tsk)  { }
0129 
0130 static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
0131 {
0132     return NULL;
0133 }
0134 
0135 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
0136 #endif /* _LINUX_HW_BREAKPOINT_H */