diff options
| -rw-r--r-- | kernel/kprobes.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index ba4d4c0740cf..134754d18bb4 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
| @@ -692,6 +692,27 @@ static __kprobes void unoptimize_kprobe(struct kprobe *p, bool force) | |||
| 692 | } | 692 | } |
| 693 | } | 693 | } |
| 694 | 694 | ||
| 695 | /* Cancel unoptimizing for reusing */ | ||
| 696 | static void reuse_unused_kprobe(struct kprobe *ap) | ||
| 697 | { | ||
| 698 | struct optimized_kprobe *op; | ||
| 699 | |||
| 700 | BUG_ON(!kprobe_unused(ap)); | ||
| 701 | /* | ||
| 702 | * Unused kprobe MUST be on the way of delayed unoptimizing (means | ||
| 703 | * there is still a relative jump) and disabled. | ||
| 704 | */ | ||
| 705 | op = container_of(ap, struct optimized_kprobe, kp); | ||
| 706 | if (unlikely(list_empty(&op->list))) | ||
| 707 | printk(KERN_WARNING "Warning: found a stray unused " | ||
| 708 | "aggrprobe@%p\n", ap->addr); | ||
| 709 | /* Enable the probe again */ | ||
| 710 | ap->flags &= ~KPROBE_FLAG_DISABLED; | ||
| 711 | /* Optimize it again (remove from op->list) */ | ||
| 712 | BUG_ON(!kprobe_optready(ap)); | ||
| 713 | optimize_kprobe(ap); | ||
| 714 | } | ||
| 715 | |||
| 695 | /* Remove optimized instructions */ | 716 | /* Remove optimized instructions */ |
| 696 | static void __kprobes kill_optimized_kprobe(struct kprobe *p) | 717 | static void __kprobes kill_optimized_kprobe(struct kprobe *p) |
| 697 | { | 718 | { |
| @@ -872,6 +893,13 @@ static void __kprobes __disarm_kprobe(struct kprobe *p, bool reopt) | |||
| 872 | #define kprobe_disarmed(p) kprobe_disabled(p) | 893 | #define kprobe_disarmed(p) kprobe_disabled(p) |
| 873 | #define wait_for_kprobe_optimizer() do {} while (0) | 894 | #define wait_for_kprobe_optimizer() do {} while (0) |
| 874 | 895 | ||
| 896 | /* There should be no unused kprobes can be reused without optimization */ | ||
| 897 | static void reuse_unused_kprobe(struct kprobe *ap) | ||
| 898 | { | ||
| 899 | printk(KERN_ERR "Error: There should be no unused kprobe here.\n"); | ||
| 900 | BUG_ON(kprobe_unused(ap)); | ||
| 901 | } | ||
| 902 | |||
| 875 | static __kprobes void free_aggr_kprobe(struct kprobe *p) | 903 | static __kprobes void free_aggr_kprobe(struct kprobe *p) |
| 876 | { | 904 | { |
| 877 | arch_remove_kprobe(p); | 905 | arch_remove_kprobe(p); |
| @@ -1173,8 +1201,8 @@ static int __kprobes register_aggr_kprobe(struct kprobe *orig_p, | |||
| 1173 | return -ENOMEM; | 1201 | return -ENOMEM; |
| 1174 | init_aggr_kprobe(ap, orig_p); | 1202 | init_aggr_kprobe(ap, orig_p); |
| 1175 | } else if (kprobe_unused(ap)) | 1203 | } else if (kprobe_unused(ap)) |
| 1176 | /* Busy to die */ | 1204 | /* This probe is going to die. Rescue it */ |
| 1177 | return -EBUSY; | 1205 | reuse_unused_kprobe(ap); |
| 1178 | 1206 | ||
| 1179 | if (kprobe_gone(ap)) { | 1207 | if (kprobe_gone(ap)) { |
| 1180 | /* | 1208 | /* |
