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>,
Arnaldo Carvalho de Melo <acme@infradead.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
Christoph Hellwig <hch@infradead.org>,
Andi Kleen <andi@firstfloor.org>, Oleg Nesterov <oleg@redhat.com>,
Andrew Morton <akpm@linux-foundation.org>,
SystemTap <systemtap@sources.redhat.com>,
Linux-mm <linux-mm@vger.kernel.org>,
Jim Keniston <jkenisto@linux.vnet.ibm.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Ananth N Mavinakayanahalli <ananth@in.ibm.com>,
LKML <linux-kernel@vger.kernel.org>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Subject: [RFC] [PATCH 2.6.37-rc5-tip 13/20] 13: x86: x86 specific probe handling
Date: Thu, 16 Dec 2010 15:29:47 +0530 [thread overview]
Message-ID: <20101216095947.23751.75003.sendpatchset@localhost6.localdomain6> (raw)
In-Reply-To: <20101216095714.23751.52601.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 | 5 +
arch/x86/kernel/uprobes.c | 155 ++++++++++++++++++++++++++++++++++++
3 files changed, 162 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index f0b6e5d..5b9c9f0 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 e38950f..0c9c8b6 100644
--- a/arch/x86/include/asm/uprobes.h
+++ b/arch/x86/include/asm/uprobes.h
@@ -44,4 +44,9 @@ struct uprobe_task_arch_info {};
#endif
struct uprobe;
extern int analyze_insn(struct task_struct *tsk, struct uprobe *uprobe);
+extern void set_ip(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 void arch_uprobe_enable_sstep(struct pt_regs *regs);
+extern void arch_uprobe_disable_sstep(struct pt_regs *regs);
#endif /* _ASM_UPROBES_H */
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 352c71f..9a0b8a9 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -413,3 +413,158 @@ int analyze_insn(struct task_struct *tsk, struct uprobe *uprobe)
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_ip(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.
+ */
+int pre_xol(struct uprobe *uprobe, struct pt_regs *regs)
+{
+ struct uprobe_task_arch_info *tskinfo = ¤t->utask->tskinfo;
+
+ regs->ip = current->utask->xol_vaddr;
+#ifdef CONFIG_X86_64
+ 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;
+ }
+#endif
+ return 0;
+}
+
+/*
+ * 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 = uprobes_read_vm(current, (void __user *) sp, &ra, rasize);
+ if (unlikely(ncopied != rasize))
+ goto fail;
+ ra += correction;
+ ncopied = uprobes_write_vm(current, (void __user *) sp, &ra, rasize);
+ if (unlikely(ncopied != rasize))
+ goto fail;
+ return 0;
+
+fail:
+ printk(KERN_ERR
+ "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);
+}
+
+#endif /* CONFIG_X86_64 */
+
+/*
+ * 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);
+#ifdef CONFIG_X86_64
+ if (is_riprel_insn(uprobe)) {
+ struct uprobe_task_arch_info *tskinfo;
+ tskinfo = ¤t->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;
+ }
+#endif
+ if (uprobe->fixups & UPROBES_FIX_IP)
+ regs->ip += correction;
+ if (uprobe->fixups & UPROBES_FIX_CALL)
+ result = adjust_ret_addr(regs->sp, correction);
+ return result;
+}
+
+void arch_uprobe_enable_sstep(struct pt_regs *regs)
+{
+ /*
+ * Enable single-stepping by
+ * - Set TF on stack
+ * - Set TIF_SINGLESTEP: Guarantees that TF is set when
+ * returning to user mode.
+ * - Indicate that TF is set by us.
+ */
+ regs->flags |= X86_EFLAGS_TF;
+ set_thread_flag(TIF_SINGLESTEP);
+ set_thread_flag(TIF_FORCED_TF);
+}
+
+void arch_uprobe_disable_sstep(struct pt_regs *regs)
+{
+ /* Disable single-stepping by clearing what we set */
+ clear_thread_flag(TIF_SINGLESTEP);
+ clear_thread_flag(TIF_FORCED_TF);
+ regs->flags &= ~X86_EFLAGS_TF;
+}
next prev parent reply other threads:[~2010-12-16 10:02 UTC|newest]
Thread overview: 91+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-16 9:57 [RFC] [PATCH 2.6.37-rc5-tip 0/20] 0: Inode based uprobes Srikar Dronamraju
2010-12-16 9:57 ` [RFC] [PATCH 2.6.37-rc5-tip 1/20] 1: mm: Move replace_page() / write_protect_page() to mm/memory.c Srikar Dronamraju
2010-12-16 9:57 ` [RFC] [PATCH 2.6.37-rc5-tip 2/20] 2: X86 specific breakpoint definitions Srikar Dronamraju
2010-12-16 9:57 ` [RFC] [PATCH 2.6.37-rc5-tip 3/20] 3: uprobes: Breakground page replacement Srikar Dronamraju
2010-12-16 9:58 ` [RFC] [PATCH 2.6.37-rc5-tip 4/20] 4: uprobes: Adding and remove a uprobe in a rb tree Srikar Dronamraju
2011-01-25 12:15 ` Peter Zijlstra
2011-01-26 8:37 ` Srikar Dronamraju
2011-01-25 12:15 ` Peter Zijlstra
2011-01-26 8:41 ` Srikar Dronamraju
2011-01-26 10:13 ` Peter Zijlstra
2011-01-25 12:15 ` Peter Zijlstra
2011-01-26 8:38 ` Srikar Dronamraju
2011-01-25 13:56 ` Peter Zijlstra
2011-01-26 8:45 ` Srikar Dronamraju
2011-01-26 10:14 ` Peter Zijlstra
2011-01-26 15:18 ` Srikar Dronamraju
2011-01-26 15:33 ` Peter Zijlstra
2010-12-16 9:58 ` [RFC] [PATCH 2.6.37-rc5-tip 5/20] 5: Uprobes: register/unregister probes Srikar Dronamraju
2011-01-25 12:15 ` Peter Zijlstra
2011-01-26 7:55 ` Srikar Dronamraju
2011-01-26 10:11 ` Peter Zijlstra
2011-01-26 15:30 ` Srikar Dronamraju
2011-01-26 15:45 ` Peter Zijlstra
2011-01-26 16:56 ` Srikar Dronamraju
2011-01-26 17:12 ` Peter Zijlstra
2011-01-27 10:01 ` Srikar Dronamraju
2011-01-27 10:23 ` Peter Zijlstra
2011-01-27 10:25 ` Srikar Dronamraju
2011-01-27 10:41 ` Peter Zijlstra
2011-01-27 10:29 ` Peter Zijlstra
2011-01-25 12:15 ` Peter Zijlstra
2011-01-26 7:47 ` Srikar Dronamraju
2011-01-26 10:10 ` Peter Zijlstra
2010-12-16 9:58 ` [RFC] [PATCH 2.6.37-rc5-tip 6/20] 6: x86: analyze instruction and determine fixups Srikar Dronamraju
2010-12-16 9:58 ` [RFC] [PATCH 2.6.37-rc5-tip 7/20] 7: uprobes: store/restore original instruction Srikar Dronamraju
2011-01-25 12:15 ` Peter Zijlstra
2010-12-16 9:58 ` [RFC] [PATCH 2.6.37-rc5-tip 8/20] 8: uprobes: mmap and fork hooks Srikar Dronamraju
2011-01-25 12:15 ` Peter Zijlstra
2011-01-26 9:03 ` Srikar Dronamraju
2011-01-26 10:20 ` Peter Zijlstra
2011-01-26 14:59 ` Srikar Dronamraju
2011-01-26 15:16 ` Peter Zijlstra
2011-01-26 16:30 ` Srikar Dronamraju
2011-01-25 12:15 ` Peter Zijlstra
2011-01-25 20:05 ` Steven Rostedt
2011-01-26 9:06 ` Srikar Dronamraju
2011-01-27 17:03 ` Steven Rostedt
2011-01-28 4:53 ` Srikar Dronamraju
2011-01-28 13:57 ` Steven Rostedt
2011-01-28 14:28 ` Steven Rostedt
2011-01-28 14:46 ` Srikar Dronamraju
2011-01-28 15:02 ` Steven Rostedt
2011-01-26 15:09 ` Srikar Dronamraju
2011-01-26 15:20 ` Peter Zijlstra
2010-12-16 9:58 ` [RFC] [PATCH 2.6.37-rc5-tip 9/20] 9: x86: architecture specific task information Srikar Dronamraju
2010-12-16 9:59 ` [RFC] [PATCH 2.6.37-rc5-tip 10/20] 10: uprobes: task specific information Srikar Dronamraju
2011-01-25 13:56 ` Peter Zijlstra
2011-01-25 18:38 ` Josh Stone
2011-01-25 18:55 ` Roland McGrath
2011-01-25 19:56 ` Peter Zijlstra
2010-12-16 9:59 ` [RFC] [PATCH 2.6.37-rc5-tip 11/20] 11: uprobes: slot allocation for uprobes Srikar Dronamraju
2011-01-25 13:56 ` Peter Zijlstra
2010-12-16 9:59 ` [RFC] [PATCH 2.6.37-rc5-tip 12/20] 12: uprobes: get the breakpoint address Srikar Dronamraju
2011-01-25 13:56 ` Peter Zijlstra
2010-12-16 9:59 ` Srikar Dronamraju [this message]
2011-01-25 13:56 ` [RFC] [PATCH 2.6.37-rc5-tip 13/20] 13: x86: x86 specific probe handling Peter Zijlstra
2011-01-27 9:40 ` Srikar Dronamraju
2011-01-27 10:22 ` Peter Zijlstra
2011-01-27 19:11 ` Roland McGrath
2011-01-28 4:57 ` Srikar Dronamraju
2011-01-28 6:23 ` Roland McGrath
2011-01-28 8:36 ` Peter Zijlstra
2011-01-28 18:23 ` Roland McGrath
2010-12-16 9:59 ` [RFC] [PATCH 2.6.37-rc5-tip 14/20] 14: uprobes: Handing int3 and singlestep exception Srikar Dronamraju
2011-01-25 13:56 ` Peter Zijlstra
2011-01-25 13:56 ` Peter Zijlstra
2011-01-26 8:52 ` Srikar Dronamraju
2011-01-26 10:17 ` Peter Zijlstra
2011-01-26 15:14 ` Srikar Dronamraju
2011-01-26 15:29 ` Peter Zijlstra
2010-12-16 10:00 ` [RFC] [PATCH 2.6.37-rc5-tip 15/20] 15: x86: uprobes exception notifier for x86 Srikar Dronamraju
2010-12-16 10:00 ` [RFC] [PATCH 2.6.37-rc5-tip 16/20] 16: uprobes: register a notifier for uprobes Srikar Dronamraju
2011-01-25 13:56 ` Peter Zijlstra
2011-01-27 6:50 ` Srikar Dronamraju
2010-12-16 10:00 ` [RFC] [PATCH 2.6.37-rc5-tip 17/20] 17: uprobes: filter chain Srikar Dronamraju
2010-12-16 10:00 ` [RFC] [PATCH 2.6.37-rc5-tip 18/20] 18: uprobes: commonly used filters Srikar Dronamraju
2010-12-17 19:32 ` Valdis.Kletnieks
2010-12-18 3:04 ` Srikar Dronamraju
2010-12-16 10:00 ` [RFC] [PATCH 2.6.37-rc5-tip 19/20] 19: tracing: Extract out common code for kprobes/uprobes traceevents Srikar Dronamraju
2010-12-16 10:01 ` [RFC] [PATCH 2.6.37-rc5-tip 20/20] 20: tracing: uprobes trace_event interface Srikar Dronamraju
2010-12-16 10:07 ` [RFC] [PATCH 2.6.37-rc5-tip 0/20] 0: Inode based uprobes 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=20101216095947.23751.75003.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=fweisbec@gmail.com \
--cc=hch@infradead.org \
--cc=jkenisto@linux.vnet.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@vger.kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@elte.hu \
--cc=oleg@redhat.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=systemtap@sources.redhat.com \
--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