aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kprobes.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kprobes.c')
-rw-r--r--kernel/kprobes.c69
1 files changed, 19 insertions, 50 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 65242529a75f..90c0e82b650c 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -240,12 +240,6 @@ static int aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
240 return 0; 240 return 0;
241} 241}
242 242
243struct kprobe trampoline_p = {
244 .addr = (kprobe_opcode_t *) &kretprobe_trampoline,
245 .pre_handler = trampoline_probe_handler,
246 .post_handler = trampoline_post_handler
247};
248
249struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp) 243struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp)
250{ 244{
251 struct hlist_node *node; 245 struct hlist_node *node;
@@ -264,35 +258,18 @@ static struct kretprobe_instance *get_used_rp_inst(struct kretprobe *rp)
264 return NULL; 258 return NULL;
265} 259}
266 260
267struct kretprobe_instance *get_rp_inst(void *sara)
268{
269 struct hlist_head *head;
270 struct hlist_node *node;
271 struct task_struct *tsk;
272 struct kretprobe_instance *ri;
273
274 tsk = arch_get_kprobe_task(sara);
275 head = &kretprobe_inst_table[hash_ptr(tsk, KPROBE_HASH_BITS)];
276 hlist_for_each_entry(ri, node, head, hlist) {
277 if (ri->stack_addr == sara)
278 return ri;
279 }
280 return NULL;
281}
282
283void add_rp_inst(struct kretprobe_instance *ri) 261void add_rp_inst(struct kretprobe_instance *ri)
284{ 262{
285 struct task_struct *tsk;
286 /* 263 /*
287 * Remove rp inst off the free list - 264 * Remove rp inst off the free list -
288 * Add it back when probed function returns 265 * Add it back when probed function returns
289 */ 266 */
290 hlist_del(&ri->uflist); 267 hlist_del(&ri->uflist);
291 tsk = arch_get_kprobe_task(ri->stack_addr); 268
292 /* Add rp inst onto table */ 269 /* Add rp inst onto table */
293 INIT_HLIST_NODE(&ri->hlist); 270 INIT_HLIST_NODE(&ri->hlist);
294 hlist_add_head(&ri->hlist, 271 hlist_add_head(&ri->hlist,
295 &kretprobe_inst_table[hash_ptr(tsk, KPROBE_HASH_BITS)]); 272 &kretprobe_inst_table[hash_ptr(ri->task, KPROBE_HASH_BITS)]);
296 273
297 /* Also add this rp inst to the used list. */ 274 /* Also add this rp inst to the used list. */
298 INIT_HLIST_NODE(&ri->uflist); 275 INIT_HLIST_NODE(&ri->uflist);
@@ -319,34 +296,25 @@ struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk)
319 return &kretprobe_inst_table[hash_ptr(tsk, KPROBE_HASH_BITS)]; 296 return &kretprobe_inst_table[hash_ptr(tsk, KPROBE_HASH_BITS)];
320} 297}
321 298
322struct kretprobe_instance *get_rp_inst_tsk(struct task_struct *tk)
323{
324 struct task_struct *tsk;
325 struct hlist_head *head;
326 struct hlist_node *node;
327 struct kretprobe_instance *ri;
328
329 head = &kretprobe_inst_table[hash_ptr(tk, KPROBE_HASH_BITS)];
330
331 hlist_for_each_entry(ri, node, head, hlist) {
332 tsk = arch_get_kprobe_task(ri->stack_addr);
333 if (tsk == tk)
334 return ri;
335 }
336 return NULL;
337}
338
339/* 299/*
340 * This function is called from do_exit or do_execv when task tk's stack is 300 * This function is called from exit_thread or flush_thread when task tk's
341 * about to be recycled. Recycle any function-return probe instances 301 * stack is being recycled so that we can recycle any function-return probe
342 * associated with this task. These represent probed functions that have 302 * instances associated with this task. These left over instances represent
343 * been called but may never return. 303 * probed functions that have been called but will never return.
344 */ 304 */
345void kprobe_flush_task(struct task_struct *tk) 305void kprobe_flush_task(struct task_struct *tk)
346{ 306{
307 struct kretprobe_instance *ri;
308 struct hlist_head *head;
309 struct hlist_node *node, *tmp;
347 unsigned long flags = 0; 310 unsigned long flags = 0;
311
348 spin_lock_irqsave(&kprobe_lock, flags); 312 spin_lock_irqsave(&kprobe_lock, flags);
349 arch_kprobe_flush_task(tk); 313 head = kretprobe_inst_table_head(current);
314 hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
315 if (ri->task == tk)
316 recycle_rp_inst(ri);
317 }
350 spin_unlock_irqrestore(&kprobe_lock, flags); 318 spin_unlock_irqrestore(&kprobe_lock, flags);
351} 319}
352 320
@@ -606,9 +574,10 @@ static int __init init_kprobes(void)
606 INIT_HLIST_HEAD(&kretprobe_inst_table[i]); 574 INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
607 } 575 }
608 576
609 err = register_die_notifier(&kprobe_exceptions_nb); 577 err = arch_init();
610 /* Register the trampoline probe for return probe */ 578 if (!err)
611 register_kprobe(&trampoline_p); 579 err = register_die_notifier(&kprobe_exceptions_nb);
580
612 return err; 581 return err;
613} 582}
614 583