Skip to content

Commit

Permalink
uprobes/x86: Emulate nop's using ops->emulate()
Browse files Browse the repository at this point in the history
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 <oleg@redhat.com>
Reviewed-by: Jim Keniston <jkenisto@us.ibm.com>
  • Loading branch information
Oleg Nesterov committed Apr 17, 2014
1 parent 7ba6db2 commit d241006
Showing 1 changed file with 1 addition and 19 deletions.
20 changes: 1 addition & 19 deletions arch/x86/kernel/uprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit d241006

Please sign in to comment.