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 <prasad@linux.vnet.ibm.com> 7 */ 8 9 #ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H 10 #define _PPC_BOOK3S_64_HW_BREAKPOINT_H 11 12 #ifdef __KERNEL__ 13 struct arch_hw_breakpoint { 14 unsigned long address; 15 u16 type; 16 u16 len; /* length of the target data symbol */ 17 }; 18 19 /* Note: Don't change the 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 30 /* bits that overlap with the bottom 3 bits of the dabr */ 31 #define HW_BRK_TYPE_RDWR (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE) 32 #define HW_BRK_TYPE_DABR (HW_BRK_TYPE_RDWR | HW_BRK_TYPE_TRANSLATE) 33 #define HW_BRK_TYPE_PRIV_ALL (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \ 34 HW_BRK_TYPE_HYP) 35 36 #ifdef CONFIG_HAVE_HW_BREAKPOINT 37 #include <linux/kdebug.h> 38 #include <asm/reg.h> 39 #include <asm/debug.h> 40 41 struct perf_event_attr; 42 struct perf_event; 43 struct pmu; 44 struct perf_sample_data; 45 struct task_struct; 46 47 #define HW_BREAKPOINT_ALIGN 0x7 48 49 extern int hw_breakpoint_slots(int type); 50 extern int arch_bp_generic_fields(int type, int *gen_bp_type); 51 extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw); 52 extern int hw_breakpoint_arch_parse(struct perf_event *bp, 53 const struct perf_event_attr *attr, 54 struct arch_hw_breakpoint *hw); 55 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, 56 unsigned long val, void *data); 57 int arch_install_hw_breakpoint(struct perf_event *bp); 58 void arch_uninstall_hw_breakpoint(struct perf_event *bp); 59 void arch_unregister_hw_breakpoint(struct perf_event *bp); 60 void hw_breakpoint_pmu_read(struct perf_event *bp); 61 extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk); 62 63 extern struct pmu perf_ops_bp; 64 extern void ptrace_triggered(struct perf_event *bp, 65 struct perf_sample_data *data, struct pt_regs *regs); 66 static inline void hw_breakpoint_disable(void) 67 { 68 struct arch_hw_breakpoint brk; 69 70 brk.address = 0; 71 brk.type = 0; 72 brk.len = 0; 73 if (ppc_breakpoint_available()) 74 __set_breakpoint(&brk); 75 } 76 extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs); 77 int hw_breakpoint_handler(struct die_args *args); 78 79 #else /* CONFIG_HAVE_HW_BREAKPOINT */ 80 static inline void hw_breakpoint_disable(void) { } 81 static inline void thread_change_pc(struct task_struct *tsk, 82 struct pt_regs *regs) { } 83 84 #endif /* CONFIG_HAVE_HW_BREAKPOINT */ 85 86 87 #ifdef CONFIG_PPC_DAWR 88 extern bool dawr_force_enable; 89 static inline bool dawr_enabled(void) 90 { 91 return dawr_force_enable; 92 } 93 int set_dawr(struct arch_hw_breakpoint *brk); 94 #else 95 static inline bool dawr_enabled(void) { return false; } 96 static inline int set_dawr(struct arch_hw_breakpoint *brk) { return -1; } 97 #endif 98 99 #endif /* __KERNEL__ */ 100 #endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */ 101