All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dylan Hatch <dylanbhatch@google.com>
To: Roman Gushchin <roman.gushchin@linux.dev>,
	Weinan Liu <wnliu@google.com>,  Will Deacon <will@kernel.org>,
	Josh Poimboeuf <jpoimboe@kernel.org>,
	 Indu Bhagat <indu.bhagat@oracle.com>,
	Peter Zijlstra <peterz@infradead.org>,
	 Steven Rostedt <rostedt@goodmis.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	 Jiri Kosina <jikos@kernel.org>
Cc: Dylan Hatch <dylanbhatch@google.com>,
	Mark Rutland <mark.rutland@arm.com>,
	 Prasanna Kumar T S M <ptsm@linux.microsoft.com>,
	Puranjay Mohan <puranjay@kernel.org>,  Song Liu <song@kernel.org>,
	joe.lawrence@redhat.com, linux-toolchains@vger.kernel.org,
	 linux-kernel@vger.kernel.org, live-patching@vger.kernel.org,
	 Jens Remus <jremus@linux.ibm.com>,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 5/8] sframe: Allow unsorted FDEs.
Date: Mon,  6 Apr 2026 18:49:57 +0000	[thread overview]
Message-ID: <20260406185000.1378082-6-dylanbhatch@google.com> (raw)
In-Reply-To: <20260406185000.1378082-1-dylanbhatch@google.com>

The .sframe in kernel modules is built without SFRAME_F_FDE_SORTED set.
In order to allow sframe PC lookup in modules, add a code path to handle
unsorted FDE tables by doing a simple linear search.

Signed-off-by: Dylan Hatch <dylanbhatch@google.com>
---
 include/linux/sframe.h |  1 +
 kernel/unwind/sframe.c | 44 +++++++++++++++++++++++++++++++++++++-----
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/include/linux/sframe.h b/include/linux/sframe.h
index 905775c3fde2..593b60715cd6 100644
--- a/include/linux/sframe.h
+++ b/include/linux/sframe.h
@@ -64,6 +64,7 @@ struct sframe_section {
 	unsigned long		text_start;
 	unsigned long		text_end;
 
+	bool			fdes_sorted;
 	unsigned long		fdes_start;
 	unsigned long		fres_start;
 	unsigned long		fres_end;
diff --git a/kernel/unwind/sframe.c b/kernel/unwind/sframe.c
index 321d0615aec7..4dd3612f9e7a 100644
--- a/kernel/unwind/sframe.c
+++ b/kernel/unwind/sframe.c
@@ -179,9 +179,34 @@ static __always_inline int __read_fde(struct sframe_section *sec,
 	return -EFAULT;
 }
 
-static __always_inline int __find_fde(struct sframe_section *sec,
-				      unsigned long ip,
-				      struct sframe_fde_internal *fde)
+static __always_inline int __find_fde_unsorted(struct sframe_section *sec,
+					       unsigned long ip,
+					       struct sframe_fde_internal *fde)
+{
+	struct sframe_fde_v3 *cur, *start, *end;
+
+	start = (struct sframe_fde_v3 *)sec->fdes_start;
+	end = start + sec->num_fdes;
+
+	for (cur = start; cur < end; cur++) {
+		s64 func_off;
+		u32 func_size;
+		unsigned long func_addr;
+
+		DATA_GET(sec, func_off, &cur->func_start_off, s64, Efault);
+		DATA_GET(sec, func_size, &cur->func_size, u32, Efault);
+		func_addr = (unsigned long)cur + func_off;
+
+		if (ip >= func_addr && ip < func_addr + func_size)
+			return __read_fde(sec, cur - start, fde);
+	}
+Efault:
+	return -EFAULT;
+}
+
+static __always_inline int __find_fde_sorted(struct sframe_section *sec,
+					     unsigned long ip,
+					     struct sframe_fde_internal *fde)
 {
 	unsigned long func_addr_low = 0, func_addr_high = ULONG_MAX;
 	struct sframe_fde_v3 *first, *low, *high, *found = NULL;
@@ -236,6 +261,15 @@ static __always_inline int __find_fde(struct sframe_section *sec,
 	return -EFAULT;
 }
 
+static __always_inline int __find_fde(struct sframe_section *sec,
+					     unsigned long ip,
+					     struct sframe_fde_internal *fde)
+{
+	if (sec->fdes_sorted)
+		return __find_fde_sorted(sec, ip, fde);
+	return __find_fde_unsorted(sec, ip, fde);
+}
+
 #define ____GET_INC(sec, to, from, type, label)				\
 ({									\
 	type __to;							\
@@ -660,7 +694,7 @@ static int sframe_validate_section(struct sframe_section *sec)
 			return ret;
 
 		ip = fde.func_addr;
-		if (ip <= prev_ip) {
+		if (sec->fdes_sorted && ip <= prev_ip) {
 			dbg_sec("fde %u not sorted\n", i);
 			return -EFAULT;
 		}
@@ -739,7 +773,6 @@ static int sframe_read_header(struct sframe_section *sec)
 
 	if (shdr.preamble.magic != SFRAME_MAGIC ||
 	    shdr.preamble.version != SFRAME_VERSION_3 ||
-	    !(shdr.preamble.flags & SFRAME_F_FDE_SORTED) ||
 	    !(shdr.preamble.flags & SFRAME_F_FDE_FUNC_START_PCREL) ||
 	    shdr.auxhdr_len) {
 		dbg_sec("bad/unsupported sframe header\n");
@@ -769,6 +802,7 @@ static int sframe_read_header(struct sframe_section *sec)
 		return -EINVAL;
 	}
 
+	sec->fdes_sorted	= shdr.preamble.flags & SFRAME_F_FDE_SORTED;
 	sec->num_fdes		= num_fdes;
 	sec->fdes_start		= fdes_start;
 	sec->fres_start		= fres_start;
-- 
2.53.0.1213.gd9a14994de-goog



  parent reply	other threads:[~2026-04-06 18:50 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-06 18:49 [PATCH v3 0/8] unwind, arm64: add sframe unwinder for kernel Dylan Hatch
2026-04-06 18:49 ` [PATCH v3 1/8] sframe: Allow kernelspace sframe sections Dylan Hatch
2026-04-14 12:09   ` Jens Remus
2026-04-06 18:49 ` [PATCH v3 2/8] arm64, unwind: build kernel with sframe V3 info Dylan Hatch
2026-04-06 21:36   ` Randy Dunlap
2026-04-14 12:43   ` Jens Remus
2026-04-18  0:20     ` Dylan Hatch
2026-04-20 12:16       ` Jens Remus
2026-04-20 12:44   ` Jens Remus
2026-04-06 18:49 ` [PATCH v3 3/8] arm64: entry: add unwind info for various kernel entries Dylan Hatch
2026-04-16 14:09   ` Jens Remus
2026-04-16 16:49   ` Jens Remus
2026-04-06 18:49 ` [PATCH v3 4/8] sframe: Provide PC lookup for vmlinux .sframe section Dylan Hatch
2026-04-16 15:10   ` Jens Remus
2026-04-06 18:49 ` Dylan Hatch [this message]
2026-04-16 14:57   ` [PATCH v3 5/8] sframe: Allow unsorted FDEs Jens Remus
2026-04-06 18:49 ` [PATCH v3 6/8] arm64/module, sframe: Add sframe support for modules Dylan Hatch
2026-04-17 14:07   ` Jens Remus
2026-04-20  9:54   ` Jens Remus
2026-04-06 18:49 ` [PATCH v3 7/8] sframe: Introduce in-kernel SFRAME_VALIDATION Dylan Hatch
2026-04-16 15:04   ` Jens Remus
2026-04-20  5:02     ` Dylan Hatch
2026-04-20 12:30       ` Jens Remus
2026-04-21  1:29         ` Dylan Hatch
2026-04-21  8:33           ` Jens Remus
2026-04-06 18:50 ` [PATCH v3 8/8] unwind: arm64: Use sframe to unwind interrupt frames Dylan Hatch
2026-04-17 15:45   ` Jens Remus
2026-04-20  5:56     ` Dylan Hatch
2026-04-20  8:42       ` Jens Remus
2026-04-14 16:10 ` [PATCH v3 0/8] unwind, arm64: add sframe unwinder for kernel 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=20260406185000.1378082-6-dylanbhatch@google.com \
    --to=dylanbhatch@google.com \
    --cc=catalin.marinas@arm.com \
    --cc=indu.bhagat@oracle.com \
    --cc=jikos@kernel.org \
    --cc=joe.lawrence@redhat.com \
    --cc=jpoimboe@kernel.org \
    --cc=jremus@linux.ibm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-toolchains@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=peterz@infradead.org \
    --cc=ptsm@linux.microsoft.com \
    --cc=puranjay@kernel.org \
    --cc=roman.gushchin@linux.dev \
    --cc=rostedt@goodmis.org \
    --cc=song@kernel.org \
    --cc=will@kernel.org \
    --cc=wnliu@google.com \
    /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.