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; 3572e6ae28SVictor Kamensky struct page; 360326f5a9SSrikar Dronamraju 37da1816b1SOleg Nesterov #define UPROBE_HANDLER_REMOVE 1 38da1816b1SOleg Nesterov #define UPROBE_HANDLER_MASK 1 39da1816b1SOleg Nesterov 40ded49c55SAnton Arapov #define MAX_URETPROBE_DEPTH 64 41ded49c55SAnton Arapov 428a7f2fa0SOleg Nesterov enum uprobe_filter_ctx { 438a7f2fa0SOleg Nesterov UPROBE_FILTER_REGISTER, 448a7f2fa0SOleg Nesterov UPROBE_FILTER_UNREGISTER, 458a7f2fa0SOleg Nesterov UPROBE_FILTER_MMAP, 468a7f2fa0SOleg Nesterov }; 478a7f2fa0SOleg Nesterov 482b144498SSrikar Dronamraju struct uprobe_consumer { 492b144498SSrikar Dronamraju int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs); 50ea024870SAnton Arapov int (*ret_handler)(struct uprobe_consumer *self, 51ea024870SAnton Arapov unsigned long func, 52ea024870SAnton Arapov struct pt_regs *regs); 538a7f2fa0SOleg Nesterov bool (*filter)(struct uprobe_consumer *self, 548a7f2fa0SOleg Nesterov enum uprobe_filter_ctx ctx, 558a7f2fa0SOleg Nesterov struct mm_struct *mm); 562b144498SSrikar Dronamraju 572b144498SSrikar Dronamraju struct uprobe_consumer *next; 582b144498SSrikar Dronamraju }; 592b144498SSrikar Dronamraju 602b144498SSrikar Dronamraju #ifdef CONFIG_UPROBES 61c912dae6SOleg Nesterov #include <asm/uprobes.h> 62c912dae6SOleg Nesterov 630326f5a9SSrikar Dronamraju enum uprobe_task_state { 640326f5a9SSrikar Dronamraju UTASK_RUNNING, 650326f5a9SSrikar Dronamraju UTASK_SSTEP, 660326f5a9SSrikar Dronamraju UTASK_SSTEP_ACK, 670326f5a9SSrikar Dronamraju UTASK_SSTEP_TRAPPED, 680326f5a9SSrikar Dronamraju }; 690326f5a9SSrikar Dronamraju 700326f5a9SSrikar Dronamraju /* 710326f5a9SSrikar Dronamraju * uprobe_task: Metadata of a task while it singlesteps. 720326f5a9SSrikar Dronamraju */ 730326f5a9SSrikar Dronamraju struct uprobe_task { 740326f5a9SSrikar Dronamraju enum uprobe_task_state state; 7532473431SOleg Nesterov 7632473431SOleg Nesterov union { 7732473431SOleg Nesterov struct { 780326f5a9SSrikar Dronamraju struct arch_uprobe_task autask; 7932473431SOleg Nesterov unsigned long vaddr; 8032473431SOleg Nesterov }; 8132473431SOleg Nesterov 8232473431SOleg Nesterov struct { 8332473431SOleg Nesterov struct callback_head dup_xol_work; 8432473431SOleg Nesterov unsigned long dup_xol_addr; 8532473431SOleg Nesterov }; 8632473431SOleg Nesterov }; 8732473431SOleg Nesterov 8832473431SOleg Nesterov struct uprobe *active_uprobe; 8932473431SOleg Nesterov unsigned long xol_vaddr; 900326f5a9SSrikar Dronamraju 910dfd0eb8SAnton Arapov struct return_instance *return_instances; 92ded49c55SAnton Arapov unsigned int depth; 930326f5a9SSrikar Dronamraju }; 940326f5a9SSrikar Dronamraju 9597da8976SOleg Nesterov struct return_instance { 9697da8976SOleg Nesterov struct uprobe *uprobe; 9797da8976SOleg Nesterov unsigned long func; 987b868e48SOleg Nesterov unsigned long stack; /* stack pointer */ 9997da8976SOleg Nesterov unsigned long orig_ret_vaddr; /* original return address */ 10097da8976SOleg Nesterov bool chained; /* true, if instance is nested */ 10197da8976SOleg Nesterov 10297da8976SOleg Nesterov struct return_instance *next; /* keep as stack */ 10397da8976SOleg Nesterov }; 10497da8976SOleg Nesterov 10586dcb702SOleg Nesterov enum rp_check { 10686dcb702SOleg Nesterov RP_CHECK_CALL, 107*db087ef6SOleg Nesterov RP_CHECK_CHAIN_CALL, 10886dcb702SOleg Nesterov RP_CHECK_RET, 10986dcb702SOleg Nesterov }; 11086dcb702SOleg Nesterov 111c912dae6SOleg Nesterov struct xol_area; 112d4b3b638SSrikar Dronamraju 113d4b3b638SSrikar Dronamraju struct uprobes_state { 114d4b3b638SSrikar Dronamraju struct xol_area *xol_area; 115d4b3b638SSrikar Dronamraju }; 116647c42dfSOleg Nesterov 117271a9c35SBjorn Helgaas extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); 118271a9c35SBjorn Helgaas extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); 119271a9c35SBjorn Helgaas extern bool is_swbp_insn(uprobe_opcode_t *insn); 120271a9c35SBjorn Helgaas extern bool is_trap_insn(uprobe_opcode_t *insn); 121271a9c35SBjorn Helgaas extern unsigned long uprobe_get_swbp_addr(struct pt_regs *regs); 122b02ef20aSOleg Nesterov extern unsigned long uprobe_get_trap_addr(struct pt_regs *regs); 123f72d41faSOleg Nesterov extern int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t); 124e3343e6aSSrikar Dronamraju extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); 125bdf8647cSOleg Nesterov extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool); 126e3343e6aSSrikar Dronamraju extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); 1277b2d81d4SIngo Molnar extern int uprobe_mmap(struct vm_area_struct *vma); 128cbc91f71SSrikar Dronamraju extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); 12932cdba1eSOleg Nesterov extern void uprobe_start_dup_mmap(void); 13032cdba1eSOleg Nesterov extern void uprobe_end_dup_mmap(void); 131f8ac4ec9SOleg Nesterov extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm); 1320326f5a9SSrikar Dronamraju extern void uprobe_free_utask(struct task_struct *t); 1333ab67966SOleg Nesterov extern void uprobe_copy_process(struct task_struct *t, unsigned long flags); 1340326f5a9SSrikar Dronamraju extern int uprobe_post_sstep_notifier(struct pt_regs *regs); 1350326f5a9SSrikar Dronamraju extern int uprobe_pre_sstep_notifier(struct pt_regs *regs); 1360326f5a9SSrikar Dronamraju extern void uprobe_notify_resume(struct pt_regs *regs); 1370326f5a9SSrikar Dronamraju extern bool uprobe_deny_signal(void); 138c2d3f25dSRalf Baechle extern bool arch_uprobe_skip_sstep(struct arch_uprobe *aup, struct pt_regs *regs); 139d4b3b638SSrikar Dronamraju extern void uprobe_clear_state(struct mm_struct *mm); 1403820b4d2SDavid A. Long extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); 1413820b4d2SDavid A. Long extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); 1423820b4d2SDavid A. Long extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); 1433820b4d2SDavid A. Long extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); 1443820b4d2SDavid A. Long extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); 1453820b4d2SDavid A. Long extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); 1463820b4d2SDavid A. Long extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs); 14786dcb702SOleg Nesterov extern bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, struct pt_regs *regs); 148271a9c35SBjorn Helgaas extern bool arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs); 149271a9c35SBjorn Helgaas extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, 15072e6ae28SVictor Kamensky void *src, unsigned long len); 1510326f5a9SSrikar Dronamraju #else /* !CONFIG_UPROBES */ 152d4b3b638SSrikar Dronamraju struct uprobes_state { 153d4b3b638SSrikar Dronamraju }; 154b02ef20aSOleg Nesterov 155b02ef20aSOleg Nesterov #define uprobe_get_trap_addr(regs) instruction_pointer(regs) 156b02ef20aSOleg Nesterov 1577b2d81d4SIngo Molnar static inline int 158e3343e6aSSrikar Dronamraju uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) 1592b144498SSrikar Dronamraju { 1602b144498SSrikar Dronamraju return -ENOSYS; 1612b144498SSrikar Dronamraju } 162bdf8647cSOleg Nesterov static inline int 163bdf8647cSOleg Nesterov uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool add) 164bdf8647cSOleg Nesterov { 165bdf8647cSOleg Nesterov return -ENOSYS; 166bdf8647cSOleg Nesterov } 1677b2d81d4SIngo Molnar static inline void 168e3343e6aSSrikar Dronamraju uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) 1692b144498SSrikar Dronamraju { 1702b144498SSrikar Dronamraju } 1717b2d81d4SIngo Molnar static inline int uprobe_mmap(struct vm_area_struct *vma) 1722b144498SSrikar Dronamraju { 1732b144498SSrikar Dronamraju return 0; 1742b144498SSrikar Dronamraju } 175cbc91f71SSrikar Dronamraju static inline void 176cbc91f71SSrikar Dronamraju uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end) 177682968e0SSrikar Dronamraju { 178682968e0SSrikar Dronamraju } 17932cdba1eSOleg Nesterov static inline void uprobe_start_dup_mmap(void) 18032cdba1eSOleg Nesterov { 18132cdba1eSOleg Nesterov } 18232cdba1eSOleg Nesterov static inline void uprobe_end_dup_mmap(void) 18332cdba1eSOleg Nesterov { 18432cdba1eSOleg Nesterov } 185f8ac4ec9SOleg Nesterov static inline void 186f8ac4ec9SOleg Nesterov uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) 187f8ac4ec9SOleg Nesterov { 188f8ac4ec9SOleg Nesterov } 1890326f5a9SSrikar Dronamraju static inline void uprobe_notify_resume(struct pt_regs *regs) 1900326f5a9SSrikar Dronamraju { 1910326f5a9SSrikar Dronamraju } 1920326f5a9SSrikar Dronamraju static inline bool uprobe_deny_signal(void) 1930326f5a9SSrikar Dronamraju { 1940326f5a9SSrikar Dronamraju return false; 1950326f5a9SSrikar Dronamraju } 1960326f5a9SSrikar Dronamraju static inline void uprobe_free_utask(struct task_struct *t) 1970326f5a9SSrikar Dronamraju { 1980326f5a9SSrikar Dronamraju } 1993ab67966SOleg Nesterov static inline void uprobe_copy_process(struct task_struct *t, unsigned long flags) 2000326f5a9SSrikar Dronamraju { 2010326f5a9SSrikar Dronamraju } 202d4b3b638SSrikar Dronamraju static inline void uprobe_clear_state(struct mm_struct *mm) 203d4b3b638SSrikar Dronamraju { 204d4b3b638SSrikar Dronamraju } 2050326f5a9SSrikar Dronamraju #endif /* !CONFIG_UPROBES */ 2062b144498SSrikar Dronamraju #endif /* _LINUX_UPROBES_H */ 207