linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
To: Peter Zijlstra <peterz@infradead.org>, Ingo Molnar <mingo@elte.hu>
Cc: Steven Rostedt <rostedt@goodmis.org>,
	Srikar Dronamraju <srikar@linux.vnet.ibm.com>,
	Linux-mm <linux-mm@kvack.org>,
	Arnaldo Carvalho de Melo <acme@infradead.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Jonathan Corbet <corbet@lwn.net>, Hugh Dickins <hughd@google.com>,
	Christoph Hellwig <hch@infradead.org>,
	Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ananth N Mavinakayanahalli <ananth@in.ibm.com>,
	Oleg Nesterov <oleg@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Jim Keniston <jkenisto@linux.vnet.ibm.com>,
	Roland McGrath <roland@hack.frob.com>,
	Andi Kleen <andi@firstfloor.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: [PATCH v4 3.0-rc2-tip 12/22] 12: x86: x86 specific probe handling
Date: Tue, 07 Jun 2011 18:30:41 +0530	[thread overview]
Message-ID: <20110607130041.28590.93677.sendpatchset@localhost6.localdomain6> (raw)
In-Reply-To: <20110607125804.28590.92092.sendpatchset@localhost6.localdomain6>


Provides x86 specific implementations for setting the current
instruction pointer, pre single-step and post-singlestep handling,
enabling and disabling singlestep.

This patch also introduces TIF_UPROBE which is set by uprobes notifier
code. TIF_UPROBE indicates that there is pending work that needs to be
done at do_notify_resume time.

Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
---
 arch/x86/include/asm/thread_info.h |    2 
 arch/x86/include/asm/uprobes.h     |    3 +
 arch/x86/kernel/uprobes.c          |  148 ++++++++++++++++++++++++++++++++++++
 3 files changed, 153 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 1f2e61e..2dc1921 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -84,6 +84,7 @@ struct thread_info {
 #define TIF_SECCOMP		8	/* secure computing */
 #define TIF_MCE_NOTIFY		10	/* notify userspace of an MCE */
 #define TIF_USER_RETURN_NOTIFY	11	/* notify kernel of userspace return */
+#define TIF_UPROBE		12	/* breakpointed or singlestepping */
 #define TIF_NOTSC		16	/* TSC is not accessible in userland */
 #define TIF_IA32		17	/* 32bit process */
 #define TIF_FORK		18	/* ret_from_fork */
@@ -107,6 +108,7 @@ struct thread_info {
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_MCE_NOTIFY		(1 << TIF_MCE_NOTIFY)
 #define _TIF_USER_RETURN_NOTIFY	(1 << TIF_USER_RETURN_NOTIFY)
+#define _TIF_UPROBE		(1 << TIF_UPROBE)
 #define _TIF_NOTSC		(1 << TIF_NOTSC)
 #define _TIF_IA32		(1 << TIF_IA32)
 #define _TIF_FORK		(1 << TIF_FORK)
diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
index 2f3c64d..3a7833c 100644
--- a/arch/x86/include/asm/uprobes.h
+++ b/arch/x86/include/asm/uprobes.h
@@ -44,4 +44,7 @@ struct uprobe_task_arch_info {};
 #endif
 struct uprobe;
 extern int analyze_insn(struct task_struct *tsk, struct uprobe *uprobe);
+extern void set_instruction_pointer(struct pt_regs *regs, unsigned long vaddr);
+extern int pre_xol(struct uprobe *uprobe, struct pt_regs *regs);
+extern int post_xol(struct uprobe *uprobe, struct pt_regs *regs);
 #endif	/* _ASM_UPROBES_H */
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 79f74c5..8d90ff3 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -25,6 +25,7 @@
 #include <linux/sched.h>
 #include <linux/ptrace.h>
 #include <linux/uprobes.h>
+#include <linux/uaccess.h>
 
 #include <linux/kdebug.h>
 #include <asm/insn.h>
@@ -412,3 +413,150 @@ int analyze_insn(struct task_struct *tsk, struct uprobe *uprobe)
 	prepare_fixups(uprobe, &insn);
 	return 0;
 }
+
+/*
+ * @reg: reflects the saved state of the task
+ * @vaddr: the virtual address to jump to.
+ * Return 0 on success or a -ve number on error.
+ */
+void set_instruction_pointer(struct pt_regs *regs, unsigned long vaddr)
+{
+	regs->ip = vaddr;
+}
+
+/*
+ * pre_xol - prepare to execute out of line.
+ * @uprobe: the probepoint information.
+ * @regs: reflects the saved user state of @tsk.
+ *
+ * If we're emulating a rip-relative instruction, save the contents
+ * of the scratch register and store the target address in that register.
+ *
+ * Returns true if @uprobe->opcode is @bkpt_insn.
+ */
+#ifdef CONFIG_X86_64
+int pre_xol(struct uprobe *uprobe, struct pt_regs *regs)
+{
+	struct uprobe_task_arch_info *tskinfo = &current->utask->tskinfo;
+
+	regs->ip = current->utask->xol_vaddr;
+	if (uprobe->fixups & UPROBES_FIX_RIP_AX) {
+		tskinfo->saved_scratch_register = regs->ax;
+		regs->ax = current->utask->vaddr;
+		regs->ax += uprobe->arch_info.rip_rela_target_address;
+	} else if (uprobe->fixups & UPROBES_FIX_RIP_CX) {
+		tskinfo->saved_scratch_register = regs->cx;
+		regs->cx = current->utask->vaddr;
+		regs->cx += uprobe->arch_info.rip_rela_target_address;
+	}
+	return 0;
+}
+#else
+int pre_xol(struct uprobe *uprobe, struct pt_regs *regs)
+{
+	regs->ip = current->utask->xol_vaddr;
+	return 0;
+}
+#endif
+
+/*
+ * Called by post_xol() to adjust the return address pushed by a call
+ * instruction executed out of line.
+ */
+static int adjust_ret_addr(unsigned long sp, long correction)
+{
+	int rasize, ncopied;
+	long ra = 0;
+
+	if (is_32bit_app(current))
+		rasize = 4;
+	else
+		rasize = 8;
+	ncopied = copy_from_user(&ra, (void __user *) sp, rasize);
+	if (unlikely(ncopied))
+		goto fail;
+	ra += correction;
+	ncopied = copy_to_user((void __user *) sp, &ra, rasize);
+	if (unlikely(ncopied))
+		goto fail;
+	return 0;
+
+fail:
+	pr_warn_once("uprobes: Failed to adjust return address after"
+		" single-stepping call instruction;"
+		" pid=%d, sp=%#lx\n", current->pid, sp);
+	return -EFAULT;
+}
+
+#ifdef CONFIG_X86_64
+static bool is_riprel_insn(struct uprobe *uprobe)
+{
+	return ((uprobe->fixups &
+			(UPROBES_FIX_RIP_AX | UPROBES_FIX_RIP_CX)) != 0);
+}
+
+static void handle_riprel_post_xol(struct uprobe *uprobe,
+			struct pt_regs *regs, long *correction)
+{
+	if (is_riprel_insn(uprobe)) {
+		struct uprobe_task_arch_info *tskinfo;
+		tskinfo = &current->utask->tskinfo;
+
+		if (uprobe->fixups & UPROBES_FIX_RIP_AX)
+			regs->ax = tskinfo->saved_scratch_register;
+		else
+			regs->cx = tskinfo->saved_scratch_register;
+		/*
+		 * The original instruction includes a displacement, and so
+		 * is 4 bytes longer than what we've just single-stepped.
+		 * Fall through to handle stuff like "jmpq *...(%rip)" and
+		 * "callq *...(%rip)".
+		 */
+		*correction += 4;
+	}
+}
+#else
+static void handle_riprel_post_xol(struct uprobe *uprobe,
+			struct pt_regs *regs, long *correction)
+{
+}
+#endif
+
+/*
+ * Called after single-stepping. To avoid the SMP problems that can
+ * occur when we temporarily put back the original opcode to
+ * single-step, we single-stepped a copy of the instruction.
+ *
+ * This function prepares to resume execution after the single-step.
+ * We have to fix things up as follows:
+ *
+ * Typically, the new ip is relative to the copied instruction.  We need
+ * to make it relative to the original instruction (FIX_IP).  Exceptions
+ * are return instructions and absolute or indirect jump or call instructions.
+ *
+ * If the single-stepped instruction was a call, the return address that
+ * is atop the stack is the address following the copied instruction.  We
+ * need to make it the address following the original instruction (FIX_CALL).
+ *
+ * If the original instruction was a rip-relative instruction such as
+ * "movl %edx,0xnnnn(%rip)", we have instead executed an equivalent
+ * instruction using a scratch register -- e.g., "movl %edx,(%rax)".
+ * We need to restore the contents of the scratch register and adjust
+ * the ip, keeping in mind that the instruction we executed is 4 bytes
+ * shorter than the original instruction (since we squeezed out the offset
+ * field).  (FIX_RIP_AX or FIX_RIP_CX)
+ */
+int post_xol(struct uprobe *uprobe, struct pt_regs *regs)
+{
+	struct uprobe_task *utask = current->utask;
+	int result = 0;
+	long correction;
+
+	correction = (long)(utask->vaddr - utask->xol_vaddr);
+	handle_riprel_post_xol(uprobe, regs, &correction);
+	if (uprobe->fixups & UPROBES_FIX_IP)
+		regs->ip += correction;
+	if (uprobe->fixups & UPROBES_FIX_CALL)
+		result = adjust_ret_addr(regs->sp, correction);
+	return result;
+}

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  parent reply	other threads:[~2011-06-07 13:07 UTC|newest]

Thread overview: 120+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-07 12:58 [PATCH v4 3.0-rc2-tip 0/22] 0: Uprobes patchset with perf probe support Srikar Dronamraju
2011-06-07 12:58 ` [PATCH v4 3.0-rc2-tip 1/22] 1: X86 specific breakpoint definitions Srikar Dronamraju
2011-06-07 12:58 ` [PATCH v4 3.0-rc2-tip 2/22] 2: uprobes: Breakground page replacement Srikar Dronamraju
2011-06-09 23:03   ` Peter Zijlstra
2011-06-13  8:48     ` Srikar Dronamraju
2011-06-09 23:03   ` Peter Zijlstra
2011-06-13  8:50     ` Srikar Dronamraju
2011-06-09 23:03   ` Peter Zijlstra
2011-06-09 23:03   ` Peter Zijlstra
2011-06-13  8:59     ` Srikar Dronamraju
2011-06-14 12:57       ` Peter Zijlstra
2011-06-14 14:57         ` Srikar Dronamraju
2011-06-09 23:03   ` Peter Zijlstra
2011-06-13  9:14     ` Srikar Dronamraju
2011-06-13 13:46   ` Oleg Nesterov
2011-06-13 17:00   ` Oleg Nesterov
2011-06-14 12:35     ` Srikar Dronamraju
2011-06-14 14:20       ` Oleg Nesterov
2011-06-15  8:55         ` Srikar Dronamraju
2011-06-15 17:54           ` Oleg Nesterov
2011-06-14 13:01     ` Peter Zijlstra
2011-06-14 14:27       ` Oleg Nesterov
2011-06-14 15:07         ` Peter Zijlstra
2011-06-14 15:40           ` Oleg Nesterov
2011-06-14 18:22             ` Peter Zijlstra
2011-06-16 12:48   ` Peter Zijlstra
2011-06-07 12:58 ` [PATCH v4 3.0-rc2-tip 3/22] 3: uprobes: Adding and remove a uprobe in a rb tree Srikar Dronamraju
2011-06-08  4:12   ` Stephen Wilson
2011-06-08  7:04     ` Josh Stone
2011-06-08 10:29       ` Srikar Dronamraju
2011-06-08 10:30   ` Srikar Dronamraju
2011-06-07 12:59 ` [PATCH v4 3.0-rc2-tip 4/22] 4: Uprobes: register/unregister probes Srikar Dronamraju
2011-06-08 22:10   ` Stephen Wilson
2011-06-09  5:43     ` Srikar Dronamraju
2011-06-09 23:03   ` Peter Zijlstra
2011-06-16  5:40     ` Srikar Dronamraju
2011-06-09 23:03   ` Peter Zijlstra
2011-06-13 16:50     ` Steven Rostedt
2011-06-16  5:26     ` Srikar Dronamraju
2011-06-16  9:42       ` Peter Zijlstra
2011-06-13 19:57   ` Oleg Nesterov
2011-06-14 12:00     ` Srikar Dronamraju
2011-06-14 14:29       ` Oleg Nesterov
2011-06-15 17:30   ` Oleg Nesterov
2011-06-16  5:09     ` Srikar Dronamraju
2011-06-15 17:41   ` Peter Zijlstra
2011-06-16  4:11     ` Srikar Dronamraju
2011-06-16  9:46       ` Peter Zijlstra
2011-06-16  9:54         ` Srikar Dronamraju
2011-06-16 10:09           ` Peter Zijlstra
2011-06-16 13:51           ` Oleg Nesterov
2011-06-17  9:29             ` Srikar Dronamraju
2011-06-15 18:01   ` Peter Zijlstra
2011-07-24 18:07   ` Oleg Nesterov
2011-07-25 12:17     ` Srikar Dronamraju
2011-06-07 12:59 ` [PATCH v4 3.0-rc2-tip 5/22] 5: x86: analyze instruction and determine fixups Srikar Dronamraju
2011-06-09 23:03   ` Peter Zijlstra
2011-06-07 12:59 ` [PATCH v4 3.0-rc2-tip 6/22] 6: uprobes: store/restore original instruction Srikar Dronamraju
2011-06-07 12:59 ` [PATCH v4 3.0-rc2-tip 7/22] 7: uprobes: mmap and fork hooks Srikar Dronamraju
2011-06-08 22:12   ` Stephen Wilson
2011-06-09  5:50     ` Srikar Dronamraju
2011-06-15 18:11   ` Peter Zijlstra
2011-06-16  3:26     ` Srikar Dronamraju
2011-06-16 12:00       ` Peter Zijlstra
2011-06-16 13:00         ` Srikar Dronamraju
2011-06-16 18:23           ` Peter Zijlstra
2011-06-16 18:25             ` Peter Zijlstra
2011-06-17  4:50             ` Srikar Dronamraju
2011-06-17  8:03               ` Peter Zijlstra
2011-06-17  9:05                 ` Srikar Dronamraju
2011-06-17  9:41                   ` Peter Zijlstra
2011-06-21 13:17                     ` Peter Zijlstra
2011-06-22 14:39                       ` Srikar Dronamraju
2011-06-24  2:06                         ` Srikar Dronamraju
2011-06-24  7:42                           ` Peter Zijlstra
2011-06-27  6:45                             ` Srikar Dronamraju
2011-06-27  8:57                               ` Peter Zijlstra
2011-07-18  9:20                                 ` Srikar Dronamraju
2011-07-18 14:31                                   ` Peter Zijlstra
2011-07-19  6:53                                     ` Srikar Dronamraju
2011-07-20 11:56                                       ` Peter Zijlstra
2011-06-07 12:59 ` [PATCH v4 3.0-rc2-tip 8/22] 8: x86: architecture specific task information Srikar Dronamraju
2011-06-07 12:59 ` [PATCH v4 3.0-rc2-tip 9/22] 9: uprobes: task specific information Srikar Dronamraju
2011-06-07 13:00 ` [PATCH v4 3.0-rc2-tip 10/22] 10: uprobes: slot allocation for uprobes Srikar Dronamraju
2011-06-07 13:00 ` [PATCH v4 3.0-rc2-tip 11/22] 11: uprobes: get the breakpoint address Srikar Dronamraju
2011-06-07 13:00 ` Srikar Dronamraju [this message]
2011-06-07 13:00 ` [PATCH v4 3.0-rc2-tip 13/22] 13: uprobes: Handing int3 and singlestep exception Srikar Dronamraju
2011-06-08 22:11   ` Stephen Wilson
2011-06-09  5:47     ` Srikar Dronamraju
2011-06-16 11:52   ` Peter Zijlstra
2011-06-16 12:04     ` Srikar Dronamraju
2011-06-16 12:35       ` Peter Zijlstra
2011-06-07 13:01 ` [PATCH v4 3.0-rc2-tip 14/22] 14: x86: uprobes exception notifier for x86 Srikar Dronamraju
2011-06-21 13:31   ` Peter Zijlstra
2011-06-21 13:32     ` Peter Zijlstra
2011-06-22 14:54       ` Srikar Dronamraju
2011-06-22 16:40         ` Roland McGrath
2011-06-07 13:01 ` [PATCH v4 3.0-rc2-tip 15/22] 15: uprobes: register a notifier for uprobes Srikar Dronamraju
2011-06-07 13:01 ` [PATCH v4 3.0-rc2-tip 16/22] 16: tracing: Extract out common code for kprobes/uprobes traceevents Srikar Dronamraju
2011-06-07 13:01 ` [PATCH v4 3.0-rc2-tip 17/22] 17: tracing: uprobes trace_event interface Srikar Dronamraju
2011-06-07 13:01 ` [PATCH v4 3.0-rc2-tip 18/22] 18: tracing: Uprobe tracer documentation Srikar Dronamraju
2011-06-07 13:02 ` [PATCH v4 3.0-rc2-tip 19/22] 19: perf: rename target_module to target Srikar Dronamraju
2011-06-07 13:02 ` [PATCH v4 3.0-rc2-tip 20/22] 20: perf: perf interface for uprobes Srikar Dronamraju
2011-06-07 13:30   ` Christoph Hellwig
2011-06-07 13:38     ` Ananth N Mavinakayanahalli
2011-06-07 14:21       ` Arnaldo Carvalho de Melo
2011-06-07 16:06         ` Srikar Dronamraju
2011-06-08  3:41       ` Masami Hiramatsu
2011-06-07 19:59   ` Josh Stone
2011-06-08  3:44     ` Srikar Dronamraju
2011-06-10 11:50   ` Masami Hiramatsu
2011-06-07 13:02 ` [PATCH v4 3.0-rc2-tip 21/22] 21: perf: show possible probes in a given executable file or library Srikar Dronamraju
2011-06-07 13:02 ` [PATCH v4 3.0-rc2-tip 22/22] 22: perf: Documentation for perf uprobes Srikar Dronamraju
2011-06-10 12:03   ` Masami Hiramatsu
2011-06-09 18:42 ` [PATCH v4 3.0-rc2-tip 0/22] 0: Uprobes patchset with perf probe support Peter Zijlstra
2011-06-10  5:56   ` Ananth N Mavinakayanahalli
2011-06-13  9:23   ` Srikar Dronamraju
2011-06-09 23:03 ` Peter Zijlstra
2011-06-10  6:15   ` Masami Hiramatsu
2011-06-13 10:08   ` Srikar Dronamraju

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110607130041.28590.93677.sendpatchset@localhost6.localdomain6 \
    --to=srikar@linux.vnet.ibm.com \
    --cc=acme@infradead.org \
    --cc=akpm@linux-foundation.org \
    --cc=ananth@in.ibm.com \
    --cc=andi@firstfloor.org \
    --cc=corbet@lwn.net \
    --cc=hch@infradead.org \
    --cc=hughd@google.com \
    --cc=jkenisto@linux.vnet.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=mingo@elte.hu \
    --cc=oleg@redhat.com \
    --cc=peterz@infradead.org \
    --cc=roland@hack.frob.com \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).