1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 #ifndef _LINUX_UPROBES_H 3 #define _LINUX_UPROBES_H 4 /* 5 * User-space Probes (UProbes) 6 * 7 * Copyright (C) IBM Corporation, 2008-2012 8 * Authors: 9 * Srikar Dronamraju 10 * Jim Keniston 11 * Copyright (C) 2011-2012 Red Hat, Inc., Peter Zijlstra 12 */ 13 14 #include <linux/errno.h> 15 #include <linux/rbtree.h> 16 #include <linux/types.h> 17 #include <linux/wait.h> 18 19 struct vm_area_struct; 20 struct mm_struct; 21 struct inode; 22 struct notifier_block; 23 struct page; 24 25 #define UPROBE_HANDLER_REMOVE 1 26 #define UPROBE_HANDLER_MASK 1 27 28 #define MAX_URETPROBE_DEPTH 64 29 30 enum uprobe_filter_ctx { 31 UPROBE_FILTER_REGISTER, 32 UPROBE_FILTER_UNREGISTER, 33 UPROBE_FILTER_MMAP, 34 }; 35 36 struct uprobe_consumer { 37 int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs); 38 int (*ret_handler)(struct uprobe_consumer *self, 39 unsigned long func, 40 struct pt_regs *regs); 41 bool (*filter)(struct uprobe_consumer *self, 42 enum uprobe_filter_ctx ctx, 43 struct mm_struct *mm); 44 45 struct uprobe_consumer *next; 46 }; 47 48 #ifdef CONFIG_UPROBES 49 #include <asm/uprobes.h> 50 51 enum uprobe_task_state { 52 UTASK_RUNNING, 53 UTASK_SSTEP, 54 UTASK_SSTEP_ACK, 55 UTASK_SSTEP_TRAPPED, 56 }; 57 58 /* 59 * uprobe_task: Metadata of a task while it singlesteps. 60 */ 61 struct uprobe_task { 62 enum uprobe_task_state state; 63 64 union { 65 struct { 66 struct arch_uprobe_task autask; 67 unsigned long vaddr; 68 }; 69 70 struct { 71 struct callback_head dup_xol_work; 72 unsigned long dup_xol_addr; 73 }; 74 }; 75 76 struct uprobe *active_uprobe; 77 unsigned long xol_vaddr; 78 79 struct return_instance *return_instances; 80 unsigned int depth; 81 }; 82 83 struct return_instance { 84 struct uprobe *uprobe; 85 unsigned long func; 86 unsigned long stack; /* stack pointer */ 87 unsigned long orig_ret_vaddr; /* original return address */ 88 bool chained; /* true, if instance is nested */ 89 90 struct return_instance *next; /* keep as stack */ 91 }; 92 93 enum rp_check { 94 RP_CHECK_CALL, 95 RP_CHECK_CHAIN_CALL, 96 RP_CHECK_RET, 97 }; 98 99 struct xol_area; 100 101 struct uprobes_state { 102 struct xol_area *xol_area; 103 }; 104 105 extern void __init uprobes_init(void); 106 extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); 107 extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); 108 extern bool is_swbp_insn(uprobe_opcode_t *insn); 109 extern bool is_trap_insn(uprobe_opcode_t *insn); 110 extern unsigned long uprobe_get_swbp_addr(struct pt_regs *regs); 111 extern unsigned long uprobe_get_trap_addr(struct pt_regs *regs); 112 extern int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t); 113 extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); 114 extern int uprobe_register_refctr(struct inode *inode, loff_t offset, loff_t ref_ctr_offset, struct uprobe_consumer *uc); 115 extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool); 116 extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); 117 extern int uprobe_mmap(struct vm_area_struct *vma); 118 extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); 119 extern void uprobe_start_dup_mmap(void); 120 extern void uprobe_end_dup_mmap(void); 121 extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm); 122 extern void uprobe_free_utask(struct task_struct *t); 123 extern void uprobe_copy_process(struct task_struct *t, unsigned long flags); 124 extern int uprobe_post_sstep_notifier(struct pt_regs *regs); 125 extern int uprobe_pre_sstep_notifier(struct pt_regs *regs); 126 extern void uprobe_notify_resume(struct pt_regs *regs); 127 extern bool uprobe_deny_signal(void); 128 extern bool arch_uprobe_skip_sstep(struct arch_uprobe *aup, struct pt_regs *regs); 129 extern void uprobe_clear_state(struct mm_struct *mm); 130 extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); 131 extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); 132 extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); 133 extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); 134 extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); 135 extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); 136 extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs); 137 extern bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, struct pt_regs *regs); 138 extern bool arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs); 139 extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, 140 void *src, unsigned long len); 141 #else /* !CONFIG_UPROBES */ 142 struct uprobes_state { 143 }; 144 145 static inline void uprobes_init(void) 146 { 147 } 148 149 #define uprobe_get_trap_addr(regs) instruction_pointer(regs) 150 151 static inline int 152 uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) 153 { 154 return -ENOSYS; 155 } 156 static inline int uprobe_register_refctr(struct inode *inode, loff_t offset, loff_t ref_ctr_offset, struct uprobe_consumer *uc) 157 { 158 return -ENOSYS; 159 } 160 static inline int 161 uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool add) 162 { 163 return -ENOSYS; 164 } 165 static inline void 166 uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) 167 { 168 } 169 static inline int uprobe_mmap(struct vm_area_struct *vma) 170 { 171 return 0; 172 } 173 static inline void 174 uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end) 175 { 176 } 177 static inline void uprobe_start_dup_mmap(void) 178 { 179 } 180 static inline void uprobe_end_dup_mmap(void) 181 { 182 } 183 static inline void 184 uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) 185 { 186 } 187 static inline void uprobe_notify_resume(struct pt_regs *regs) 188 { 189 } 190 static inline bool uprobe_deny_signal(void) 191 { 192 return false; 193 } 194 static inline void uprobe_free_utask(struct task_struct *t) 195 { 196 } 197 static inline void uprobe_copy_process(struct task_struct *t, unsigned long flags) 198 { 199 } 200 static inline void uprobe_clear_state(struct mm_struct *mm) 201 { 202 } 203 #endif /* !CONFIG_UPROBES */ 204 #endif /* _LINUX_UPROBES_H */ 205