Skip to contentSkip to conversation

x86: Enable the deferred unwinding infrastructure

PATCH Superseded Steven Rostedt 1 participant 3 messages Aug 20, 2025

Subsystems (4)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover x86: Enable the deferred unwinding infrastructure

This enables deferred unwinding for x86.

Josh Poimboeuf (1):
unwind_user/x86: Enable frame pointer unwinding on x86

Steven Rostedt (1):
unwind deferred/x86: Do not defer stack tracing for compat tasks

----

 arch/x86/Kconfig                   |  1 +
 arch/x86/include/asm/unwind_user.h | 22 ++++++++++++++++++++++
 include/linux/unwind_deferred.h    |  5 +++++
 kernel/unwind/deferred.c           |  3 +++
 4 files changed, 31 insertions(+)
 create mode 100644 arch/x86/include/asm/unwind_user.h
#1 lore raw

PATCH 1/2 unwind_user/x86: Enable frame pointer unwinding on x86

From: Josh Poimboeuf <[email protected]>

Use ARCH_INIT_USER_FP_FRAME to describe how frame pointers are unwound on x86, and enable CONFIG_HAVE_UNWIND_USER_FP accordingly so the unwind_user interfaces can be used.

---
 arch/x86/Kconfig                   |  1 +
 arch/x86/include/asm/unwind_user.h | 11 +++++++++++
 2 files changed, 12 insertions(+)
 create mode 100644 arch/x86/include/asm/unwind_user.h
arch/x86/Kconfig +1 -0
index 58d890fe2100..8f94c58d4de8 100644
@@ -299,6 +299,7 @@ config X86
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UACCESS_VALIDATION		if HAVE_OBJTOOL
 	select HAVE_UNSTABLE_SCHED_CLOCK
+	select HAVE_UNWIND_USER_FP		if X86_64
 	select HAVE_USER_RETURN_NOTIFIER
 	select HAVE_GENERIC_VDSO
 	select VDSO_GETRANDOM			if X86_64
arch/x86/include/asm/unwind_user.h new file +11 -0
new file mode 100644
index 000000000000..8597857bf896
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_UNWIND_USER_H
+#define _ASM_X86_UNWIND_USER_H
+
+#define ARCH_INIT_USER_FP_FRAME							\
+	.cfa_off	= (s32)sizeof(long) *  2,				\
+	.ra_off		= (s32)sizeof(long) * -1,				\
+	.fp_off		= (s32)sizeof(long) * -2,				\
+	.use_fp		= true,
+
+#endif /* _ASM_X86_UNWIND_USER_H */
Signature · 1 line
2.50.1
#2 lore raw

PATCH 2/2 unwind deferred/x86: Do not defer stack tracing for compat tasks

In reply to Steven Rostedt

From: Steven Rostedt <[email protected]>

Currently compat tasks are not supported. If a deferred user space stack trace is requested on a compat task, it should fail and return an error so that the profiler can use an alternative approach (whatever it uses today).

Add a arch_unwind_can_defer() macro that is called in unwind_deferred_request(). Have x86 define it to a function that makes sure that the current task is running in 64bit mode, and if it is not, it returns false. This will cause unwind_deferred_request() to error out and the caller can use the current method of user space stack tracing.

---
 arch/x86/include/asm/unwind_user.h | 11 +++++++++++
 include/linux/unwind_deferred.h    |  5 +++++
 kernel/unwind/deferred.c           |  3 +++
 3 files changed, 19 insertions(+)
arch/x86/include/asm/unwind_user.h +11 -0
index 8597857bf896..220fd0a6e175 100644
@@ -2,6 +2,17 @@
 #ifndef _ASM_X86_UNWIND_USER_H
 #define _ASM_X86_UNWIND_USER_H
 
+#ifdef CONFIG_IA32_EMULATION
+/* Currently compat mode is not supported for deferred stack trace */
+static inline bool arch_unwind_can_defer(void)
+{
+	struct pt_regs *regs = task_pt_regs(current);
+
+	return user_64bit_mode(regs);
+}
+# define arch_unwind_can_defer	arch_unwind_can_defer
+#endif /* CONFIG_IA32_EMULATION */
+
 #define ARCH_INIT_USER_FP_FRAME							\
 	.cfa_off	= (s32)sizeof(long) *  2,				\
 	.ra_off		= (s32)sizeof(long) * -1,				\
include/linux/unwind_deferred.h +5 -0
index 26122d00708a..0124865aaab4 100644
@@ -16,6 +16,11 @@ struct unwind_work {
 	int				bit;
 };
 
+/* Architectures can add a test to not defer unwinding */
+#ifndef arch_unwind_can_defer
+# define arch_unwind_can_defer()	(true)
+#endif
+
 #ifdef CONFIG_UNWIND_USER
 
 enum {
kernel/unwind/deferred.c +3 -0
index dc6040aae3ee..3601b2efe48d 100644
@@ -237,6 +237,9 @@ int unwind_deferred_request(struct unwind_work *work, u64 *cookie)
 
 	*cookie = 0;
 
+	if (!arch_unwind_can_defer())
+		return -EINVAL;
+
 	if ((current->flags & (PF_KTHREAD | PF_EXITING)) ||
 	    !user_mode(task_pt_regs(current)))
 		return -EINVAL;
Signature · 1 line
2.50.1