hw_breakpoint.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #ifndef _LINUX_HW_BREAKPOINT_H
  2. #define _LINUX_HW_BREAKPOINT_H
  3. enum {
  4. HW_BREAKPOINT_LEN_1 = 1,
  5. HW_BREAKPOINT_LEN_2 = 2,
  6. HW_BREAKPOINT_LEN_4 = 4,
  7. HW_BREAKPOINT_LEN_8 = 8,
  8. };
  9. enum {
  10. HW_BREAKPOINT_R = 1,
  11. HW_BREAKPOINT_W = 2,
  12. HW_BREAKPOINT_X = 4,
  13. };
  14. #ifdef __KERNEL__
  15. #include <linux/perf_event.h>
  16. #ifdef CONFIG_HAVE_HW_BREAKPOINT
  17. static inline void hw_breakpoint_init(struct perf_event_attr *attr)
  18. {
  19. memset(attr, 0, sizeof(*attr));
  20. attr->type = PERF_TYPE_BREAKPOINT;
  21. attr->size = sizeof(*attr);
  22. /*
  23. * As it's for in-kernel or ptrace use, we want it to be pinned
  24. * and to call its callback every hits.
  25. */
  26. attr->pinned = 1;
  27. attr->sample_period = 1;
  28. }
  29. static inline unsigned long hw_breakpoint_addr(struct perf_event *bp)
  30. {
  31. return bp->attr.bp_addr;
  32. }
  33. static inline int hw_breakpoint_type(struct perf_event *bp)
  34. {
  35. return bp->attr.bp_type;
  36. }
  37. static inline int hw_breakpoint_len(struct perf_event *bp)
  38. {
  39. return bp->attr.bp_len;
  40. }
  41. extern struct perf_event *
  42. register_user_hw_breakpoint(struct perf_event_attr *attr,
  43. perf_overflow_handler_t triggered,
  44. struct task_struct *tsk);
  45. /* FIXME: only change from the attr, and don't unregister */
  46. extern int
  47. modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr);
  48. /*
  49. * Kernel breakpoints are not associated with any particular thread.
  50. */
  51. extern struct perf_event *
  52. register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
  53. perf_overflow_handler_t triggered,
  54. int cpu);
  55. extern struct perf_event **
  56. register_wide_hw_breakpoint(struct perf_event_attr *attr,
  57. perf_overflow_handler_t triggered);
  58. extern int register_perf_hw_breakpoint(struct perf_event *bp);
  59. extern int __register_perf_hw_breakpoint(struct perf_event *bp);
  60. extern void unregister_hw_breakpoint(struct perf_event *bp);
  61. extern void unregister_wide_hw_breakpoint(struct perf_event **cpu_events);
  62. extern int dbg_reserve_bp_slot(struct perf_event *bp);
  63. extern int dbg_release_bp_slot(struct perf_event *bp);
  64. extern int reserve_bp_slot(struct perf_event *bp);
  65. extern void release_bp_slot(struct perf_event *bp);
  66. extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
  67. static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
  68. {
  69. return &bp->hw.info;
  70. }
  71. #else /* !CONFIG_HAVE_HW_BREAKPOINT */
  72. static inline struct perf_event *
  73. register_user_hw_breakpoint(struct perf_event_attr *attr,
  74. perf_overflow_handler_t triggered,
  75. struct task_struct *tsk) { return NULL; }
  76. static inline int
  77. modify_user_hw_breakpoint(struct perf_event *bp,
  78. struct perf_event_attr *attr) { return -ENOSYS; }
  79. static inline struct perf_event *
  80. register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
  81. perf_overflow_handler_t triggered,
  82. int cpu) { return NULL; }
  83. static inline struct perf_event **
  84. register_wide_hw_breakpoint(struct perf_event_attr *attr,
  85. perf_overflow_handler_t triggered) { return NULL; }
  86. static inline int
  87. register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; }
  88. static inline int
  89. __register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; }
  90. static inline void unregister_hw_breakpoint(struct perf_event *bp) { }
  91. static inline void
  92. unregister_wide_hw_breakpoint(struct perf_event **cpu_events) { }
  93. static inline int
  94. reserve_bp_slot(struct perf_event *bp) {return -ENOSYS; }
  95. static inline void release_bp_slot(struct perf_event *bp) { }
  96. static inline void flush_ptrace_hw_breakpoint(struct task_struct *tsk) { }
  97. static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
  98. {
  99. return NULL;
  100. }
  101. #endif /* CONFIG_HAVE_HW_BREAKPOINT */
  102. #endif /* __KERNEL__ */
  103. #endif /* _LINUX_HW_BREAKPOINT_H */