On Mon, Apr 07, 2025 at 01:07:26PM +0200, Jiri Olsa wrote: > On Fri, Apr 04, 2025 at 01:33:11PM -0700, Andrii Nakryiko wrote: > > On Thu, Mar 20, 2025 at 4:43 AM Jiri Olsa <jo...@kernel.org> wrote: > > > > > > Adding support to emulate nop5 as the original uprobe instruction. > > > > > > Signed-off-by: Jiri Olsa <jo...@kernel.org> > > > --- > > > arch/x86/kernel/uprobes.c | 16 ++++++++++++++++ > > > 1 file changed, 16 insertions(+) > > > > > > > This optimization is independent from the sys_uprobe, right? Maybe > > send it as a stand-alone patch and let's land it sooner? > > ok, will send it separately > > > Also, how hard would it be to do the same for other nopX instructions? > > will check, might be easy
we can't do all at the moment, nop1-nop8 are fine, but uprobe won't attach on nop9/10/11 due unsupported prefix.. I guess insn decode would need to be updated first I'll send the nop5 emulation change, because of above and also I don't see practical justification to emulate other nops jirka --- diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 9194695662b2..6616cc9866cc 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c @@ -608,6 +608,21 @@ static void riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) *sr = utask->autask.saved_scratch_register; } } + +static bool emulate_nop_insn(struct arch_uprobe *auprobe) +{ + unsigned int i; + + /* + * Uprobe is only allowed to be attached on nop1 through nop8. Further nop + * instructions have unsupported prefix and uprobe fails to attach on them. + */ + for (i = 1; i < 9; i++) { + if (!memcmp(&auprobe->insn, x86_nops[i], i)) + return true; + } + return false; +} #else /* 32-bit: */ /* * No RIP-relative addressing on 32-bit @@ -621,6 +636,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_nop_insn(struct arch_uprobe *auprobe) +{ + return false; +} #endif /* CONFIG_X86_64 */ struct uprobe_xol_ops { @@ -840,6 +859,9 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn) insn_byte_t p; int i; + if (emulate_nop_insn(auprobe)) + goto setup; + switch (opc1) { case 0xeb: /* jmp 8 */ case 0xe9: /* jmp 32 */