From d241006354c550c7d22f304e2fdf90137fb8eaab Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sat, 5 Apr 2014 21:06:10 +0200 Subject: uprobes/x86: Emulate nop's using ops->emulate() Finally we can kill the ugly (and very limited) code in __skip_sstep(). Just change branch_setup_xol_ops() to treat "nop" as jmp to the next insn. Thanks to lib/insn.c, it is clever enough. OPCODE1() == 0x90 includes "(rep;)+ nop;" at least, and (afaics) much more. Signed-off-by: Oleg Nesterov Reviewed-by: Jim Keniston diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index c3baeaa..f3c4212 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c @@ -478,6 +478,7 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn) switch (OPCODE1(insn)) { case 0xeb: /* jmp 8 */ case 0xe9: /* jmp 32 */ + case 0x90: /* prefix* + nop; same as jmp with .offs = 0 */ break; default: return -ENOSYS; @@ -710,29 +711,10 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) regs->flags &= ~X86_EFLAGS_TF; } -/* - * Skip these instructions as per the currently known x86 ISA. - * rep=0x66*; nop=0x90 - */ static bool __skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) { - int i; - if (auprobe->ops->emulate) return auprobe->ops->emulate(auprobe, regs); - - /* TODO: move this code into ->emulate() hook */ - for (i = 0; i < MAX_UINSN_BYTES; i++) { - if (auprobe->insn[i] == 0x66) - continue; - - if (auprobe->insn[i] == 0x90) { - regs->ip += i + 1; - return true; - } - - break; - } return false; } -- cgit v0.10.2