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.. ?