hw_breakpoint.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _LINUX_HW_BREAKPOINT_H
  3. #define _LINUX_HW_BREAKPOINT_H
  4. #include <linux/perf_event.h>
  5. #include <uapi/linux/hw_breakpoint.h>
  6. #ifdef CONFIG_HAVE_HW_BREAKPOINT
  7. extern int __init init_hw_breakpoint(void);
  8. static inline void hw_breakpoint_init(struct perf_event_attr *attr)
  9. {
  10. memset(attr, 0, sizeof(*attr));
  11. attr->type = PERF_TYPE_BREAKPOINT;
  12. attr->size = sizeof(*attr);
  13. /*
  14. * As it's for in-kernel or ptrace use, we want it to be pinned
  15. * and to call its callback every hits.
  16. */
  17. attr->pinned = 1;
  18. attr->sample_period = 1;
  19. }
  20. static inline void ptrace_breakpoint_init(struct perf_event_attr *attr)
  21. {
  22. hw_breakpoint_init(attr);
  23. attr->exclude_kernel = 1;
  24. }
  25. static inline unsigned long hw_breakpoint_addr(struct perf_event *bp)
  26. {
  27. return bp->attr.bp_addr;
  28. }
  29. static inline int hw_breakpoint_type(struct perf_event *bp)
  30. {
  31. return bp->attr.bp_type;
  32. }
  33. static inline unsigned long hw_breakpoint_len(struct perf_event *bp)
  34. {
  35. return bp->attr.bp_len;
  36. }
  37. extern struct perf_event *
  38. register_user_hw_breakpoint(struct perf_event_attr *attr,
  39. perf_overflow_handler_t triggered,
  40. void *context,
  41. struct task_struct *tsk);
  42. /* FIXME: only change from the attr, and don't unregister */
  43. extern int
  44. modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr);
  45. extern int
  46. modify_user_hw_breakpoint_check(struct perf_event *bp, struct perf_event_attr *attr,
  47. bool check);
  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. void *context,
  55. int cpu);
  56. extern struct perf_event * __percpu *
  57. register_wide_hw_breakpoint(struct perf_event_attr *attr,
  58. perf_overflow_handler_t triggered,
  59. void *context);
  60. extern int register_perf_hw_breakpoint(struct perf_event *bp);
  61. extern void unregister_hw_breakpoint(struct perf_event *bp);
  62. extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events);
  63. extern int dbg_reserve_bp_slot(struct perf_event *bp);
  64. extern int dbg_release_bp_slot(struct perf_event *bp);
  65. extern int reserve_bp_slot(struct perf_event *bp);
  66. extern void release_bp_slot(struct perf_event *bp);
  67. int hw_breakpoint_weight(struct perf_event *bp);
  68. int arch_reserve_bp_slot(struct perf_event *bp);
  69. void arch_release_bp_slot(struct perf_event *bp);
  70. void arch_unregister_hw_breakpoint(struct perf_event *bp);
  71. extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
  72. static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
  73. {
  74. return &bp->hw.info;
  75. }
  76. #else /* !CONFIG_HAVE_HW_BREAKPOINT */
  77. static inline int __init init_hw_breakpoint(void) { return 0; }
  78. static inline struct perf_event *
  79. register_user_hw_breakpoint(struct perf_event_attr *attr,
  80. perf_overflow_handler_t triggered,
  81. void *context,
  82. struct task_struct *tsk) { return NULL; }
  83. static inline int
  84. modify_user_hw_breakpoint(struct perf_event *bp,
  85. struct perf_event_attr *attr) { return -ENOSYS; }
  86. static inline int
  87. modify_user_hw_breakpoint_check(struct perf_event *bp, struct perf_event_attr *attr,
  88. bool check) { return -ENOSYS; }
  89. static inline struct perf_event *
  90. register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
  91. perf_overflow_handler_t triggered,
  92. void *context,
  93. int cpu) { return NULL; }
  94. static inline struct perf_event * __percpu *
  95. register_wide_hw_breakpoint(struct perf_event_attr *attr,
  96. perf_overflow_handler_t triggered,
  97. void *context) { return NULL; }
  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 * __percpu *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 /* _LINUX_HW_BREAKPOINT_H */