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>,
	Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Linux-mm <linux-mm@kvack.org>, Ingo Molnar <mingo@elte.hu>,
	Andi Kleen <andi@firstfloor.org>,
	Christoph Hellwig <hch@infradead.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Roland McGrath <roland@hack.frob.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
	Arnaldo Carvalho de Melo <acme@infradead.org>,
	Anton Arapov <anton@redhat.com>,
	Ananth N Mavinakayanahalli <ananth@in.ibm.com>,
	Jim Keniston <jkenisto@linux.vnet.ibm.com>,
	Stephen Wilson <wilsons@start.ca>
Subject: [PATCH v6 3.2-rc1 17/28]   x86: arch specific hooks for pre/post singlestep handling.
Date: Fri, 11 Nov 2011 00:10:55 +0530	[thread overview]
Message-ID: <20111110184055.11361.73915.sendpatchset@srdronam.in.ibm.com> (raw)
In-Reply-To: <20111110183725.11361.57827.sendpatchset@srdronam.in.ibm.com>


Hooks for handling pre singlestepping and post singlestepping.

Signed-off-by: Jim Keniston <jkenisto@us.ibm.com>
Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
---
 arch/x86/include/asm/uprobes.h |    2 +
 arch/x86/kernel/uprobes.c      |  135 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
index cf794bf..99d7d4b 100644
--- a/arch/x86/include/asm/uprobes.h
+++ b/arch/x86/include/asm/uprobes.h
@@ -47,6 +47,8 @@ struct uprobe_task_arch_info {};
 struct uprobe;
 extern int analyze_insn(struct mm_struct *mm, 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);
 extern int uprobe_exception_notify(struct notifier_block *self,
 				       unsigned long val, void *data);
 #endif	/* _ASM_UPROBES_H */
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 2ee5ddc..0792fc8 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>
@@ -409,6 +410,140 @@ void set_instruction_pointer(struct pt_regs *regs, unsigned long 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))
+		return -EFAULT;
+
+	ra += correction;
+	ncopied = copy_to_user((void __user *)sp, &ra, rasize);
+	if (unlikely(ncopied))
+		return -EFAULT;
+
+	return 0;
+}
+
+#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;
+}
+
+/*
  * Wrapper routine for handling exceptions.
  */
 int uprobe_exception_notify(struct notifier_block *self,

--
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-11-10 19:05 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-10 18:37 [PATCH v6 3.2-rc1 0/28] Uprobes patchset with perf probe support Srikar Dronamraju
2011-11-10 18:37 ` [PATCH v6 3.2-rc1 1/28] uprobes: Auxillary routines to insert, find, delete uprobes Srikar Dronamraju
2011-11-10 18:37 ` [PATCH v6 3.2-rc1 2/28] Uprobes: Allow multiple consumers for an uprobe Srikar Dronamraju
2011-11-10 18:37 ` [PATCH v6 3.2-rc1 3/28] Uprobes: register/unregister probes Srikar Dronamraju
2011-11-10 18:38 ` [PATCH v6 3.2-rc1 4/28] uprobes: Define hooks for mmap/munmap Srikar Dronamraju
2011-11-10 18:38 ` [PATCH v6 3.2-rc1 5/28] Uprobes: copy of the original instruction Srikar Dronamraju
2011-11-10 18:38 ` [PATCH v6 3.2-rc1 6/28] Uprobes: define fixups Srikar Dronamraju
2011-11-10 18:38 ` [PATCH v6 3.2-rc1 7/28] Uprobes: uprobes arch info Srikar Dronamraju
2011-11-10 18:39 ` [PATCH v6 3.2-rc1 8/28] x86: analyze instruction and determine fixups Srikar Dronamraju
2011-11-10 18:39 ` [PATCH v6 3.2-rc1 9/28] Uprobes: Background page replacement Srikar Dronamraju
2011-11-10 18:39 ` [PATCH v6 3.2-rc1 10/28] x86: Set instruction pointer Srikar Dronamraju
2011-11-10 18:39 ` [PATCH v6 3.2-rc1 11/28] x86: Introduce TIF_UPROBE FLAG Srikar Dronamraju
2011-11-10 18:39 ` [PATCH v6 3.2-rc1 12/28] Uprobes: Handle breakpoint and Singlestep Srikar Dronamraju
2011-11-10 18:40 ` [PATCH v6 3.2-rc1 13/28] x86: define a x86 specific exception notifier Srikar Dronamraju
2011-11-10 18:40 ` [PATCH v6 3.2-rc1 14/28] uprobe: register " Srikar Dronamraju
2011-11-10 18:40 ` [PATCH v6 3.2-rc1 15/28] x86: Define x86_64 specific uprobe_task_arch_info structure Srikar Dronamraju
2011-11-10 18:40 ` [PATCH v6 3.2-rc1 16/28] uprobes: Introduce " Srikar Dronamraju
2011-11-10 18:40 ` Srikar Dronamraju [this message]
2011-11-10 18:41 ` [PATCH v6 3.2-rc1 18/28] uprobes: slot allocation Srikar Dronamraju
2011-11-10 18:41 ` [PATCH v6 3.2-rc1 19/28] tracing: modify is_delete, is_return from ints to bool Srikar Dronamraju
2011-11-10 18:41 ` [PATCH v6 3.2-rc1 20/28] tracing: Extract out common code for kprobes/uprobes traceevents Srikar Dronamraju
2011-11-10 18:41 ` [PATCH v6 3.2-rc1 21/28] tracing: uprobes trace_event interface Srikar Dronamraju
2011-11-10 18:41 ` [PATCH v6 3.2-rc1 22/28] perf: rename target_module to target Srikar Dronamraju
2011-11-10 18:42 ` [PATCH v6 3.2-rc1 23/28] perf: perf interface for uprobes Srikar Dronamraju
2011-11-10 18:42 ` [PATCH v6 3.2-rc1 24/28] perf: show possible probes in a given executable file or library Srikar Dronamraju
2011-11-10 18:42 ` [PATCH v6 3.2-rc1 25/28] uprobes: call post_xol() unconditionally Srikar Dronamraju
2011-11-10 18:42 ` [PATCH v6 3.2-rc1 26/28] uprobes: introduce uprobe_deny_signal() Srikar Dronamraju
2011-11-10 18:42 ` [PATCH v6 3.2-rc1 27/28] uprobes: x86: introduce xol_was_trapped() Srikar Dronamraju
2011-11-10 18:43 ` [PATCH v6 3.2-rc1 28/28] uprobes: introduce UTASK_SSTEP_TRAPPED logic Srikar Dronamraju
2011-11-14 16:39   ` Oleg Nesterov
2011-11-15  7:44     ` 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=20111110184055.11361.73915.sendpatchset@srdronam.in.ibm.com \
    --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=anton@redhat.com \
    --cc=hch@infradead.org \
    --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 \
    --cc=wilsons@start.ca \
    /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).