From: Jens Remus <jremus@linux.ibm.com>
To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
linux-s390@vger.kernel.org, bpf@vger.kernel.org, x86@kernel.org,
Steven Rostedt <rostedt@kernel.org>
Cc: Jens Remus <jremus@linux.ibm.com>,
Heiko Carstens <hca@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Ilya Leoshkevich <iii@linux.ibm.com>,
Josh Poimboeuf <jpoimboe@kernel.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@kernel.org>, Jiri Olsa <jolsa@kernel.org>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
Andrii Nakryiko <andrii@kernel.org>,
Indu Bhagat <indu.bhagat@oracle.com>,
"Jose E. Marchesi" <jemarch@gnu.org>,
Beau Belgrave <beaub@linux.microsoft.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
Andrew Morton <akpm@linux-foundation.org>,
Florian Weimer <fweimer@redhat.com>, Kees Cook <kees@kernel.org>,
"Carlos O'Donell" <codonell@redhat.com>,
Sam James <sam@gentoo.org>, Dylan Hatch <dylanbhatch@google.com>
Subject: [RFC PATCH v3 10/17] unwind_user: Enable archs that pass RA in a register
Date: Mon, 8 Dec 2025 18:15:52 +0100 [thread overview]
Message-ID: <20251208171559.2029709-11-jremus@linux.ibm.com> (raw)
In-Reply-To: <20251208171559.2029709-1-jremus@linux.ibm.com>
Not all architectures have the return address (RA) in user space saved
on the stack on function entry, such as x86-64 does due to its CALL
instruction pushing the RA onto the stack. Architectures/ABIs, such as
s390, also do not necessarily enforce to save the RA in user space on
the stack in the function prologue or even at all, for instance in leaf
functions.
Treat a RA offset from CFA of zero as indication that the RA is not
saved (on the stack). For the topmost frame treat it as indication that
the RA is in the link/RA register, such as on arm64 and s390, and obtain
it from there. For non-topmost frames treat it as error, as the RA must
be saved.
Additionally allow the SP to be unchanged in the topmost frame, for
architectures where SP at function entry == SP at call site, such as
arm64 and s390.
Note that treating a RA offset from CFA of zero as indication that
the RA is not saved on the stack additionally allows for architectures,
such as s390, where the frame pointer (FP) may be saved without the RA
being saved as well. Provided that such architectures represent this
in SFrame by encoding the "missing" RA offset using a padding RA offset
with a value of zero.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---
Notes (jremus):
Changes in v2:
- Reword commit subject and message.
- Rename config option USER_RA_REG to UNWIND_USER_RA_REG and reword
help text to mention both link and return address register. (Josh)
- Move dummy user_return_address() from linux/ptrace.h to
linux/unwind_user.h, rename to unwind_user_get_ra_reg(),
return -EINVAL, and guard by !CONFIG_HAVE_UNWIND_USER_RA_REG. (Josh)
- Do not check for !IS_ENABLED(CONFIG_HAVE_USER_RA_REG), as the dummy
implementation of user_return_address() returns -EINVAL.
- Drop config option USER_RA_REG / UNWIND_USER_RA_REG, as it is of
no value any longer.
- Drop topmost checks from unwind user sframe, as they are already
done by unwind user. (Josh)
include/linux/unwind_user.h | 9 +++++++++
kernel/unwind/sframe.c | 6 ++----
kernel/unwind/user.c | 17 +++++++++++++----
3 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/include/linux/unwind_user.h b/include/linux/unwind_user.h
index 64618618febd..bc2edae39955 100644
--- a/include/linux/unwind_user.h
+++ b/include/linux/unwind_user.h
@@ -23,6 +23,15 @@ static inline bool unwind_user_at_function_start(struct pt_regs *regs)
#define unwind_user_at_function_start unwind_user_at_function_start
#endif
+#ifndef unwind_user_get_ra_reg
+static inline int unwind_user_get_ra_reg(unsigned long *val)
+{
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+}
+#define unwind_user_get_ra_reg unwind_user_get_ra_reg
+#endif
+
int unwind_user(struct unwind_stacktrace *trace, unsigned int max_entries);
#endif /* _LINUX_UNWIND_USER_H */
diff --git a/kernel/unwind/sframe.c b/kernel/unwind/sframe.c
index 7952b041dd23..38b3577f5253 100644
--- a/kernel/unwind/sframe.c
+++ b/kernel/unwind/sframe.c
@@ -228,10 +228,8 @@ static __always_inline int __read_fre(struct sframe_section *sec,
offset_count--;
ra_off = sec->ra_off;
- if (!ra_off) {
- if (!offset_count--)
- return -EFAULT;
-
+ if (!ra_off && offset_count) {
+ offset_count--;
UNSAFE_GET_USER_INC(ra_off, cur, offset_size, Efault);
}
diff --git a/kernel/unwind/user.c b/kernel/unwind/user.c
index 6c75a7411871..58e1549cd9f4 100644
--- a/kernel/unwind/user.c
+++ b/kernel/unwind/user.c
@@ -50,16 +50,25 @@ static int unwind_user_next_common(struct unwind_user_state *state,
/* Get the Stack Pointer (SP) */
sp = cfa + frame->sp_off;
- /* Make sure that stack is not going in wrong direction */
- if (sp <= state->sp)
+ /*
+ * Make sure that stack is not going in wrong direction. Allow SP
+ * to be unchanged for the topmost frame, by subtracting topmost,
+ * which is either 0 or 1.
+ */
+ if (sp <= state->sp - state->topmost)
return -EINVAL;
/* Make sure that the address is word aligned */
if (sp & (state->ws - 1))
return -EINVAL;
/* Get the Return Address (RA) */
- if (get_user_word(&ra, cfa, frame->ra_off, state->ws))
- return -EINVAL;
+ if (frame->ra_off) {
+ if (get_user_word(&ra, cfa, frame->ra_off, state->ws))
+ return -EINVAL;
+ } else {
+ if (!state->topmost || unwind_user_get_ra_reg(&ra))
+ return -EINVAL;
+ }
/* Get the Frame Pointer (FP) */
if (frame->fp_off && get_user_word(&fp, cfa, frame->fp_off, state->ws))
--
2.51.0
next prev parent reply other threads:[~2025-12-08 17:16 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-08 17:15 [RFC PATCH v3 00/17] s390: SFrame user space unwinding Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 01/17] unwind_user: Enhance comments on get CFA, FP, and RA Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 02/17] unwind_user/fp: Use dummies instead of ifdef Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 03/17] x86/unwind_user: Guard unwind_user_word_size() by UNWIND_USER Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 04/17] x86/unwind_user: Simplify unwind_user_word_size() Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 05/17] s390: asm/dwarf.h should only be included in assembly files Jens Remus
2025-12-10 15:16 ` Heiko Carstens
2025-12-11 9:43 ` Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 06/17] s390/vdso: Avoid emitting DWARF CFI for non-vDSO Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 07/17] s390/vdso: Keep function symbols in vDSO Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 08/17] s390/vdso: Enable SFrame generation " Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 09/17] unwind_user: Enable archs that define CFA = SP_callsite + offset Jens Remus
2025-12-08 17:15 ` Jens Remus [this message]
2025-12-08 17:15 ` [RFC PATCH v3 11/17] unwind_user: Enable archs that save RA/FP in other registers Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 12/17] unwind_user/sframe: Enable archs with encoded SFrame CFA offsets Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 13/17] s390/ptrace: Provide frame_pointer() Jens Remus
2025-12-10 15:19 ` Heiko Carstens
2025-12-08 17:15 ` [RFC PATCH v3 14/17] s390/unwind_user/sframe: Enable HAVE_UNWIND_USER_SFRAME Jens Remus
2025-12-10 15:10 ` Heiko Carstens
2025-12-12 8:13 ` Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 15/17] unwind_user: Introduce FP/RA location unknown Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 16/17] unwind_user/fp: Use arch-specific helper to initialize FP frame Jens Remus
2025-12-08 17:15 ` [RFC PATCH v3 17/17] s390/unwind_user/fp: Enable back chain unwinding of user space Jens Remus
2025-12-12 9:21 ` Jens Remus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251208171559.2029709-11-jremus@linux.ibm.com \
--to=jremus@linux.ibm.com \
--cc=acme@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=andrii@kernel.org \
--cc=beaub@linux.microsoft.com \
--cc=bpf@vger.kernel.org \
--cc=codonell@redhat.com \
--cc=dylanbhatch@google.com \
--cc=fweimer@redhat.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=iii@linux.ibm.com \
--cc=indu.bhagat@oracle.com \
--cc=jemarch@gnu.org \
--cc=jolsa@kernel.org \
--cc=jpoimboe@kernel.org \
--cc=kees@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mhiramat@kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=rostedt@kernel.org \
--cc=sam@gentoo.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).