diff options
Diffstat (limited to 'kernel/kprobes.c')
| -rw-r--r-- | kernel/kprobes.c | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 3ea6325228da..fef1af8a73ce 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
| @@ -344,23 +344,6 @@ void __kprobes kprobe_flush_task(struct task_struct *tk) | |||
| 344 | spin_unlock_irqrestore(&kretprobe_lock, flags); | 344 | spin_unlock_irqrestore(&kretprobe_lock, flags); |
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | /* | ||
| 348 | * This kprobe pre_handler is registered with every kretprobe. When probe | ||
| 349 | * hits it will set up the return probe. | ||
| 350 | */ | ||
| 351 | static int __kprobes pre_handler_kretprobe(struct kprobe *p, | ||
| 352 | struct pt_regs *regs) | ||
| 353 | { | ||
| 354 | struct kretprobe *rp = container_of(p, struct kretprobe, kp); | ||
| 355 | unsigned long flags = 0; | ||
| 356 | |||
| 357 | /*TODO: consider to only swap the RA after the last pre_handler fired */ | ||
| 358 | spin_lock_irqsave(&kretprobe_lock, flags); | ||
| 359 | arch_prepare_kretprobe(rp, regs); | ||
| 360 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
| 361 | return 0; | ||
| 362 | } | ||
| 363 | |||
| 364 | static inline void free_rp_inst(struct kretprobe *rp) | 347 | static inline void free_rp_inst(struct kretprobe *rp) |
| 365 | { | 348 | { |
| 366 | struct kretprobe_instance *ri; | 349 | struct kretprobe_instance *ri; |
| @@ -578,6 +561,23 @@ void __kprobes unregister_jprobe(struct jprobe *jp) | |||
| 578 | 561 | ||
| 579 | #ifdef ARCH_SUPPORTS_KRETPROBES | 562 | #ifdef ARCH_SUPPORTS_KRETPROBES |
| 580 | 563 | ||
| 564 | /* | ||
| 565 | * This kprobe pre_handler is registered with every kretprobe. When probe | ||
| 566 | * hits it will set up the return probe. | ||
| 567 | */ | ||
| 568 | static int __kprobes pre_handler_kretprobe(struct kprobe *p, | ||
| 569 | struct pt_regs *regs) | ||
| 570 | { | ||
| 571 | struct kretprobe *rp = container_of(p, struct kretprobe, kp); | ||
| 572 | unsigned long flags = 0; | ||
| 573 | |||
| 574 | /*TODO: consider to only swap the RA after the last pre_handler fired */ | ||
| 575 | spin_lock_irqsave(&kretprobe_lock, flags); | ||
| 576 | arch_prepare_kretprobe(rp, regs); | ||
| 577 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
| 578 | return 0; | ||
| 579 | } | ||
| 580 | |||
| 581 | int __kprobes register_kretprobe(struct kretprobe *rp) | 581 | int __kprobes register_kretprobe(struct kretprobe *rp) |
| 582 | { | 582 | { |
| 583 | int ret = 0; | 583 | int ret = 0; |
| @@ -631,12 +631,12 @@ void __kprobes unregister_kretprobe(struct kretprobe *rp) | |||
| 631 | unregister_kprobe(&rp->kp); | 631 | unregister_kprobe(&rp->kp); |
| 632 | /* No race here */ | 632 | /* No race here */ |
| 633 | spin_lock_irqsave(&kretprobe_lock, flags); | 633 | spin_lock_irqsave(&kretprobe_lock, flags); |
| 634 | free_rp_inst(rp); | ||
| 635 | while ((ri = get_used_rp_inst(rp)) != NULL) { | 634 | while ((ri = get_used_rp_inst(rp)) != NULL) { |
| 636 | ri->rp = NULL; | 635 | ri->rp = NULL; |
| 637 | hlist_del(&ri->uflist); | 636 | hlist_del(&ri->uflist); |
| 638 | } | 637 | } |
| 639 | spin_unlock_irqrestore(&kretprobe_lock, flags); | 638 | spin_unlock_irqrestore(&kretprobe_lock, flags); |
| 639 | free_rp_inst(rp); | ||
| 640 | } | 640 | } |
| 641 | 641 | ||
| 642 | static int __init init_kprobes(void) | 642 | static int __init init_kprobes(void) |
