| From | Srikar Dronamraju <> | Date | Fri, 18 Nov 2011 16:42:39 +0530 | Subject | [PATCH v7 3.2-rc2 30/30] x86: skip singlestep where possible |
| |
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@linux.vnet.ibm.com> --- 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; +}
|