On 25.07.2025 20:55, Steven Rostedt wrote: > From: Josh Poimboeuf <jpoimboe@xxxxxxxxxx> > > Introduce a generic API for unwinding user stacks. > > In order to expand user space unwinding to be able to handle more complex > scenarios, such as deferred unwinding and reading user space information, > create a generic interface that all architectures can use that support the > various unwinding methods. > > This is an alternative method for handling user space stack traces from > the simple stack_trace_save_user() API. This does not replace that > interface, but this interface will be used to expand the functionality of > user space stack walking. > > None of the structures introduced will be exposed to user space tooling. > > Support for frame pointer unwinding is added. For an architecture to > support frame pointer unwinding it needs to enable > CONFIG_HAVE_UNWIND_USER_FP and define ARCH_INIT_USER_FP_FRAME. > > By encoding the frame offsets in struct unwind_user_frame, much of this > code can also be reused for future unwinder implementations like sframe. > > Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx> > Co-developed-by: Mathieu Desnoyers <mathieu.desnoyers@xxxxxxxxxxxx> > Link: https://lore.kernel.org/all/20250710164301.3094-2-mathieu.desnoyers@xxxxxxxxxxxx/ > Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@xxxxxxxxxxxx> > Co-developed-by: Steven Rostedt (Google) <rostedt@xxxxxxxxxxx> > Signed-off-by: Steven Rostedt (Google) <rostedt@xxxxxxxxxxx> Reviewed-by: Jens Remus <jremus@xxxxxxxxxxxxx> > diff --git a/kernel/unwind/user.c b/kernel/unwind/user.c > +static int unwind_user_next_fp(struct unwind_user_state *state) > +{ > + struct unwind_user_frame *frame = &fp_frame; Optional: Pointer to const? > + unsigned long cfa, fp, ra = 0; Nit: Is initialization of ra really required? I don't see where ra would be getting used without being set beforehand. > + unsigned int shift; > + > + if (frame->use_fp) { > + if (state->fp < state->sp) > + return -EINVAL; > + cfa = state->fp; > + } else { > + cfa = state->sp; > + } > + > + /* Get the Canonical Frame Address (CFA) */ > + cfa += frame->cfa_off; > + > + /* stack going in wrong direction? */ > + if (cfa <= state->sp) > + return -EINVAL; > + > + /* Make sure that the address is word aligned */ > + shift = sizeof(long) == 4 ? 2 : 3; > + if (cfa & ((1 << shift) - 1)) > + return -EINVAL; > + > + /* Find the Return Address (RA) */ > + if (get_user(ra, (unsigned long *)(cfa + frame->ra_off))) > + return -EINVAL; > + > + if (frame->fp_off && get_user(fp, (unsigned long __user *)(cfa + frame->fp_off))) > + return -EINVAL; > + > + state->ip = ra; > + state->sp = cfa; > + if (frame->fp_off) > + state->fp = fp; > + return 0; > +} Regards, Jens -- Jens Remus Linux on Z Development (D3303) +49-7031-16-1128 Office jremus@xxxxxxxxxx IBM IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294 IBM Data Privacy Statement: https://www.ibm.com/privacy/