[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aHV2vLQiWIbSrttH@krava>
Date: Mon, 14 Jul 2025 23:29:32 +0200
From: Jiri Olsa <olsajiri@...il.com>
To: Peter Zijlstra <peterz@...radead.org>
Cc: Masami Hiramatsu <mhiramat@...nel.org>, Oleg Nesterov <oleg@...hat.com>,
Andrii Nakryiko <andrii@...nel.org>, bpf@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-trace-kernel@...r.kernel.org,
x86@...nel.org, Song Liu <songliubraving@...com>,
Yonghong Song <yhs@...com>,
John Fastabend <john.fastabend@...il.com>,
Hao Luo <haoluo@...gle.com>, Steven Rostedt <rostedt@...dmis.org>,
Alan Maguire <alan.maguire@...cle.com>,
David Laight <David.Laight@...lab.com>,
Thomas Weißschuh <thomas@...ch.de>,
Ingo Molnar <mingo@...nel.org>
Subject: Re: [PATCHv5 perf/core 09/22] uprobes/x86: Add uprobe syscall to
speed up uprobe
On Mon, Jul 14, 2025 at 11:28:01AM +0200, Peter Zijlstra wrote:
> On Mon, Jul 14, 2025 at 05:39:15PM +0900, Masami Hiramatsu wrote:
>
> > > +SYSCALL_DEFINE0(uprobe)
> > > +{
> > > + struct pt_regs *regs = task_pt_regs(current);
> > > + unsigned long ip, sp, ax_r11_cx_ip[4];
> > > + int err;
> > > +
> > > + /* Allow execution only from uprobe trampolines. */
> > > + if (!in_uprobe_trampoline(regs->ip))
> > > + goto sigill;
> > > +
> >
> > /*
> > * When syscall from the trampoline, including a call to the trampoline
> > * the stack will be shown as;
> > * regs->sp[0]: [rax]
> > * [1]: [r11]
> > * [2]: [rcx]
> > * [3]: [return-address] (probed address + sizeof(call-instruction))
> > *
> > * And the `®s->sp[4]` should be the `sp` value when probe is hit.
> > */
> >
> > > + err = copy_from_user(ax_r11_cx_ip, (void __user *)regs->sp, sizeof(ax_r11_cx_ip));
> > > + if (err)
> > > + goto sigill;
> > > +
> > > + ip = regs->ip;
> > > +
> > > + /*
> > > + * expose the "right" values of ax/r11/cx/ip/sp to uprobe_consumer/s, plus:
> > > + * - adjust ip to the probe address, call saved next instruction address
> > > + * - adjust sp to the probe's stack frame (check trampoline code)
> > > + */
> > > + regs->ax = ax_r11_cx_ip[0];
> > > + regs->r11 = ax_r11_cx_ip[1];
> > > + regs->cx = ax_r11_cx_ip[2];
> > > + regs->ip = ax_r11_cx_ip[3] - 5;
> > > + regs->sp += sizeof(ax_r11_cx_ip);
> > > + regs->orig_ax = -1;
> > > +
>
> Would not a structure be more natural?
>
> /*
> * See uprobe syscall trampoline; the call to the trampoline will push
> * the return address on the stack, the trampoline itself then pushes
> * cx, r11 and ax.
> */
> struct uprobe_syscall_args {
> unsigned long ax;
> unsigned long r11;
> unsigned long cx;
> unsigned long retaddr;
> };
>
> err = copy_from_user(sys_args, (void __user *)regs->sp, sizeof(sys_args));
> if (err)
> goto sigill;
>
> ip = regs->ip;
>
> regs->ax = sys_args->ax;
> regs->r11 = sys_args->r11;
> regs->cx = sys_args->cx;
> regs->ip = sys_args->retaddr - CALL_INSN_SIZE;
> regs->sp += sizeof(sys_args);
>
> etc.. ?
I was mimicking sys_uretprobe, but using struct does seem better
thanks,
jirka
Powered by blists - more mailing lists