hw_breakpoint.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. /* As it's for in-kernel or ptrace use, we want it to be pinned */
  18. #define DEFINE_BREAKPOINT_ATTR(name) \
  19. struct perf_event_attr name = { \
  20. .type = PERF_TYPE_BREAKPOINT, \
  21. .size = sizeof(name), \
  22. .pinned = 1, \
  23. };
  24. static inline unsigned long hw_breakpoint_addr(struct perf_event *bp)
  25. {
  26. return bp->attr.bp_addr;
  27. }
  28. static inline int hw_breakpoint_type(struct perf_event *bp)
  29. {
  30. return bp->attr.bp_type;
  31. }
  32. static inline int hw_breakpoint_len(struct perf_event *bp)
  33. {
  34. return bp->attr.bp_len;
  35. }
  36. extern struct perf_event *
  37. register_user_hw_breakpoint(struct perf_event_attr *attr,
  38. perf_callback_t triggered,
  39. struct task_struct *tsk);
  40. /* FIXME: only change from the attr, and don't unregister */
  41. extern struct perf_event *
  42. modify_user_hw_breakpoint(struct perf_event *bp,
  43. struct perf_event_attr *attr,
  44. perf_callback_t triggered,
  45. struct task_struct *tsk);
  46. /*
  47. * Kernel breakpoints are not associated with any particular thread.
  48. */
  49. extern struct perf_event *
  50. register_wide_hw_breakpoint_cpu(unsigned long addr,
  51. int len,
  52. int type,
  53. perf_callback_t triggered,
  54. int cpu,
  55. bool active);
  56. extern struct perf_event **
  57. register_wide_hw_breakpoint(unsigned long addr,
  58. int len,
  59. int type,
  60. perf_callback_t triggered,
  61. bool active);
  62. extern int register_perf_hw_breakpoint(struct perf_event *bp);
  63. extern int __register_perf_hw_breakpoint(struct perf_event *bp);
  64. extern void unregister_hw_breakpoint(struct perf_event *bp);
  65. extern void unregister_wide_hw_breakpoint(struct perf_event **cpu_events);
  66. extern int reserve_bp_slot(struct perf_event *bp);
  67. extern void release_bp_slot(struct perf_event *bp);
  68. extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
  69. static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
  70. {
  71. return &bp->hw.info;
  72. }
  73. #else /* !CONFIG_HAVE_HW_BREAKPOINT */
  74. static inline struct perf_event *
  75. register_user_hw_breakpoint(struct perf_event_attr *attr,
  76. perf_callback_t triggered,
  77. struct task_struct *tsk) { return NULL; }
  78. static inline struct perf_event *
  79. modify_user_hw_breakpoint(struct perf_event *bp,
  80. struct perf_event_attr *attr,
  81. perf_callback_t triggered,
  82. struct task_struct *tsk) { return NULL; }
  83. static inline struct perf_event *
  84. register_wide_hw_breakpoint_cpu(unsigned long addr,
  85. int len,
  86. int type,
  87. perf_callback_t triggered,
  88. int cpu,
  89. bool active) { return NULL; }
  90. static inline struct perf_event **
  91. register_wide_hw_breakpoint(unsigned long addr,
  92. int len,
  93. int type,
  94. perf_callback_t triggered,
  95. bool active) { return NULL; }
  96. static inline int
  97. register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; }
  98. static inline int
  99. __register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; }
  100. static inline void unregister_hw_breakpoint(struct perf_event *bp) { }
  101. static inline void
  102. unregister_wide_hw_breakpoint(struct perf_event **cpu_events) { }
  103. static inline int
  104. reserve_bp_slot(struct perf_event *bp) {return -ENOSYS; }
  105. static inline void release_bp_slot(struct perf_event *bp) { }
  106. static inline void flush_ptrace_hw_breakpoint(struct task_struct *tsk) { }
  107. static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
  108. {
  109. return NULL;
  110. }
  111. #endif /* CONFIG_HAVE_HW_BREAKPOINT */
  112. #endif /* __KERNEL__ */
  113. #endif /* _LINUX_HW_BREAKPOINT_H */