diff options
Diffstat (limited to 'kernel/events')
-rw-r--r-- | kernel/events/uprobes.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 5d38b40644b8..358baddc8ac2 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -669,6 +669,10 @@ remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vad | |||
669 | return set_orig_insn(&uprobe->arch, mm, vaddr); | 669 | return set_orig_insn(&uprobe->arch, mm, vaddr); |
670 | } | 670 | } |
671 | 671 | ||
672 | static inline bool uprobe_is_active(struct uprobe *uprobe) | ||
673 | { | ||
674 | return !RB_EMPTY_NODE(&uprobe->rb_node); | ||
675 | } | ||
672 | /* | 676 | /* |
673 | * There could be threads that have already hit the breakpoint. They | 677 | * There could be threads that have already hit the breakpoint. They |
674 | * will recheck the current insn and restart if find_uprobe() fails. | 678 | * will recheck the current insn and restart if find_uprobe() fails. |
@@ -676,9 +680,13 @@ remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vad | |||
676 | */ | 680 | */ |
677 | static void delete_uprobe(struct uprobe *uprobe) | 681 | static void delete_uprobe(struct uprobe *uprobe) |
678 | { | 682 | { |
683 | if (WARN_ON(!uprobe_is_active(uprobe))) | ||
684 | return; | ||
685 | |||
679 | spin_lock(&uprobes_treelock); | 686 | spin_lock(&uprobes_treelock); |
680 | rb_erase(&uprobe->rb_node, &uprobes_tree); | 687 | rb_erase(&uprobe->rb_node, &uprobes_tree); |
681 | spin_unlock(&uprobes_treelock); | 688 | spin_unlock(&uprobes_treelock); |
689 | RB_CLEAR_NODE(&uprobe->rb_node); /* for uprobe_is_active() */ | ||
682 | iput(uprobe->inode); | 690 | iput(uprobe->inode); |
683 | put_uprobe(uprobe); | 691 | put_uprobe(uprobe); |
684 | } | 692 | } |