12b144498SSrikar Dronamraju #ifndef _LINUX_UPROBES_H 22b144498SSrikar Dronamraju #define _LINUX_UPROBES_H 32b144498SSrikar Dronamraju /* 47b2d81d4SIngo Molnar * User-space Probes (UProbes) 52b144498SSrikar Dronamraju * 62b144498SSrikar Dronamraju * This program is free software; you can redistribute it and/or modify 72b144498SSrikar Dronamraju * it under the terms of the GNU General Public License as published by 82b144498SSrikar Dronamraju * the Free Software Foundation; either version 2 of the License, or 92b144498SSrikar Dronamraju * (at your option) any later version. 102b144498SSrikar Dronamraju * 112b144498SSrikar Dronamraju * This program is distributed in the hope that it will be useful, 122b144498SSrikar Dronamraju * but WITHOUT ANY WARRANTY; without even the implied warranty of 132b144498SSrikar Dronamraju * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 142b144498SSrikar Dronamraju * GNU General Public License for more details. 152b144498SSrikar Dronamraju * 162b144498SSrikar Dronamraju * You should have received a copy of the GNU General Public License 172b144498SSrikar Dronamraju * along with this program; if not, write to the Free Software 182b144498SSrikar Dronamraju * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 192b144498SSrikar Dronamraju * 2035aa621bSIngo Molnar * Copyright (C) IBM Corporation, 2008-2012 212b144498SSrikar Dronamraju * Authors: 222b144498SSrikar Dronamraju * Srikar Dronamraju 232b144498SSrikar Dronamraju * Jim Keniston 2435aa621bSIngo Molnar * Copyright (C) 2011-2012 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com> 252b144498SSrikar Dronamraju */ 262b144498SSrikar Dronamraju 272b144498SSrikar Dronamraju #include <linux/errno.h> 282b144498SSrikar Dronamraju #include <linux/rbtree.h> 2932473431SOleg Nesterov #include <linux/types.h> 302b144498SSrikar Dronamraju 312b144498SSrikar Dronamraju struct vm_area_struct; 32d4b3b638SSrikar Dronamraju struct mm_struct; 33d4b3b638SSrikar Dronamraju struct inode; 343820b4d2SDavid A. Long struct notifier_block; 350326f5a9SSrikar Dronamraju 36da1816b1SOleg Nesterov #define UPROBE_HANDLER_REMOVE 1 37da1816b1SOleg Nesterov #define UPROBE_HANDLER_MASK 1 38da1816b1SOleg Nesterov 39ded49c55SAnton Arapov #define MAX_URETPROBE_DEPTH 64 40ded49c55SAnton Arapov 418a7f2fa0SOleg Nesterov enum uprobe_filter_ctx { 428a7f2fa0SOleg Nesterov UPROBE_FILTER_REGISTER, 438a7f2fa0SOleg Nesterov UPROBE_FILTER_UNREGISTER, 448a7f2fa0SOleg Nesterov UPROBE_FILTER_MMAP, 458a7f2fa0SOleg Nesterov }; 468a7f2fa0SOleg Nesterov 472b144498SSrikar Dronamraju struct uprobe_consumer { 482b144498SSrikar Dronamraju int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs); 49ea024870SAnton Arapov int (*ret_handler)(struct uprobe_consumer *self, 50ea024870SAnton Arapov unsigned long func, 51ea024870SAnton Arapov struct pt_regs *regs); 528a7f2fa0SOleg Nesterov bool (*filter)(struct uprobe_consumer *self, 538a7f2fa0SOleg Nesterov enum uprobe_filter_ctx ctx, 548a7f2fa0SOleg Nesterov struct mm_struct *mm); 552b144498SSrikar Dronamraju 562b144498SSrikar Dronamraju struct uprobe_consumer *next; 572b144498SSrikar Dronamraju }; 582b144498SSrikar Dronamraju 592b144498SSrikar Dronamraju #ifdef CONFIG_UPROBES 60*c912dae6SOleg Nesterov #include <asm/uprobes.h> 61*c912dae6SOleg Nesterov 620326f5a9SSrikar Dronamraju enum uprobe_task_state { 630326f5a9SSrikar Dronamraju UTASK_RUNNING, 640326f5a9SSrikar Dronamraju UTASK_SSTEP, 650326f5a9SSrikar Dronamraju UTASK_SSTEP_ACK, 660326f5a9SSrikar Dronamraju UTASK_SSTEP_TRAPPED, 670326f5a9SSrikar Dronamraju }; 680326f5a9SSrikar Dronamraju 690326f5a9SSrikar Dronamraju /* 700326f5a9SSrikar Dronamraju * uprobe_task: Metadata of a task while it singlesteps. 710326f5a9SSrikar Dronamraju */ 720326f5a9SSrikar Dronamraju struct uprobe_task { 730326f5a9SSrikar Dronamraju enum uprobe_task_state state; 7432473431SOleg Nesterov 7532473431SOleg Nesterov union { 7632473431SOleg Nesterov struct { 770326f5a9SSrikar Dronamraju struct arch_uprobe_task autask; 7832473431SOleg Nesterov unsigned long vaddr; 7932473431SOleg Nesterov }; 8032473431SOleg Nesterov 8132473431SOleg Nesterov struct { 8232473431SOleg Nesterov struct callback_head dup_xol_work; 8332473431SOleg Nesterov unsigned long dup_xol_addr; 8432473431SOleg Nesterov }; 8532473431SOleg Nesterov }; 8632473431SOleg Nesterov 8732473431SOleg Nesterov struct uprobe *active_uprobe; 8832473431SOleg Nesterov unsigned long xol_vaddr; 890326f5a9SSrikar Dronamraju 900dfd0eb8SAnton Arapov struct return_instance *return_instances; 91ded49c55SAnton Arapov unsigned int depth; 920326f5a9SSrikar Dronamraju }; 930326f5a9SSrikar Dronamraju 94*c912dae6SOleg Nesterov struct xol_area; 95d4b3b638SSrikar Dronamraju 96d4b3b638SSrikar Dronamraju struct uprobes_state { 97d4b3b638SSrikar Dronamraju struct xol_area *xol_area; 98d4b3b638SSrikar Dronamraju }; 99647c42dfSOleg Nesterov 1005cb4ac3aSSrikar Dronamraju extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); 101ded86e7cSOleg Nesterov extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); 1025cb4ac3aSSrikar Dronamraju extern bool __weak is_swbp_insn(uprobe_opcode_t *insn); 1030908ad6eSAnanth N Mavinakayanahalli extern bool __weak is_trap_insn(uprobe_opcode_t *insn); 104*c912dae6SOleg Nesterov extern unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs); 105f72d41faSOleg Nesterov extern int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t); 106e3343e6aSSrikar Dronamraju extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); 107bdf8647cSOleg Nesterov extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool); 108e3343e6aSSrikar Dronamraju extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); 1097b2d81d4SIngo Molnar extern int uprobe_mmap(struct vm_area_struct *vma); 110cbc91f71SSrikar Dronamraju extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); 11132cdba1eSOleg Nesterov extern void uprobe_start_dup_mmap(void); 11232cdba1eSOleg Nesterov extern void uprobe_end_dup_mmap(void); 113f8ac4ec9SOleg Nesterov extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm); 1140326f5a9SSrikar Dronamraju extern void uprobe_free_utask(struct task_struct *t); 1153ab67966SOleg Nesterov extern void uprobe_copy_process(struct task_struct *t, unsigned long flags); 1160326f5a9SSrikar Dronamraju extern int uprobe_post_sstep_notifier(struct pt_regs *regs); 1170326f5a9SSrikar Dronamraju extern int uprobe_pre_sstep_notifier(struct pt_regs *regs); 1180326f5a9SSrikar Dronamraju extern void uprobe_notify_resume(struct pt_regs *regs); 1190326f5a9SSrikar Dronamraju extern bool uprobe_deny_signal(void); 120c2d3f25dSRalf Baechle extern bool arch_uprobe_skip_sstep(struct arch_uprobe *aup, struct pt_regs *regs); 121d4b3b638SSrikar Dronamraju extern void uprobe_clear_state(struct mm_struct *mm); 1223820b4d2SDavid A. Long extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); 1233820b4d2SDavid A. Long extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); 1243820b4d2SDavid A. Long extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); 1253820b4d2SDavid A. Long extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); 1263820b4d2SDavid A. Long extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); 1273820b4d2SDavid A. Long extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); 1283820b4d2SDavid A. Long extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs); 1290326f5a9SSrikar Dronamraju #else /* !CONFIG_UPROBES */ 130d4b3b638SSrikar Dronamraju struct uprobes_state { 131d4b3b638SSrikar Dronamraju }; 1327b2d81d4SIngo Molnar static inline int 133e3343e6aSSrikar Dronamraju uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) 1342b144498SSrikar Dronamraju { 1352b144498SSrikar Dronamraju return -ENOSYS; 1362b144498SSrikar Dronamraju } 137bdf8647cSOleg Nesterov static inline int 138bdf8647cSOleg Nesterov uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool add) 139bdf8647cSOleg Nesterov { 140bdf8647cSOleg Nesterov return -ENOSYS; 141bdf8647cSOleg Nesterov } 1427b2d81d4SIngo Molnar static inline void 143e3343e6aSSrikar Dronamraju uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) 1442b144498SSrikar Dronamraju { 1452b144498SSrikar Dronamraju } 1467b2d81d4SIngo Molnar static inline int uprobe_mmap(struct vm_area_struct *vma) 1472b144498SSrikar Dronamraju { 1482b144498SSrikar Dronamraju return 0; 1492b144498SSrikar Dronamraju } 150cbc91f71SSrikar Dronamraju static inline void 151cbc91f71SSrikar Dronamraju uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end) 152682968e0SSrikar Dronamraju { 153682968e0SSrikar Dronamraju } 15432cdba1eSOleg Nesterov static inline void uprobe_start_dup_mmap(void) 15532cdba1eSOleg Nesterov { 15632cdba1eSOleg Nesterov } 15732cdba1eSOleg Nesterov static inline void uprobe_end_dup_mmap(void) 15832cdba1eSOleg Nesterov { 15932cdba1eSOleg Nesterov } 160f8ac4ec9SOleg Nesterov static inline void 161f8ac4ec9SOleg Nesterov uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) 162f8ac4ec9SOleg Nesterov { 163f8ac4ec9SOleg Nesterov } 1640326f5a9SSrikar Dronamraju static inline void uprobe_notify_resume(struct pt_regs *regs) 1650326f5a9SSrikar Dronamraju { 1660326f5a9SSrikar Dronamraju } 1670326f5a9SSrikar Dronamraju static inline bool uprobe_deny_signal(void) 1680326f5a9SSrikar Dronamraju { 1690326f5a9SSrikar Dronamraju return false; 1700326f5a9SSrikar Dronamraju } 1710326f5a9SSrikar Dronamraju static inline void uprobe_free_utask(struct task_struct *t) 1720326f5a9SSrikar Dronamraju { 1730326f5a9SSrikar Dronamraju } 1743ab67966SOleg Nesterov static inline void uprobe_copy_process(struct task_struct *t, unsigned long flags) 1750326f5a9SSrikar Dronamraju { 1760326f5a9SSrikar Dronamraju } 177d4b3b638SSrikar Dronamraju static inline void uprobe_clear_state(struct mm_struct *mm) 178d4b3b638SSrikar Dronamraju { 179d4b3b638SSrikar Dronamraju } 1800326f5a9SSrikar Dronamraju #endif /* !CONFIG_UPROBES */ 1812b144498SSrikar Dronamraju #endif /* _LINUX_UPROBES_H */ 182