aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kprobes.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2014-08-03 23:10:16 -0400
committerIngo Molnar <mingo@kernel.org>2014-08-08 04:38:04 -0400
commitf96f56780ca584930bb3a2769d73fd9a101bcbbe (patch)
treec3974ec34ef0e249e25819248d84b8ec2c80325c /kernel/kprobes.c
parent98a96f202203fecad65b44449077c695686ad4db (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.c13
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)) {