hw_breakpoint.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * PowerPC BookIII S hardware breakpoint definitions
  4. *
  5. * Copyright 2010, IBM Corporation.
  6. * Author: K.Prasad <[email protected]>
  7. */
  8. #ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
  9. #define _PPC_BOOK3S_64_HW_BREAKPOINT_H
  10. #include <asm/cpu_has_feature.h>
  11. #ifdef __KERNEL__
  12. struct arch_hw_breakpoint {
  13. unsigned long address;
  14. u16 type;
  15. u16 len; /* length of the target data symbol */
  16. u16 hw_len; /* length programmed in hw */
  17. u8 flags;
  18. };
  19. /* Note: Don't change the first 6 bits below as they are in the same order
  20. * as the dabr and dabrx.
  21. */
  22. #define HW_BRK_TYPE_READ 0x01
  23. #define HW_BRK_TYPE_WRITE 0x02
  24. #define HW_BRK_TYPE_TRANSLATE 0x04
  25. #define HW_BRK_TYPE_USER 0x08
  26. #define HW_BRK_TYPE_KERNEL 0x10
  27. #define HW_BRK_TYPE_HYP 0x20
  28. #define HW_BRK_TYPE_EXTRANEOUS_IRQ 0x80
  29. /* bits that overlap with the bottom 3 bits of the dabr */
  30. #define HW_BRK_TYPE_RDWR (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE)
  31. #define HW_BRK_TYPE_DABR (HW_BRK_TYPE_RDWR | HW_BRK_TYPE_TRANSLATE)
  32. #define HW_BRK_TYPE_PRIV_ALL (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \
  33. HW_BRK_TYPE_HYP)
  34. #define HW_BRK_FLAG_DISABLED 0x1
  35. /* Minimum granularity */
  36. #ifdef CONFIG_PPC_8xx
  37. #define HW_BREAKPOINT_SIZE 0x4
  38. #else
  39. #define HW_BREAKPOINT_SIZE 0x8
  40. #endif
  41. #define HW_BREAKPOINT_SIZE_QUADWORD 0x10
  42. #define DABR_MAX_LEN 8
  43. #define DAWR_MAX_LEN 512
  44. static inline int nr_wp_slots(void)
  45. {
  46. return cpu_has_feature(CPU_FTR_DAWR1) ? 2 : 1;
  47. }
  48. bool wp_check_constraints(struct pt_regs *regs, ppc_inst_t instr,
  49. unsigned long ea, int type, int size,
  50. struct arch_hw_breakpoint *info);
  51. void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr,
  52. int *type, int *size, unsigned long *ea);
  53. #ifdef CONFIG_HAVE_HW_BREAKPOINT
  54. #include <linux/kdebug.h>
  55. #include <asm/reg.h>
  56. #include <asm/debug.h>
  57. struct perf_event_attr;
  58. struct perf_event;
  59. struct pmu;
  60. struct perf_sample_data;
  61. struct task_struct;
  62. extern int hw_breakpoint_slots(int type);
  63. extern int arch_bp_generic_fields(int type, int *gen_bp_type);
  64. extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
  65. extern int hw_breakpoint_arch_parse(struct perf_event *bp,
  66. const struct perf_event_attr *attr,
  67. struct arch_hw_breakpoint *hw);
  68. extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
  69. unsigned long val, void *data);
  70. int arch_install_hw_breakpoint(struct perf_event *bp);
  71. void arch_uninstall_hw_breakpoint(struct perf_event *bp);
  72. void hw_breakpoint_pmu_read(struct perf_event *bp);
  73. extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
  74. extern struct pmu perf_ops_bp;
  75. extern void ptrace_triggered(struct perf_event *bp,
  76. struct perf_sample_data *data, struct pt_regs *regs);
  77. static inline void hw_breakpoint_disable(void)
  78. {
  79. int i;
  80. struct arch_hw_breakpoint null_brk = {0};
  81. if (!ppc_breakpoint_available())
  82. return;
  83. for (i = 0; i < nr_wp_slots(); i++)
  84. __set_breakpoint(i, &null_brk);
  85. }
  86. extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
  87. int hw_breakpoint_handler(struct die_args *args);
  88. #else /* CONFIG_HAVE_HW_BREAKPOINT */
  89. static inline void hw_breakpoint_disable(void) { }
  90. static inline void thread_change_pc(struct task_struct *tsk,
  91. struct pt_regs *regs) { }
  92. #endif /* CONFIG_HAVE_HW_BREAKPOINT */
  93. #ifdef CONFIG_PPC_DAWR
  94. extern bool dawr_force_enable;
  95. static inline bool dawr_enabled(void)
  96. {
  97. return dawr_force_enable;
  98. }
  99. int set_dawr(int nr, struct arch_hw_breakpoint *brk);
  100. #else
  101. static inline bool dawr_enabled(void) { return false; }
  102. static inline int set_dawr(int nr, struct arch_hw_breakpoint *brk) { return -1; }
  103. #endif
  104. #endif /* __KERNEL__ */
  105. #endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */