From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
To: linux-kernel@vger.kernel.org
Cc: oleg@redhat.com, ananth@in.ibm.com, a.p.zijlstra@chello.nl,
mingo@redhat.com, srikar@linux.vnet.ibm.com,
roland@hack.frob.com,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Subject: [PATCH 2/2] x86/uprobes: implement x86 specific arch_uprobe_*_step
Date: Tue, 31 Jul 2012 13:52:28 +0200 [thread overview]
Message-ID: <1343735548-18101-2-git-send-email-bigeasy@linutronix.de> (raw)
In-Reply-To: <1343735548-18101-1-git-send-email-bigeasy@linutronix.de>
The arch specific implementation enables single stepping directly by
setting the trap flag. "Single-Step on branches" is always disabled
since only one opcode has to be executed.
The disable call removes the trap flag unless it was there before. It
does not touch the flags register if the executed instruction was
"popf". It does not take into account various prefixes like "lock popf"
or "repz popf".
SIGTRAP is sent to the process in case it was traced so the debugger
knows once we advanced by one opcode. This isn't done in case we have to
restore the BTF flag. In case the BTF flag is set, we should look at the
opcode and send SIGTRAP depending on the jump/flag status. For now we
wait for the next exception/jump to be taken.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
arch/x86/include/asm/uprobes.h | 3 ++
arch/x86/kernel/uprobes.c | 60 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+)
diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
index f3971bb..47f4cf1 100644
--- a/arch/x86/include/asm/uprobes.h
+++ b/arch/x86/include/asm/uprobes.h
@@ -46,6 +46,9 @@ struct arch_uprobe_task {
#ifdef CONFIG_X86_64
unsigned long saved_scratch_register;
#endif
+#define UPROBE_CLEAR_TF (1 << 0)
+#define UPROBE_SET_BTF (1 << 1)
+ unsigned int restore_flags;
};
extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 36fd420..6eec3e4 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -673,3 +673,63 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
}
return false;
}
+
+static int insn_is_popf(const u8 *insn)
+{
+ /* popf */
+ if (insn[0] == 0x9d)
+ return 1;
+ return 0;
+}
+
+void arch_uprobe_enable_step(struct task_struct *child,
+ struct arch_uprobe *auprobe)
+{
+ struct uprobe_task *utask = child->utask;
+ struct arch_uprobe_task *autask = &utask->autask;
+ struct pt_regs *regs = task_pt_regs(child);
+ unsigned long debugctl;
+
+ autask->restore_flags = 0;
+ if (!(regs->flags & X86_EFLAGS_TF) &&
+ !insn_is_popf(auprobe->insn)) {
+ autask->restore_flags |= UPROBE_CLEAR_TF;
+
+ debugctl = get_debugctlmsr();
+ if (debugctl & DEBUGCTLMSR_BTF) {
+ autask->restore_flags |= UPROBE_SET_BTF;
+ debugctl &= ~DEBUGCTLMSR_BTF;
+ update_debugctlmsr(debugctl);
+ }
+ }
+ regs->flags |= X86_EFLAGS_TF;
+}
+
+void arch_uprobe_disable_step(struct task_struct *child,
+ struct arch_uprobe *auprobe)
+{
+ struct uprobe_task *utask = child->utask;
+ struct arch_uprobe_task *autask = &utask->autask;
+ struct pt_regs *regs = task_pt_regs(child);
+
+ /*
+ * Disable the single step flag if it was set by us. Notify the debugger
+ * via SIGTRAP in case it was already there so it learns that we
+ * advanced by an opcode unless the debugger is waiting for the next
+ * jump to be taken. This logic gets it wrong if the uprobe was set
+ * on jump instruction that would raise an exception.
+ */
+ if (autask->restore_flags & UPROBE_CLEAR_TF) {
+ regs->flags &= ~X86_EFLAGS_TF;
+ } else {
+ if (autask->restore_flags & UPROBE_SET_BTF) {
+ unsigned long debugctl;
+
+ debugctl = get_debugctlmsr();
+ debugctl |= DEBUGCTLMSR_BTF;
+ update_debugctlmsr(debugctl);
+ } else {
+ send_sig(SIGTRAP, current, 0);
+ }
+ }
+}
--
1.7.10.4
next prev parent reply other threads:[~2012-07-31 11:52 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-26 15:20 [PATCH] uprobes: don't enable/disable signle step if the user did it Sebastian Andrzej Siewior
2012-07-26 17:31 ` Oleg Nesterov
2012-07-27 17:39 ` Sebastian Andrzej Siewior
2012-07-27 18:04 ` Oleg Nesterov
2012-07-26 17:38 ` Sebastian Andrzej Siewior
2012-07-30 11:06 ` Ananth N Mavinakayanahalli
2012-07-30 14:16 ` Oleg Nesterov
2012-07-30 15:15 ` Sebastian Andrzej Siewior
2012-07-31 4:01 ` Ananth N Mavinakayanahalli
2012-07-31 5:22 ` Srikar Dronamraju
2012-07-31 17:38 ` Oleg Nesterov
2012-07-31 11:52 ` [PATCH 1/2] uprobes: Use a helper instead of ptrace's single step enable Sebastian Andrzej Siewior
2012-07-31 11:52 ` Sebastian Andrzej Siewior [this message]
2012-07-31 17:51 ` [PATCH 2/2] x86/uprobes: implement x86 specific arch_uprobe_*_step Oleg Nesterov
2012-07-31 19:30 ` Sebastian Andrzej Siewior
2012-08-01 12:26 ` Oleg Nesterov
2012-08-01 13:01 ` Q: user_enable_single_step() && update_debugctlmsr() Oleg Nesterov
2012-08-01 13:32 ` Sebastian Andrzej Siewior
2012-08-01 13:46 ` Oleg Nesterov
2012-08-01 13:54 ` Sebastian Andrzej Siewior
2012-08-01 14:01 ` Oleg Nesterov
2012-08-01 14:21 ` Sebastian Andrzej Siewior
2012-08-01 14:31 ` Oleg Nesterov
2012-08-01 14:47 ` Oleg Nesterov
2012-08-01 14:51 ` Sebastian Andrzej Siewior
2012-08-01 15:01 ` Oleg Nesterov
2012-08-01 15:12 ` Sebastian Andrzej Siewior
2012-08-01 15:14 ` Oleg Nesterov
2012-08-01 18:46 ` Sebastian Andrzej Siewior
2012-08-02 13:05 ` Oleg Nesterov
2012-08-02 13:20 ` Sebastian Andrzej Siewior
2012-08-02 13:24 ` Oleg Nesterov
2012-08-01 13:43 ` [PATCH 2/2] x86/uprobes: implement x86 specific arch_uprobe_*_step Oleg Nesterov
2012-08-02 4:58 ` Ananth N Mavinakayanahalli
2012-07-31 17:40 ` [PATCH 1/2] uprobes: Use a helper instead of ptrace's single step enable Oleg Nesterov
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=1343735548-18101-2-git-send-email-bigeasy@linutronix.de \
--to=bigeasy@linutronix.de \
--cc=a.p.zijlstra@chello.nl \
--cc=ananth@in.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=oleg@redhat.com \
--cc=roland@hack.frob.com \
--cc=srikar@linux.vnet.ibm.com \
/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).