diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2014-08-03 23:10:16 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-08-08 04:38:04 -0400 |
commit | f96f56780ca584930bb3a2769d73fd9a101bcbbe (patch) | |
tree | c3974ec34ef0e249e25819248d84b8ec2c80325c /kernel/kprobes.c | |
parent | 98a96f202203fecad65b44449077c695686ad4db (diff) |
kprobes: Skip kretprobe hit in NMI context to avoid deadlock
Skip kretprobe hit in NMI context, because if an NMI happens
inside the critical section protected by kretprobe_table.lock
and another(or same) kretprobe hit, pre_kretprobe_handler
tries to lock kretprobe_table.lock again.
Normal interrupts have no problem because they are disabled
with the lock.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Acked-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: David S. Miller <davem@davemloft.net>
Link: http://lkml.kernel.org/r/20140804031016.11433.65539.stgit@kbuild-fedora.novalocal
[ Minor edits for clarity. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/kprobes.c')
-rw-r--r-- | kernel/kprobes.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 734e9a7d280b..3995f546d0f3 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -1778,7 +1778,18 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) | |||
1778 | unsigned long hash, flags = 0; | 1778 | unsigned long hash, flags = 0; |
1779 | struct kretprobe_instance *ri; | 1779 | struct kretprobe_instance *ri; |
1780 | 1780 | ||
1781 | /*TODO: consider to only swap the RA after the last pre_handler fired */ | 1781 | /* |
1782 | * To avoid deadlocks, prohibit return probing in NMI contexts, | ||
1783 | * just skip the probe and increase the (inexact) 'nmissed' | ||
1784 | * statistical counter, so that the user is informed that | ||
1785 | * something happened: | ||
1786 | */ | ||
1787 | if (unlikely(in_nmi())) { | ||
1788 | rp->nmissed++; | ||
1789 | return 0; | ||
1790 | } | ||
1791 | |||
1792 | /* TODO: consider to only swap the RA after the last pre_handler fired */ | ||
1782 | hash = hash_ptr(current, KPROBE_HASH_BITS); | 1793 | hash = hash_ptr(current, KPROBE_HASH_BITS); |
1783 | raw_spin_lock_irqsave(&rp->lock, flags); | 1794 | raw_spin_lock_irqsave(&rp->lock, flags); |
1784 | if (!hlist_empty(&rp->free_instances)) { | 1795 | if (!hlist_empty(&rp->free_instances)) { |