On 04/08, Jiri Olsa wrote: > > --- a/arch/x86/kernel/uprobes.c > +++ b/arch/x86/kernel/uprobes.c > @@ -608,6 +608,16 @@ static void riprel_post_xol(struct arch_uprobe *auprobe, > struct pt_regs *regs) > *sr = utask->autask.saved_scratch_register; > } > } > + > +static int is_nop5_insn(uprobe_opcode_t *insn) > +{ > + return !memcmp(insn, x86_nops[5], 5); > +} > + > +static bool emulate_nop5_insn(struct arch_uprobe *auprobe) > +{ > + return is_nop5_insn((uprobe_opcode_t *) &auprobe->insn); > +}
Why do we need 2 functions? Can't branch_setup_xol_ops() just use is_nop5_insn(insn->kaddr) ? > #else /* 32-bit: */ > /* > * No RIP-relative addressing on 32-bit > @@ -621,6 +631,10 @@ static void riprel_pre_xol(struct arch_uprobe *auprobe, > struct pt_regs *regs) > static void riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs > *regs) > { > } > +static bool emulate_nop5_insn(struct arch_uprobe *auprobe) > +{ > + return false; > +} Hmm, why? I mean, why we can't emulate x86_nops[5] if !CONFIG_X86_64 ? OTOH. What if the kernel is 64-bit, but the probed task is 32-bit and it uses the 64-bit version of BYTES_NOP5? Perhaps this is fine, I simply don't know, so let me ask... > @@ -852,6 +866,8 @@ static int branch_setup_xol_ops(struct arch_uprobe > *auprobe, struct insn *insn) > break; > > case 0x0f: > + if (emulate_nop5_insn(auprobe)) > + goto setup; I think this will work, but if we want to emulate nop5, then perhaps we can do the same for other nops? For the moment, lets forget about compat tasks on a 64-bit kernel, can't we simply do something like below? Oleg. --- diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 9194695662b2..76d2cceca6c4 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c @@ -840,12 +840,16 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn) insn_byte_t p; int i; + /* prefix* + nop[i]; same as jmp with .offs = 0 */ + for (i = 1; i <= ASM_NOP_MAX; ++i) { + if (!memcmp(insn->kaddr, x86_nops[i], i)) + goto setup; + } + switch (opc1) { case 0xeb: /* jmp 8 */ case 0xe9: /* jmp 32 */ break; - case 0x90: /* prefix* + nop; same as jmp with .offs = 0 */ - goto setup; case 0xe8: /* call relative */ branch_clear_offset(auprobe, insn);