From: Jens Remus <jremus@linux.ibm.com>
To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
x86@kernel.org, Steven Rostedt <rostedt@kernel.org>,
Josh Poimboeuf <jpoimboe@kernel.org>,
Indu Bhagat <ibhagatgnu@gmail.com>,
Peter Zijlstra <peterz@infradead.org>,
Dylan Hatch <dylanbhatch@google.com>,
Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
"H. Peter Anvin" <hpa@zytor.com>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Kees Cook <kees@kernel.org>, Sam James <sam@gentoo.org>
Cc: Jens Remus <jremus@linux.ibm.com>,
bpf@vger.kernel.org, linux-mm@kvack.org,
Namhyung Kim <namhyung@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
"Jose E. Marchesi" <jemarch@gnu.org>,
Beau Belgrave <beaub@linux.microsoft.com>,
Florian Weimer <fweimer@redhat.com>,
"Carlos O'Donell" <codonell@redhat.com>,
Masami Hiramatsu <mhiramat@kernel.org>,
Jiri Olsa <jolsa@kernel.org>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>,
"Liam R. Howlett" <liam@infradead.org>,
Vlastimil Babka <vbabka@kernel.org>,
Mike Rapoport <rppt@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Michal Hocko <mhocko@suse.com>,
Heiko Carstens <hca@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Ilya Leoshkevich <iii@linux.ibm.com>
Subject: [PATCH v15 18/20] unwind_user/sframe: Duplicate registered .sframe section data on clone/fork
Date: Wed, 20 May 2026 17:40:02 +0200 [thread overview]
Message-ID: <20260520154004.3845823-19-jremus@linux.ibm.com> (raw)
In-Reply-To: <20260520154004.3845823-1-jremus@linux.ibm.com>
When duplicating a process' virtual memory mappings also duplicate all
of its registered .sframe sections stored in the per-mm maple tree to
enable stacktracing using sframe of the child process.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---
include/linux/sframe.h | 5 ++++
kernel/unwind/sframe.c | 48 ++++++++++++++++++++++++++++++++++++
kernel/unwind/sframe_debug.h | 7 ++++++
mm/mmap.c | 9 +++++++
4 files changed, 69 insertions(+)
diff --git a/include/linux/sframe.h b/include/linux/sframe.h
index b79c5ec09229..91889b4fe3dd 100644
--- a/include/linux/sframe.h
+++ b/include/linux/sframe.h
@@ -28,6 +28,7 @@ struct sframe_section {
};
#define INIT_MM_SFRAME .sframe_mt = MTREE_INIT(sframe_mt, 0),
+extern int sframe_dup_mm(struct mm_struct *mm, struct mm_struct *oldmm);
extern void sframe_free_mm(struct mm_struct *mm);
extern int sframe_add_section(unsigned long sframe_start, unsigned long sframe_end,
@@ -45,6 +46,10 @@ static inline bool current_has_sframe(void)
#else /* !CONFIG_HAVE_UNWIND_USER_SFRAME */
#define INIT_MM_SFRAME
+static inline int sframe_dup_mm(struct mm_struct *mm, struct mm_struct *oldmm)
+{
+ return 0;
+}
static inline void sframe_free_mm(struct mm_struct *mm) {}
static inline int sframe_add_section(unsigned long sframe_start, unsigned long sframe_end,
unsigned long text_start, unsigned long text_end)
diff --git a/kernel/unwind/sframe.c b/kernel/unwind/sframe.c
index ec8318977a2e..0661090dd5bc 100644
--- a/kernel/unwind/sframe.c
+++ b/kernel/unwind/sframe.c
@@ -886,6 +886,54 @@ int sframe_remove_section(unsigned long sframe_start)
return 0;
}
+static void __sframe_dup_section(struct sframe_section *sec, struct sframe_section *oldsec)
+{
+ sec->sframe_start = oldsec->sframe_start;
+ sec->sframe_end = oldsec->sframe_end;
+ sec->text_start = oldsec->text_start;
+ sec->text_end = oldsec->text_end;
+
+ sec->fdes_start = oldsec->fdes_start;
+ sec->fres_start = oldsec->fres_start;
+ sec->fres_end = oldsec->fres_end;
+ sec->num_fdes = oldsec->num_fdes;
+
+ sec->ra_off = oldsec->ra_off;
+ sec->fp_off = oldsec->fp_off;
+
+ dbg_dup(sec, oldsec);
+}
+
+int sframe_dup_mm(struct mm_struct *mm, struct mm_struct *oldmm)
+{
+ struct sframe_section *sec, *oldsec;
+ unsigned long index = 0;
+ int ret;
+
+ guard(srcu)(&sframe_srcu);
+
+ mt_for_each(&oldmm->sframe_mt, oldsec, index, ULONG_MAX) {
+ sec = kzalloc(sizeof(*sec), GFP_KERNEL_ACCOUNT);
+ if (!sec)
+ return -ENOMEM;
+
+ __sframe_dup_section(sec, oldsec);
+
+ ret = mtree_insert_range(&mm->sframe_mt,
+ sec->text_start,
+ sec->text_end - 1,
+ sec, GFP_KERNEL_ACCOUNT);
+ if (ret)
+ goto err_free;
+ }
+
+ return 0;
+
+err_free:
+ free_section(sec);
+ return ret;
+}
+
void sframe_free_mm(struct mm_struct *mm)
{
struct sframe_section *sec;
diff --git a/kernel/unwind/sframe_debug.h b/kernel/unwind/sframe_debug.h
index a63e75cccc70..2503972155e8 100644
--- a/kernel/unwind/sframe_debug.h
+++ b/kernel/unwind/sframe_debug.h
@@ -48,6 +48,12 @@ static inline void dbg_init(struct sframe_section *sec)
sec->filename = kstrdup("(anonymous)", GFP_KERNEL_ACCOUNT);
}
+static inline void dbg_dup(struct sframe_section *sec, struct sframe_section *oldsec)
+{
+ if (oldsec->filename)
+ sec->filename = kstrdup(oldsec->filename, GFP_KERNEL_ACCOUNT);
+}
+
static inline void dbg_free(struct sframe_section *sec)
{
kfree(sec->filename);
@@ -61,6 +67,7 @@ static inline void dbg_free(struct sframe_section *sec)
static inline void dbg_print_header(struct sframe_section *sec) {}
static inline void dbg_init(struct sframe_section *sec) {}
+static inline void dbg_dup(struct sframe_section *sec, struct sframe_section *oldsec) {}
static inline void dbg_free(struct sframe_section *sec) {}
#endif /* !CONFIG_DYNAMIC_DEBUG */
diff --git a/mm/mmap.c b/mm/mmap.c
index 5754d1c36462..250e8bea73ef 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -48,6 +48,7 @@
#include <linux/sched/mm.h>
#include <linux/ksm.h>
#include <linux/memfd.h>
+#include <linux/sframe.h>
#include <linux/uaccess.h>
#include <asm/cacheflush.h>
@@ -1846,6 +1847,11 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
}
/* a new mm has just been created */
retval = arch_dup_mmap(oldmm, mm);
+#ifdef CONFIG_HAVE_UNWIND_USER_SFRAME
+ if (!retval) {
+ retval = sframe_dup_mm(mm, oldmm);
+ }
+#endif
loop_out:
vma_iter_free(&vmi);
if (!retval) {
@@ -1893,6 +1899,9 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
vm_unacct_memory(charge);
}
__mt_destroy(&mm->mm_mt);
+#ifdef CONFIG_HAVE_UNWIND_USER_SFRAME
+ sframe_free_mm(mm);
+#endif
/*
* The mm_struct is going to exit, but the locks will be dropped
* first. Set the mm_struct as unstable is advisable as it is
--
2.51.0
next prev parent reply other threads:[~2026-05-20 15:40 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-20 15:39 [PATCH v15 00/20] unwind_deferred: Implement sframe handling Jens Remus
2026-05-20 15:39 ` [PATCH v15 01/20] unwind_user: Add generic and arch-specific headers to MAINTAINERS Jens Remus
2026-05-20 15:39 ` [PATCH v15 02/20] unwind_user/sframe: Add support for reading .sframe headers Jens Remus
2026-05-20 15:39 ` [PATCH v15 03/20] unwind_user/sframe: Store .sframe section data in per-mm maple tree Jens Remus
2026-05-20 15:39 ` [PATCH v15 04/20] x86/uaccess: Add unsafe_copy_from_user() implementation Jens Remus
2026-05-20 15:39 ` [PATCH v15 05/20] unwind_user/sframe: Add support for reading .sframe contents Jens Remus
2026-05-20 15:39 ` [PATCH v15 06/20] unwind_user/sframe: Detect .sframe sections in executables Jens Remus
2026-05-20 15:39 ` [PATCH v15 07/20] unwind_user/sframe: Wire up unwind_user to sframe Jens Remus
2026-05-20 15:39 ` [PATCH v15 08/20] unwind_user: Stop when reaching an outermost frame Jens Remus
2026-05-20 15:39 ` [PATCH v15 09/20] unwind_user/sframe: Add support for outermost frame indication Jens Remus
2026-05-20 15:39 ` [PATCH v15 10/20] unwind_user/sframe: Remove .sframe section on detected corruption Jens Remus
2026-05-20 15:39 ` [PATCH v15 11/20] unwind_user/sframe: Show file name in debug output Jens Remus
2026-05-20 15:39 ` [PATCH v15 12/20] unwind_user/sframe: Add .sframe validation option Jens Remus
2026-05-20 15:39 ` [PATCH v15 13/20] unwind_user: Enable archs that pass RA in a register Jens Remus
2026-05-20 15:39 ` [PATCH v15 14/20] unwind_user: Flexible FP/RA recovery rules Jens Remus
2026-05-20 15:39 ` [PATCH v15 15/20] unwind_user: Flexible CFA " Jens Remus
2026-05-20 15:40 ` [PATCH v15 16/20] unwind_user/sframe: Add support for SFrame V3 flexible FDEs Jens Remus
2026-05-20 15:40 ` [PATCH v15 17/20] unwind_user/sframe: Separate reading of FRE from reading of FRE data words Jens Remus
2026-05-20 15:40 ` Jens Remus [this message]
2026-05-20 15:40 ` [PATCH v15 19/20] unwind_user/sframe/x86: Enable sframe unwinding on x86 Jens Remus
2026-05-20 15:40 ` [PATCH v15 20/20] unwind_user/sframe: Add prctl() interface for registering .sframe sections 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=20260520154004.3845823-19-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=bp@alien8.de \
--cc=bpf@vger.kernel.org \
--cc=codonell@redhat.com \
--cc=dave.hansen@linux.intel.com \
--cc=david@kernel.org \
--cc=dylanbhatch@google.com \
--cc=fweimer@redhat.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=hpa@zytor.com \
--cc=ibhagatgnu@gmail.com \
--cc=iii@linux.ibm.com \
--cc=jemarch@gnu.org \
--cc=jolsa@kernel.org \
--cc=jpoimboe@kernel.org \
--cc=kees@kernel.org \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mhiramat@kernel.org \
--cc=mhocko@suse.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=rostedt@kernel.org \
--cc=rppt@kernel.org \
--cc=sam@gentoo.org \
--cc=surenb@google.com \
--cc=tglx@kernel.org \
--cc=vbabka@kernel.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