All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Remus <jremus@linux.ibm.com>
To: linux-kernel@vger.kernel.org, linux-trace-kernel@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>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	Josh Poimboeuf <jpoimboe@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@kernel.org>, Jiri Olsa <jolsa@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>,
	Jens Axboe <axboe@kernel.dk>, Florian Weimer <fweimer@redhat.com>,
	Sam James <sam@gentoo.org>
Subject: [RFC PATCH v1 06/16] unwind_user: Enable archs that define CFA = SP_callsite + offset
Date: Thu, 10 Jul 2025 18:35:12 +0200	[thread overview]
Message-ID: <20250710163522.3195293-7-jremus@linux.ibm.com> (raw)
In-Reply-To: <20250710163522.3195293-1-jremus@linux.ibm.com>

Most architectures define their CFA as the value of the stack pointer
(SP) at the call site in the previous frame, as suggested by the DWARF
standard:

  CFA = <SP at call site>

Enable unwinding of user space for architectures, such as s390, which
define their CFA as the value of the SP at the call site in the previous
frame with an offset:

  CFA = <SP at call site> + offset

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---

Notes (jremus):
    Alternatively the conditional definition of generic_sframe_sp_val_off()
    could be moved into kernel/unwind/sframe.c.

 arch/x86/include/asm/unwind_user.h       |  2 ++
 include/asm-generic/Kbuild               |  1 +
 include/asm-generic/unwind_user_sframe.h | 30 ++++++++++++++++++++++++
 include/linux/unwind_user_types.h        |  1 +
 kernel/unwind/sframe.c                   |  2 ++
 kernel/unwind/user.c                     |  8 ++++---
 6 files changed, 41 insertions(+), 3 deletions(-)
 create mode 100644 include/asm-generic/unwind_user_sframe.h

diff --git a/arch/x86/include/asm/unwind_user.h b/arch/x86/include/asm/unwind_user.h
index 19634a73612d..c2881840adf4 100644
--- a/arch/x86/include/asm/unwind_user.h
+++ b/arch/x86/include/asm/unwind_user.h
@@ -8,6 +8,7 @@
 	.cfa_off	= (s32)sizeof(long) *  2,				\
 	.ra_off		= (s32)sizeof(long) * -1,				\
 	.fp_off		= (s32)sizeof(long) * -2,				\
+	.sp_val_off	= (s32)0,						\
 	.use_fp		= true,
 
 #ifdef CONFIG_IA32_EMULATION
@@ -16,6 +17,7 @@
 	.cfa_off	= (s32)sizeof(u32)  *  2,				\
 	.ra_off		= (s32)sizeof(u32)  * -1,				\
 	.fp_off		= (s32)sizeof(u32)  * -2,				\
+	.sp_val_off	= (s32)0,						\
 	.use_fp		= true,
 
 #define in_compat_mode(regs) !user_64bit_mode(regs)
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index b797a2434396..64a15cde776c 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -60,6 +60,7 @@ mandatory-y += topology.h
 mandatory-y += trace_clock.h
 mandatory-y += uaccess.h
 mandatory-y += unwind_user.h
+mandatory-y += unwind_user_sframe.h
 mandatory-y += unwind_user_types.h
 mandatory-y += vermagic.h
 mandatory-y += vga.h
diff --git a/include/asm-generic/unwind_user_sframe.h b/include/asm-generic/unwind_user_sframe.h
new file mode 100644
index 000000000000..6c87a7f29861
--- /dev/null
+++ b/include/asm-generic/unwind_user_sframe.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_UNWIND_USER_SFRAME_H
+#define _ASM_GENERIC_UNWIND_USER_SFRAME_H
+
+#include <linux/types.h>
+
+/**
+ * generic_sframe_sp_val_off - Get generic SP value offset from CFA.
+ *
+ * During unwinding the stack pointer (SP) at call site can be derived
+ * from the Canonical Frame Address (CFA) as follows:
+ *
+ *   SP = CFA + SP_val_off
+ *
+ * Most architectures define the CFA as value of SP at call site, as
+ * suggested by DWARF. For those architectures the SP value offset
+ * from CFA is 0, so that the SP at call site computes as:
+ *
+ *   SP = CFA
+ *
+ * Returns the generic SP value offset from CFA of 0.
+ */
+static inline s32 generic_sframe_sp_val_off(void)
+{
+	return 0;
+}
+
+#define sframe_sp_val_off generic_sframe_sp_val_off
+
+#endif /* _ASM_GENERIC_UNWIND_USER_SFRAME_H */
diff --git a/include/linux/unwind_user_types.h b/include/linux/unwind_user_types.h
index 4d50476e950e..8050a3237a03 100644
--- a/include/linux/unwind_user_types.h
+++ b/include/linux/unwind_user_types.h
@@ -25,6 +25,7 @@ struct unwind_user_frame {
 	s32 cfa_off;
 	s32 ra_off;
 	s32 fp_off;
+	s32 sp_val_off;
 	bool use_fp;
 };
 
diff --git a/kernel/unwind/sframe.c b/kernel/unwind/sframe.c
index 6159f072bdb6..acbf791e713b 100644
--- a/kernel/unwind/sframe.c
+++ b/kernel/unwind/sframe.c
@@ -12,6 +12,7 @@
 #include <linux/mm.h>
 #include <linux/string_helpers.h>
 #include <linux/sframe.h>
+#include <asm/unwind_user_sframe.h>
 #include <linux/unwind_user_types.h>
 
 #include "sframe.h"
@@ -313,6 +314,7 @@ static __always_inline int __find_fre(struct sframe_section *sec,
 	frame->ra_off  = fre->ra_off;
 	frame->fp_off  = fre->fp_off;
 	frame->use_fp  = SFRAME_FRE_CFA_BASE_REG_ID(fre->info) == SFRAME_BASE_REG_FP;
+	frame->sp_val_off = sframe_sp_val_off();
 
 	return 0;
 }
diff --git a/kernel/unwind/user.c b/kernel/unwind/user.c
index d0181c636c6b..45c8c6932ba6 100644
--- a/kernel/unwind/user.c
+++ b/kernel/unwind/user.c
@@ -52,7 +52,7 @@ static int unwind_user_next(struct unwind_user_state *state)
 {
 	struct unwind_user_frame *frame;
 	struct unwind_user_frame _frame;
-	unsigned long cfa = 0, fp, ra = 0;
+	unsigned long cfa = 0, sp, fp, ra = 0;
 	unsigned int shift;
 
 	if (state->done)
@@ -84,8 +84,10 @@ static int unwind_user_next(struct unwind_user_state *state)
 	}
 	cfa += frame->cfa_off;
 
+	/* Get the Stack Pointer (SP) */
+	sp = cfa + frame->sp_val_off;
 	/* Make sure that stack is not going in wrong direction */
-	if (cfa <= state->sp)
+	if (sp <= state->sp)
 		goto done;
 
 	/* Make sure that the address is word aligned */
@@ -102,7 +104,7 @@ static int unwind_user_next(struct unwind_user_state *state)
 		goto done;
 
 	state->ip = ra;
-	state->sp = cfa;
+	state->sp = sp;
 	if (frame->fp_off)
 		state->fp = fp;
 
-- 
2.48.1


  parent reply	other threads:[~2025-07-10 16:36 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-10 16:35 [RFC PATCH v1 00/16] s390: SFrame user space unwinding Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 01/16] fixup! unwind_user: Add frame pointer support Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 02/16] s390: asm/dwarf.h should only be included in assembly files Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 03/16] s390/vdso: Avoid emitting DWARF CFI for non-vDSO Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 04/16] s390/vdso: Enable SFrame generation in vDSO Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 05/16] s390/vdso: Keep function symbols " Jens Remus
2025-07-10 16:35 ` Jens Remus [this message]
2025-07-16 21:32   ` [RFC PATCH v1 06/16] unwind_user: Enable archs that define CFA = SP_callsite + offset Josh Poimboeuf
2025-07-17  9:27     ` Jens Remus
2025-07-18  4:51       ` Josh Poimboeuf
2025-07-10 16:35 ` [RFC PATCH v1 07/16] unwind_user: Enable archs that do not necessarily save RA Jens Remus
2025-07-16 23:01   ` Josh Poimboeuf
2025-07-17 11:09     ` Jens Remus
2025-07-18  8:28       ` Jens Remus
2025-07-18 16:59         ` Josh Poimboeuf
2025-07-21 14:25           ` Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 08/16] unwind_user: Enable archs that save RA/FP in other registers Jens Remus
2025-07-17  2:01   ` Josh Poimboeuf
2025-07-17  2:50     ` Josh Poimboeuf
2025-07-17 12:07       ` Jens Remus
2025-07-18  4:52         ` Josh Poimboeuf
2025-07-17  3:57     ` Steven Rostedt
2025-07-17  7:24       ` Josh Poimboeuf
2025-07-17 12:05         ` Steven Rostedt
2025-07-17 11:28     ` Jens Remus
2025-07-17 12:10       ` Steven Rostedt
2025-07-18  4:51       ` Josh Poimboeuf
2025-07-10 16:35 ` [RFC PATCH v1 09/16] unwind_user/sframe: Enable archs with encoded SFrame CFA offsets Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 10/16] s390/ptrace: Enable HAVE_USER_RA_REG Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 11/16] s390/unwind_user/sframe: Enable HAVE_UNWIND_USER_SFRAME Jens Remus
2025-08-01 12:53   ` Heiko Carstens
2025-08-01 15:46     ` Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 12/16] unwind_user/backchain: Introduce back chain user space unwinding Jens Remus
2025-07-17  2:06   ` Josh Poimboeuf
2025-07-17 12:20     ` Jens Remus
2025-07-18  5:19       ` Josh Poimboeuf
2025-08-01 12:36         ` Heiko Carstens
2025-08-01 15:49           ` Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 13/16] s390/unwind_user/backchain: Enable HAVE_UNWIND_USER_BACKCHAIN Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 14/16] PREREQ: x86/asm: Avoid emitting DWARF CFI for non-VDSO Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 15/16] PREREQ: x86/vdso: Enable sframe generation in VDSO Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 16/16] WIP: fixup! s390/unwind_user/sframe: Enable HAVE_UNWIND_USER_SFRAME 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=20250710163522.3195293-7-jremus@linux.ibm.com \
    --to=jremus@linux.ibm.com \
    --cc=akpm@linux-foundation.org \
    --cc=andrii@kernel.org \
    --cc=axboe@kernel.dk \
    --cc=beaub@linux.microsoft.com \
    --cc=bpf@vger.kernel.org \
    --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=linux-kernel@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.