[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20120405222046.GA19166@redhat.com>
Date: Fri, 6 Apr 2012 00:20:46 +0200
From: Oleg Nesterov <oleg@...hat.com>
To: Ingo Molnar <mingo@...e.hu>, Peter Zijlstra <peterz@...radead.org>,
Srikar Dronamraju <srikar@...ux.vnet.ibm.com>
Cc: Andrew Morton <akpm@...ux-foundation.org>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Ananth N Mavinakayanahalli <ananth@...ibm.com>,
Jim Keniston <jkenisto@...ux.vnet.ibm.com>,
LKML <linux-kernel@...r.kernel.org>,
Linux-mm <linux-mm@...ck.org>, Andi Kleen <andi@...stfloor.org>,
Christoph Hellwig <hch@...radead.org>,
Steven Rostedt <rostedt@...dmis.org>,
Arnaldo Carvalho de Melo <acme@...radead.org>,
Masami Hiramatsu <masami.hiramatsu.pt@...achi.com>,
Thomas Gleixner <tglx@...utronix.de>,
Anton Arapov <anton@...hat.com>
Subject: [PATCH 1/6] uprobes: introduce find_active_uprobe()
No functional changes. Move the "find uprobe" code from
handle_swbp() to the new helper, find_active_uprobe().
Note: with or without this change, the find-active-uprobe logic
is not exactly right. We can race with another thread which unmaps
the memory with the valid uprobe before we take mm->mmap_sem. We
can't find this uprobe simply because find_vma() fails. In this
case we wrongly assume that this trap was not caused by uprobe
and send the erroneous SIGTRAP.
---
kernel/events/uprobes.c | 31 +++++++++++++++++++------------
1 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 29e881b..3d0a4d6 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1474,21 +1474,12 @@ static bool can_skip_sstep(struct uprobe *uprobe, struct pt_regs *regs)
return false;
}
-/*
- * Run handler and ask thread to singlestep.
- * Ensure all non-fatal signals cannot interrupt thread while it singlesteps.
- */
-static void handle_swbp(struct pt_regs *regs)
+static struct uprobe *find_active_uprobe(unsigned long bp_vaddr)
{
+ struct mm_struct *mm = current->mm;
+ struct uprobe *uprobe = NULL;
struct vm_area_struct *vma;
- struct uprobe_task *utask;
- struct uprobe *uprobe;
- struct mm_struct *mm;
- unsigned long bp_vaddr;
- uprobe = NULL;
- bp_vaddr = uprobe_get_swbp_addr(regs);
- mm = current->mm;
down_read(&mm->mmap_sem);
vma = find_vma(mm, bp_vaddr);
@@ -1506,6 +1497,22 @@ static void handle_swbp(struct pt_regs *regs)
current->uprobe_srcu_id = -1;
up_read(&mm->mmap_sem);
+ return uprobe;
+}
+
+/*
+ * Run handler and ask thread to singlestep.
+ * Ensure all non-fatal signals cannot interrupt thread while it singlesteps.
+ */
+static void handle_swbp(struct pt_regs *regs)
+{
+ struct uprobe_task *utask;
+ struct uprobe *uprobe;
+ unsigned long bp_vaddr;
+
+ bp_vaddr = uprobe_get_swbp_addr(regs);
+ uprobe = find_active_uprobe(bp_vaddr);
+
if (!uprobe) {
/* No matching uprobe; signal SIGTRAP. */
send_sig(SIGTRAP, current, 0);
--
1.5.5.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists