diff options
Diffstat (limited to 'arch/s390/kernel/kprobes.c')
-rw-r--r-- | arch/s390/kernel/kprobes.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index ca28fb0b3790..4d9ff5ce4cbd 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c | |||
@@ -369,11 +369,12 @@ void __kprobes kretprobe_trampoline_holder(void) | |||
369 | int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | 369 | int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) |
370 | { | 370 | { |
371 | struct kretprobe_instance *ri = NULL; | 371 | struct kretprobe_instance *ri = NULL; |
372 | struct hlist_head *head; | 372 | struct hlist_head *head, empty_rp; |
373 | struct hlist_node *node, *tmp; | 373 | struct hlist_node *node, *tmp; |
374 | unsigned long flags, orig_ret_address = 0; | 374 | unsigned long flags, orig_ret_address = 0; |
375 | unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; | 375 | unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; |
376 | 376 | ||
377 | INIT_HLIST_HEAD(&empty_rp); | ||
377 | spin_lock_irqsave(&kretprobe_lock, flags); | 378 | spin_lock_irqsave(&kretprobe_lock, flags); |
378 | head = kretprobe_inst_table_head(current); | 379 | head = kretprobe_inst_table_head(current); |
379 | 380 | ||
@@ -399,7 +400,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
399 | ri->rp->handler(ri, regs); | 400 | ri->rp->handler(ri, regs); |
400 | 401 | ||
401 | orig_ret_address = (unsigned long)ri->ret_addr; | 402 | orig_ret_address = (unsigned long)ri->ret_addr; |
402 | recycle_rp_inst(ri); | 403 | recycle_rp_inst(ri, &empty_rp); |
403 | 404 | ||
404 | if (orig_ret_address != trampoline_address) { | 405 | if (orig_ret_address != trampoline_address) { |
405 | /* | 406 | /* |
@@ -417,6 +418,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
417 | spin_unlock_irqrestore(&kretprobe_lock, flags); | 418 | spin_unlock_irqrestore(&kretprobe_lock, flags); |
418 | preempt_enable_no_resched(); | 419 | preempt_enable_no_resched(); |
419 | 420 | ||
421 | hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { | ||
422 | hlist_del(&ri->hlist); | ||
423 | kfree(ri); | ||
424 | } | ||
420 | /* | 425 | /* |
421 | * By returning a non-zero value, we are telling | 426 | * By returning a non-zero value, we are telling |
422 | * kprobe_handler() that we don't want the post_handler | 427 | * kprobe_handler() that we don't want the post_handler |