diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-i386/kprobes.h | 3 | ||||
-rw-r--r-- | include/linux/kprobes.h | 90 |
2 files changed, 91 insertions, 2 deletions
diff --git a/include/asm-i386/kprobes.h b/include/asm-i386/kprobes.h index 4092f68d123a..8b6d3a90cd78 100644 --- a/include/asm-i386/kprobes.h +++ b/include/asm-i386/kprobes.h | |||
@@ -39,6 +39,9 @@ typedef u8 kprobe_opcode_t; | |||
39 | : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) | 39 | : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) |
40 | 40 | ||
41 | #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry | 41 | #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry |
42 | #define ARCH_SUPPORTS_KRETPROBES | ||
43 | |||
44 | void kretprobe_trampoline(void); | ||
42 | 45 | ||
43 | /* Architecture specific copy of original instruction*/ | 46 | /* Architecture specific copy of original instruction*/ |
44 | struct arch_specific_insn { | 47 | struct arch_specific_insn { |
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 99ddba5a4e00..fba39f87efec 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h | |||
@@ -25,21 +25,31 @@ | |||
25 | * Rusty Russell). | 25 | * Rusty Russell). |
26 | * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes | 26 | * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes |
27 | * interface to access function arguments. | 27 | * interface to access function arguments. |
28 | * 2005-May Hien Nguyen <hien@us.ibm.com> and Jim Keniston | ||
29 | * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi | ||
30 | * <prasanna@in.ibm.com> added function-return probes. | ||
28 | */ | 31 | */ |
29 | #include <linux/config.h> | 32 | #include <linux/config.h> |
30 | #include <linux/list.h> | 33 | #include <linux/list.h> |
31 | #include <linux/notifier.h> | 34 | #include <linux/notifier.h> |
32 | #include <linux/smp.h> | 35 | #include <linux/smp.h> |
36 | #include <linux/spinlock.h> | ||
37 | |||
33 | #include <asm/kprobes.h> | 38 | #include <asm/kprobes.h> |
34 | 39 | ||
35 | struct kprobe; | 40 | struct kprobe; |
36 | struct pt_regs; | 41 | struct pt_regs; |
42 | struct kretprobe; | ||
43 | struct kretprobe_instance; | ||
37 | typedef int (*kprobe_pre_handler_t) (struct kprobe *, struct pt_regs *); | 44 | typedef int (*kprobe_pre_handler_t) (struct kprobe *, struct pt_regs *); |
38 | typedef int (*kprobe_break_handler_t) (struct kprobe *, struct pt_regs *); | 45 | typedef int (*kprobe_break_handler_t) (struct kprobe *, struct pt_regs *); |
39 | typedef void (*kprobe_post_handler_t) (struct kprobe *, struct pt_regs *, | 46 | typedef void (*kprobe_post_handler_t) (struct kprobe *, struct pt_regs *, |
40 | unsigned long flags); | 47 | unsigned long flags); |
41 | typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *, | 48 | typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *, |
42 | int trapnr); | 49 | int trapnr); |
50 | typedef int (*kretprobe_handler_t) (struct kretprobe_instance *, | ||
51 | struct pt_regs *); | ||
52 | |||
43 | struct kprobe { | 53 | struct kprobe { |
44 | struct hlist_node hlist; | 54 | struct hlist_node hlist; |
45 | 55 | ||
@@ -85,6 +95,62 @@ struct jprobe { | |||
85 | kprobe_opcode_t *entry; /* probe handling code to jump to */ | 95 | kprobe_opcode_t *entry; /* probe handling code to jump to */ |
86 | }; | 96 | }; |
87 | 97 | ||
98 | #ifdef ARCH_SUPPORTS_KRETPROBES | ||
99 | extern int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs); | ||
100 | extern void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs, | ||
101 | unsigned long flags); | ||
102 | extern struct task_struct *arch_get_kprobe_task(void *ptr); | ||
103 | extern void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs); | ||
104 | extern void arch_kprobe_flush_task(struct task_struct *tk, spinlock_t *kp_lock); | ||
105 | #else /* ARCH_SUPPORTS_KRETPROBES */ | ||
106 | static inline void kretprobe_trampoline(void) | ||
107 | { | ||
108 | } | ||
109 | static inline int trampoline_probe_handler(struct kprobe *p, | ||
110 | struct pt_regs *regs) | ||
111 | { | ||
112 | return 0; | ||
113 | } | ||
114 | static inline void trampoline_post_handler(struct kprobe *p, | ||
115 | struct pt_regs *regs, unsigned long flags) | ||
116 | { | ||
117 | } | ||
118 | static inline void arch_prepare_kretprobe(struct kretprobe *rp, | ||
119 | struct pt_regs *regs) | ||
120 | { | ||
121 | } | ||
122 | static inline void arch_kprobe_flush_task(struct task_struct *tk) | ||
123 | { | ||
124 | } | ||
125 | #define arch_get_kprobe_task(ptr) ((struct task_struct *)NULL) | ||
126 | #endif /* ARCH_SUPPORTS_KRETPROBES */ | ||
127 | /* | ||
128 | * Function-return probe - | ||
129 | * Note: | ||
130 | * User needs to provide a handler function, and initialize maxactive. | ||
131 | * maxactive - The maximum number of instances of the probed function that | ||
132 | * can be active concurrently. | ||
133 | * nmissed - tracks the number of times the probed function's return was | ||
134 | * ignored, due to maxactive being too low. | ||
135 | * | ||
136 | */ | ||
137 | struct kretprobe { | ||
138 | struct kprobe kp; | ||
139 | kretprobe_handler_t handler; | ||
140 | int maxactive; | ||
141 | int nmissed; | ||
142 | struct hlist_head free_instances; | ||
143 | struct hlist_head used_instances; | ||
144 | }; | ||
145 | |||
146 | struct kretprobe_instance { | ||
147 | struct hlist_node uflist; /* either on free list or used list */ | ||
148 | struct hlist_node hlist; | ||
149 | struct kretprobe *rp; | ||
150 | void *ret_addr; | ||
151 | void *stack_addr; | ||
152 | }; | ||
153 | |||
88 | #ifdef CONFIG_KPROBES | 154 | #ifdef CONFIG_KPROBES |
89 | /* Locks kprobe: irq must be disabled */ | 155 | /* Locks kprobe: irq must be disabled */ |
90 | void lock_kprobes(void); | 156 | void lock_kprobes(void); |
@@ -104,6 +170,7 @@ extern void show_registers(struct pt_regs *regs); | |||
104 | 170 | ||
105 | /* Get the kprobe at this addr (if any). Must have called lock_kprobes */ | 171 | /* Get the kprobe at this addr (if any). Must have called lock_kprobes */ |
106 | struct kprobe *get_kprobe(void *addr); | 172 | struct kprobe *get_kprobe(void *addr); |
173 | struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk); | ||
107 | 174 | ||
108 | int register_kprobe(struct kprobe *p); | 175 | int register_kprobe(struct kprobe *p); |
109 | void unregister_kprobe(struct kprobe *p); | 176 | void unregister_kprobe(struct kprobe *p); |
@@ -113,7 +180,16 @@ int register_jprobe(struct jprobe *p); | |||
113 | void unregister_jprobe(struct jprobe *p); | 180 | void unregister_jprobe(struct jprobe *p); |
114 | void jprobe_return(void); | 181 | void jprobe_return(void); |
115 | 182 | ||
116 | #else | 183 | int register_kretprobe(struct kretprobe *rp); |
184 | void unregister_kretprobe(struct kretprobe *rp); | ||
185 | |||
186 | struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp); | ||
187 | struct kretprobe_instance *get_rp_inst(void *sara); | ||
188 | struct kretprobe_instance *get_rp_inst_tsk(struct task_struct *tk); | ||
189 | void add_rp_inst(struct kretprobe_instance *ri); | ||
190 | void kprobe_flush_task(struct task_struct *tk); | ||
191 | void recycle_rp_inst(struct kretprobe_instance *ri); | ||
192 | #else /* CONFIG_KPROBES */ | ||
117 | static inline int kprobe_running(void) | 193 | static inline int kprobe_running(void) |
118 | { | 194 | { |
119 | return 0; | 195 | return 0; |
@@ -135,5 +211,15 @@ static inline void unregister_jprobe(struct jprobe *p) | |||
135 | static inline void jprobe_return(void) | 211 | static inline void jprobe_return(void) |
136 | { | 212 | { |
137 | } | 213 | } |
138 | #endif | 214 | static inline int register_kretprobe(struct kretprobe *rp) |
215 | { | ||
216 | return -ENOSYS; | ||
217 | } | ||
218 | static inline void unregister_kretprobe(struct kretprobe *rp) | ||
219 | { | ||
220 | } | ||
221 | static inline void kprobe_flush_task(struct task_struct *tk) | ||
222 | { | ||
223 | } | ||
224 | #endif /* CONFIG_KPROBES */ | ||
139 | #endif /* _LINUX_KPROBES_H */ | 225 | #endif /* _LINUX_KPROBES_H */ |