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