[PATCH v7 3.2-rc2 30/30] x86: skip singlestep where possible

From: Srikar Dronamraju
Date: Fri Nov 18 2011 - 06:40:18 EST



Check and skip singlestepping underlying instructions where possible.

For now handles single byte as well as few multibyte nop instructions.
However can be extended to other instructions too.

Signed-off-by: Srikar Dronamraju <srikar@xxxxxxxxxxxxxxxxxx>
---
arch/x86/kernel/uprobes.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 3f0eb4e..f59053f 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -602,3 +602,47 @@ void abort_xol(struct pt_regs *regs, struct uprobe *uprobe)
handle_riprel_post_xol(uprobe, regs, NULL);
set_instruction_pointer(regs, utask->vaddr);
}
+
+/*
+ * Skip these instructions:
+ *
+ * 0f 19 90 90 90 90 90 nopl -0x6f6f6f70(%rax)
+ * 0f 1f 00 nopl (%rax)
+ * 0f 1f 40 00 nopl 0x0(%rax)
+ * 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
+ * 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
+ * 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
+ * 66 0f 1f 44 00 00 00 nopw 0x0(%rax,%rax,1)
+ * 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
+ * 66 87 c0 xchg %eax,%eax
+ * 66 90 nop
+ * 87 c0 xchg %eax,%eax
+ * 90 nop
+ */
+
+bool can_skip_xol(struct pt_regs *regs, struct uprobe *u)
+{
+ int i;
+
+ for (i = 0; i < MAX_UINSN_BYTES; i++) {
+ if ((u->insn[i] == 0x66))
+ continue;
+
+ if (u->insn[i] == 0x90)
+ return true;
+
+ if ((u->insn[i] == 0x0f) && (u->insn[i+1] == 0x1f))
+ return true;
+
+ if ((u->insn[i] == 0x0f) && (u->insn[i+1] == 0x19))
+ return true;
+
+ if ((u->insn[i] == 0x87) && (u->insn[i+1] == 0xc0))
+ return true;
+
+ break;
+ }
+
+ u->flags &= ~UPROBES_SKIP_SSTEP;
+ return false;
+}

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/