All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	bpf@vger.kernel.org, x86@kernel.org
Cc: 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>,
	Jens Remus <jremus@linux.ibm.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: [PATCH v10 02/14] unwind_user: Add frame pointer support
Date: Tue, 10 Jun 2025 20:54:23 -0400	[thread overview]
Message-ID: <20250611010428.092934995@goodmis.org> (raw)
In-Reply-To: 20250611005421.144238328@goodmis.org

From: Josh Poimboeuf <jpoimboe@kernel.org>

Add optional support for user space frame pointer unwinding.  If
supported, the arch 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@kernel.org>
Co-developed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
Changes since v9: https://lore.kernel.org/linux-trace-kernel/20250513223551.290698040@goodmis.org/

As asm-generic headers are not included when an architecture defines the
header, having more than one #ifndef and setting variables does not work
with those checks in the asm-generic header and the architecture header
does not define all the values.

- Move ARCH_INIT_USER_FP_FRAME check to linux/user_unwind.h

- Have linux/user_unwind.h include asm/user_unwind.h and not have C files
  have to call the asm header directly

- Remove unnecessary frame initialization

- Added unwind_user.h to asm-generic/Kbuild

 arch/Kconfig                      |  4 +++
 include/asm-generic/Kbuild        |  1 +
 include/asm-generic/unwind_user.h |  5 ++++
 include/linux/unwind_user.h       |  5 ++++
 include/linux/unwind_user_types.h |  1 +
 kernel/unwind/user.c              | 49 +++++++++++++++++++++++++++++--
 6 files changed, 63 insertions(+), 2 deletions(-)
 create mode 100644 include/asm-generic/unwind_user.h

diff --git a/arch/Kconfig b/arch/Kconfig
index ea59e5d7cc69..8e3fd723bd74 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -438,6 +438,10 @@ config HAVE_HARDLOCKUP_DETECTOR_ARCH
 config UNWIND_USER
 	bool
 
+config HAVE_UNWIND_USER_FP
+	bool
+	select UNWIND_USER
+
 config HAVE_PERF_REGS
 	bool
 	help
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index 8675b7b4ad23..295c94a3ccc1 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -59,6 +59,7 @@ mandatory-y += tlbflush.h
 mandatory-y += topology.h
 mandatory-y += trace_clock.h
 mandatory-y += uaccess.h
+mandatory-y += unwind_user.h
 mandatory-y += vermagic.h
 mandatory-y += vga.h
 mandatory-y += video.h
diff --git a/include/asm-generic/unwind_user.h b/include/asm-generic/unwind_user.h
new file mode 100644
index 000000000000..b8882b909944
--- /dev/null
+++ b/include/asm-generic/unwind_user.h
@@ -0,0 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_UNWIND_USER_H
+#define _ASM_GENERIC_UNWIND_USER_H
+
+#endif /* _ASM_GENERIC_UNWIND_USER_H */
diff --git a/include/linux/unwind_user.h b/include/linux/unwind_user.h
index aa7923c1384f..a405111c41b0 100644
--- a/include/linux/unwind_user.h
+++ b/include/linux/unwind_user.h
@@ -3,6 +3,11 @@
 #define _LINUX_UNWIND_USER_H
 
 #include <linux/unwind_user_types.h>
+#include <asm/unwind_user.h>
+
+#ifndef ARCH_INIT_USER_FP_FRAME
+ #define ARCH_INIT_USER_FP_FRAME
+#endif
 
 int unwind_user_start(struct unwind_user_state *state);
 int unwind_user_next(struct unwind_user_state *state);
diff --git a/include/linux/unwind_user_types.h b/include/linux/unwind_user_types.h
index 6ed1b4ae74e1..65bd070eb6b0 100644
--- a/include/linux/unwind_user_types.h
+++ b/include/linux/unwind_user_types.h
@@ -6,6 +6,7 @@
 
 enum unwind_user_type {
 	UNWIND_USER_TYPE_NONE,
+	UNWIND_USER_TYPE_FP,
 };
 
 struct unwind_stacktrace {
diff --git a/kernel/unwind/user.c b/kernel/unwind/user.c
index d30449328981..4fc550356b33 100644
--- a/kernel/unwind/user.c
+++ b/kernel/unwind/user.c
@@ -6,10 +6,52 @@
 #include <linux/sched.h>
 #include <linux/sched/task_stack.h>
 #include <linux/unwind_user.h>
+#include <linux/uaccess.h>
+
+static struct unwind_user_frame fp_frame = {
+	ARCH_INIT_USER_FP_FRAME
+};
+
+static inline bool fp_state(struct unwind_user_state *state)
+{
+	return IS_ENABLED(CONFIG_HAVE_UNWIND_USER_FP) &&
+	       state->type == UNWIND_USER_TYPE_FP;
+}
 
 int unwind_user_next(struct unwind_user_state *state)
 {
-	/* no implementation yet */
+	struct unwind_user_frame *frame;
+	unsigned long cfa = 0, fp, ra = 0;
+
+	if (state->done)
+		return -EINVAL;
+
+	if (fp_state(state))
+		frame = &fp_frame;
+	else
+		goto the_end;
+
+	cfa = (frame->use_fp ? state->fp : state->sp) + frame->cfa_off;
+
+	/* stack going in wrong direction? */
+	if (cfa <= state->sp)
+		goto the_end;
+
+	if (get_user(ra, (unsigned long *)(cfa + frame->ra_off)))
+		goto the_end;
+
+	if (frame->fp_off && get_user(fp, (unsigned long __user *)(cfa + frame->fp_off)))
+		goto the_end;
+
+	state->ip = ra;
+	state->sp = cfa;
+	if (frame->fp_off)
+		state->fp = fp;
+
+	return 0;
+
+the_end:
+	state->done = true;
 	return -EINVAL;
 }
 
@@ -24,7 +66,10 @@ int unwind_user_start(struct unwind_user_state *state)
 		return -EINVAL;
 	}
 
-	state->type = UNWIND_USER_TYPE_NONE;
+	if (IS_ENABLED(CONFIG_HAVE_UNWIND_USER_FP))
+		state->type = UNWIND_USER_TYPE_FP;
+	else
+		state->type = UNWIND_USER_TYPE_NONE;
 
 	state->ip = instruction_pointer(regs);
 	state->sp = user_stack_pointer(regs);
-- 
2.47.2



  parent reply	other threads:[~2025-06-11  1:03 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-11  0:54 [PATCH v10 00/14] unwind_user: x86: Deferred unwinding infrastructure Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 01/14] unwind_user: Add user space unwinding API Steven Rostedt
2025-06-18 13:49   ` Peter Zijlstra
2025-06-11  0:54 ` Steven Rostedt [this message]
2025-06-18 13:52   ` [PATCH v10 02/14] unwind_user: Add frame pointer support Peter Zijlstra
2025-06-18 15:09     ` Steven Rostedt
2025-06-23 16:31       ` Indu Bhagat
2025-06-24 20:30         ` Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 03/14] unwind_user: Add compat mode " Steven Rostedt
2025-06-18 13:46   ` Peter Zijlstra
2025-06-18 15:10     ` Steven Rostedt
2025-06-18 17:52       ` Linus Torvalds
2025-06-18 18:37         ` Steven Rostedt
2025-06-18 13:47   ` Peter Zijlstra
2025-06-18 15:18     ` Steven Rostedt
2025-06-19  7:51       ` Peter Zijlstra
2025-06-19  8:39         ` Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 04/14] unwind_user/deferred: Add unwind_deferred_trace() Steven Rostedt
2025-06-18 13:54   ` Peter Zijlstra
2025-06-18 13:59   ` Peter Zijlstra
2025-06-18 15:20     ` Steven Rostedt
2025-06-18 16:26       ` Steven Rostedt
2025-06-18 14:01   ` Peter Zijlstra
2025-06-18 15:23     ` Steven Rostedt
2025-06-18 14:02   ` Peter Zijlstra
2025-06-18 15:29     ` Steven Rostedt
2025-06-19  7:54       ` Peter Zijlstra
2025-06-19  8:44         ` Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 05/14] unwind_user/deferred: Add unwind cache Steven Rostedt
2025-06-18 14:13   ` Peter Zijlstra
2025-06-18 15:33     ` Steven Rostedt
2025-06-19  7:56       ` Peter Zijlstra
2025-06-19  8:47         ` Steven Rostedt
2025-06-19  9:04           ` Peter Zijlstra
2025-06-19  9:12             ` Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 06/14] unwind_user/deferred: Add deferred unwinding interface Steven Rostedt
2025-06-18 14:20   ` Peter Zijlstra
2025-06-18 15:37     ` Steven Rostedt
2025-06-18 15:38       ` Steven Rostedt
2025-06-19  8:01       ` Peter Zijlstra
2025-06-19  8:49         ` Steven Rostedt
2025-06-18 18:46   ` Peter Zijlstra
2025-06-18 19:09     ` Steven Rostedt
2025-06-18 19:36       ` Steven Rostedt
2025-06-19  7:50       ` Peter Zijlstra
2025-06-19  8:56         ` Steven Rostedt
2025-06-19  9:11           ` Peter Zijlstra
2025-06-24 14:03             ` Steven Rostedt
2025-06-24 22:36     ` Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 07/14] unwind_user/deferred: Make unwind deferral requests NMI-safe Steven Rostedt
2025-06-19  8:34   ` Peter Zijlstra
2025-06-19  8:37     ` Steven Rostedt
2025-06-19  8:44       ` Peter Zijlstra
2025-06-19  8:48         ` Peter Zijlstra
2025-06-19  9:10           ` Steven Rostedt
2025-06-19  9:24             ` Peter Zijlstra
2025-06-19  8:57   ` Peter Zijlstra
2025-06-19  9:07     ` Steven Rostedt
2025-06-19  9:32       ` Peter Zijlstra
2025-06-19  9:34         ` Peter Zijlstra
2025-06-19  9:42         ` Steven Rostedt
2025-06-19  9:45           ` Peter Zijlstra
2025-06-19 10:19             ` Steven Rostedt
2025-06-19 10:39               ` Peter Zijlstra
2025-06-19 13:04                 ` Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 08/14] unwind deferred: Use bitmask to determine which callbacks to call Steven Rostedt
2025-06-20  8:15   ` Peter Zijlstra
2025-06-24 14:55     ` Steven Rostedt
2025-06-24 15:00       ` Peter Zijlstra
2025-06-24 16:36         ` Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 09/14] unwind deferred: Use SRCU unwind_deferred_task_work() Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 10/14] unwind: Clear unwind_mask on exit back to user space Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 11/14] unwind: Finish up unwind when a task exits Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 12/14] unwind_user/x86: Enable frame pointer unwinding on x86 Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 13/14] perf/x86: Rename and move get_segment_base() and make it global Steven Rostedt
2025-06-11  0:54 ` [PATCH v10 14/14] unwind_user/x86: Enable compat mode frame pointer unwinding on x86 Steven Rostedt
2025-06-12 21:44 ` [PATCH v10 00/14] unwind_user: x86: Deferred unwinding infrastructure Andrii Nakryiko
2025-06-12 22:02   ` Josh Poimboeuf
2025-06-12 23:30     ` Andrii Nakryiko

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=20250611010428.092934995@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=akpm@linux-foundation.org \
    --cc=andrii@kernel.org \
    --cc=beaub@linux.microsoft.com \
    --cc=bpf@vger.kernel.org \
    --cc=indu.bhagat@oracle.com \
    --cc=jemarch@gnu.org \
    --cc=jolsa@kernel.org \
    --cc=jpoimboe@kernel.org \
    --cc=jremus@linux.ibm.com \
    --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=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.