On Fri, Aug 11, 2023 at 10:37 PM Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx> wrote: > > +#ifdef CONFIG_HAVE_REGS_AND_STACK_ACCESS_API > +static __always_inline unsigned long > +ftrace_regs_get_kernel_stack_nth(struct ftrace_regs *fregs, unsigned int nth) > +{ > + unsigned long *stackp; > + > + stackp = (unsigned long *)ftrace_regs_get_stack_pointer(fregs); > + if (((unsigned long)(stackp + nth) & ~(THREAD_SIZE - 1)) == > + ((unsigned long)stackp & ~(THREAD_SIZE - 1))) > + return *(stackp + nth); > + > + return 0; > +} > +#endif /* CONFIG_HAVE_REGS_AND_STACK_ACCESS_API */ ... > > @@ -140,17 +140,17 @@ process_fetch_insn(struct fetch_insn *code, void *rec, void *dest, > /* 1st stage: get value from context */ > switch (code->op) { > case FETCH_OP_STACK: > - val = regs_get_kernel_stack_nth(regs, code->param); > + val = ftrace_regs_get_kernel_stack_nth(fregs, code->param); > break; Just noticed that bit. You probably want to document that access to arguments and especially arguments on stack is not precise. It's "best effort". x86-64 calling convention is not as simple as it might appear. For example if 6th argument is a 16-byte struct like sockptr_t it will be passed on the stack and 7th actual argument (if it's <= 8 byte) will be the register. Things similar on 32-bit and there is a non-zero chance that regs_get_kernel_argument() doesn't return the actual arg.