--- /dev/null
+From stable+bounces-267216-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:18 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:30 -0400
+Subject: arm64: scripts/sorttable: Implement sorting mcount_loc at boot for arm64
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <bf4bcdb583a211d91e2e566510551b8dab733ea5.1781809956.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit b3d09d06e052e1d754645acea4e4d1e96f81c934 ]
+
+The mcount_loc section holds the addresses of the functions that get
+patched by ftrace when enabling function callbacks. It can contain tens of
+thousands of entries. These addresses must be sorted. If they are not
+sorted at compile time, they are sorted at boot. Sorting at boot does take
+some time and does have a small impact on boot performance.
+
+x86 and arm32 have the addresses in the mcount_loc section of the ELF
+file. But for arm64, the section just contains zeros. The .rela.dyn
+Elf_Rela section holds the addresses and they get patched at boot during
+the relocation phase.
+
+In order to sort these addresses, the Elf_Rela needs to be updated instead
+of the location in the binary that holds the mcount_loc section. Have the
+sorttable code, allocate an array to hold the functions, load the
+addresses from the Elf_Rela entries, sort them, then put them back in
+order into the Elf_rela entries so that they will be sorted at boot up
+without having to sort them during boot up.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Alexander Gordeev <agordeev@linux.ibm.com>
+Link: https://lore.kernel.org/20250218200022.373319428@goodmis.org
+Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/Kconfig | 1
+ scripts/sorttable.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 183 insertions(+), 3 deletions(-)
+
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -212,6 +212,7 @@ config ARM64
+ if DYNAMIC_FTRACE_WITH_ARGS
+ select HAVE_SAMPLE_FTRACE_DIRECT
+ select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
++ select HAVE_BUILDTIME_MCOUNT_SORT
+ select HAVE_EFFICIENT_UNALIGNED_ACCESS
+ select HAVE_GUP_FAST
+ select HAVE_FTRACE_MCOUNT_RECORD
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -28,6 +28,7 @@
+ #include <fcntl.h>
+ #include <stdio.h>
+ #include <stdlib.h>
++#include <stdbool.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <errno.h>
+@@ -79,10 +80,16 @@ typedef union {
+ Elf64_Sym e64;
+ } Elf_Sym;
+
++typedef union {
++ Elf32_Rela e32;
++ Elf64_Rela e64;
++} Elf_Rela;
++
+ static uint32_t (*r)(const uint32_t *);
+ static uint16_t (*r2)(const uint16_t *);
+ static uint64_t (*r8)(const uint64_t *);
+ static void (*w)(uint32_t, uint32_t *);
++static void (*w8)(uint64_t, uint64_t *);
+ typedef void (*table_sort_t)(char *, int);
+
+ static struct elf_funcs {
+@@ -102,6 +109,10 @@ static struct elf_funcs {
+ uint32_t (*sym_name)(Elf_Sym *sym);
+ uint64_t (*sym_value)(Elf_Sym *sym);
+ uint16_t (*sym_shndx)(Elf_Sym *sym);
++ uint64_t (*rela_offset)(Elf_Rela *rela);
++ uint64_t (*rela_info)(Elf_Rela *rela);
++ uint64_t (*rela_addend)(Elf_Rela *rela);
++ void (*rela_write_addend)(Elf_Rela *rela, uint64_t val);
+ } e;
+
+ static uint64_t ehdr64_shoff(Elf_Ehdr *ehdr)
+@@ -262,6 +273,38 @@ SYM_ADDR(value)
+ SYM_WORD(name)
+ SYM_HALF(shndx)
+
++#define __maybe_unused __attribute__((__unused__))
++
++#define RELA_ADDR(fn_name) \
++static uint64_t rela64_##fn_name(Elf_Rela *rela) \
++{ \
++ return r8((uint64_t *)&rela->e64.r_##fn_name); \
++} \
++ \
++static uint64_t rela32_##fn_name(Elf_Rela *rela) \
++{ \
++ return r((uint32_t *)&rela->e32.r_##fn_name); \
++} \
++ \
++static uint64_t __maybe_unused rela_##fn_name(Elf_Rela *rela) \
++{ \
++ return e.rela_##fn_name(rela); \
++}
++
++RELA_ADDR(offset)
++RELA_ADDR(info)
++RELA_ADDR(addend)
++
++static void rela64_write_addend(Elf_Rela *rela, uint64_t val)
++{
++ w8(val, (uint64_t *)&rela->e64.r_addend);
++}
++
++static void rela32_write_addend(Elf_Rela *rela, uint64_t val)
++{
++ w(val, (uint32_t *)&rela->e32.r_addend);
++}
++
+ /*
+ * Get the whole file as a programming convenience in order to avoid
+ * malloc+lseek+read+free of many pieces. If successful, then mmap
+@@ -341,6 +384,16 @@ static void wle(uint32_t val, uint32_t *
+ put_unaligned_le32(val, x);
+ }
+
++static void w8be(uint64_t val, uint64_t *x)
++{
++ put_unaligned_be64(val, x);
++}
++
++static void w8le(uint64_t val, uint64_t *x)
++{
++ put_unaligned_le64(val, x);
++}
++
+ /*
+ * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
+ * the way to -256..-1, to avoid conflicting with real section
+@@ -398,13 +451,12 @@ static inline void *get_index(void *star
+ static int extable_ent_size;
+ static int long_size;
+
++#define ERRSTR_MAXSZ 256
+
+ #ifdef UNWINDER_ORC_ENABLED
+ /* ORC unwinder only support X86_64 */
+ #include <asm/orc_types.h>
+
+-#define ERRSTR_MAXSZ 256
+-
+ static char g_err[ERRSTR_MAXSZ];
+ static int *g_orc_ip_table;
+ static struct orc_entry *g_orc_table;
+@@ -499,7 +551,19 @@ static void *sort_orctable(void *arg)
+ #endif
+
+ #ifdef MCOUNT_SORT_ENABLED
++
++/* Only used for sorting mcount table */
++static void rela_write_addend(Elf_Rela *rela, uint64_t val)
++{
++ e.rela_write_addend(rela, val);
++}
++
+ static pthread_t mcount_sort_thread;
++static bool sort_reloc;
++
++static long rela_type;
++
++static char m_err[ERRSTR_MAXSZ];
+
+ struct elf_mcount_loc {
+ Elf_Ehdr *ehdr;
+@@ -508,6 +572,103 @@ struct elf_mcount_loc {
+ uint64_t stop_mcount_loc;
+ };
+
++/* Sort the relocations not the address itself */
++static void *sort_relocs(Elf_Ehdr *ehdr, uint64_t start_loc, uint64_t size)
++{
++ Elf_Shdr *shdr_start;
++ Elf_Rela *rel;
++ unsigned int shnum;
++ unsigned int count;
++ int shentsize;
++ void *vals;
++ void *ptr;
++
++ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
++ shentsize = ehdr_shentsize(ehdr);
++
++ vals = malloc(long_size * size);
++ if (!vals) {
++ snprintf(m_err, ERRSTR_MAXSZ, "Failed to allocate sort array");
++ pthread_exit(m_err);
++ return NULL;
++ }
++
++ ptr = vals;
++
++ shnum = ehdr_shnum(ehdr);
++ if (shnum == SHN_UNDEF)
++ shnum = shdr_size(shdr_start);
++
++ for (int i = 0; i < shnum; i++) {
++ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
++ void *end;
++
++ if (shdr_type(shdr) != SHT_RELA)
++ continue;
++
++ rel = (void *)ehdr + shdr_offset(shdr);
++ end = (void *)rel + shdr_size(shdr);
++
++ for (; (void *)rel < end; rel = (void *)rel + shdr_entsize(shdr)) {
++ uint64_t offset = rela_offset(rel);
++
++ if (offset >= start_loc && offset < start_loc + size) {
++ if (ptr + long_size > vals + size) {
++ free(vals);
++ snprintf(m_err, ERRSTR_MAXSZ,
++ "Too many relocations");
++ pthread_exit(m_err);
++ return NULL;
++ }
++
++ /* Make sure this has the correct type */
++ if (rela_info(rel) != rela_type) {
++ free(vals);
++ snprintf(m_err, ERRSTR_MAXSZ,
++ "rela has type %lx but expected %lx\n",
++ (long)rela_info(rel), rela_type);
++ pthread_exit(m_err);
++ return NULL;
++ }
++
++ if (long_size == 4)
++ *(uint32_t *)ptr = rela_addend(rel);
++ else
++ *(uint64_t *)ptr = rela_addend(rel);
++ ptr += long_size;
++ }
++ }
++ }
++ count = ptr - vals;
++ qsort(vals, count / long_size, long_size, compare_extable);
++
++ ptr = vals;
++ for (int i = 0; i < shnum; i++) {
++ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
++ void *end;
++
++ if (shdr_type(shdr) != SHT_RELA)
++ continue;
++
++ rel = (void *)ehdr + shdr_offset(shdr);
++ end = (void *)rel + shdr_size(shdr);
++
++ for (; (void *)rel < end; rel = (void *)rel + shdr_entsize(shdr)) {
++ uint64_t offset = rela_offset(rel);
++
++ if (offset >= start_loc && offset < start_loc + size) {
++ if (long_size == 4)
++ rela_write_addend(rel, *(uint32_t *)ptr);
++ else
++ rela_write_addend(rel, *(uint64_t *)ptr);
++ ptr += long_size;
++ }
++ }
++ }
++ free(vals);
++ return NULL;
++}
++
+ /* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
+ static void *sort_mcount_loc(void *arg)
+ {
+@@ -517,6 +678,9 @@ static void *sort_mcount_loc(void *arg)
+ uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
+ unsigned char *start_loc = (void *)emloc->ehdr + offset;
+
++ if (sort_reloc)
++ return sort_relocs(emloc->ehdr, emloc->start_mcount_loc, count);
++
+ qsort(start_loc, count/long_size, long_size, compare_extable);
+ return NULL;
+ }
+@@ -866,12 +1030,14 @@ static int do_file(char const *const fna
+ r2 = r2le;
+ r8 = r8le;
+ w = wle;
++ w8 = w8le;
+ break;
+ case ELFDATA2MSB:
+ r = rbe;
+ r2 = r2be;
+ r8 = r8be;
+ w = wbe;
++ w8 = w8be;
+ break;
+ default:
+ fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
+@@ -887,8 +1053,13 @@ static int do_file(char const *const fna
+ }
+
+ switch (r2(&ehdr->e32.e_machine)) {
+- case EM_386:
+ case EM_AARCH64:
++#ifdef MCOUNT_SORT_ENABLED
++ sort_reloc = true;
++ rela_type = 0x403;
++#endif
++ /* fallthrough */
++ case EM_386:
+ case EM_LOONGARCH:
+ case EM_RISCV:
+ case EM_S390:
+@@ -932,6 +1103,10 @@ static int do_file(char const *const fna
+ .sym_name = sym32_name,
+ .sym_value = sym32_value,
+ .sym_shndx = sym32_shndx,
++ .rela_offset = rela32_offset,
++ .rela_info = rela32_info,
++ .rela_addend = rela32_addend,
++ .rela_write_addend = rela32_write_addend,
+ };
+
+ e = efuncs;
+@@ -965,6 +1140,10 @@ static int do_file(char const *const fna
+ .sym_name = sym64_name,
+ .sym_value = sym64_value,
+ .sym_shndx = sym64_shndx,
++ .rela_offset = rela64_offset,
++ .rela_info = rela64_info,
++ .rela_addend = rela64_addend,
++ .rela_write_addend = rela64_write_addend,
+ };
+
+ e = efuncs;
--- /dev/null
+From stable+bounces-267224-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:33 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:38 -0400
+Subject: ftrace: Check against is_kernel_text() instead of kaslr_offset()
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <0fb5f2bc351b85c4658cb247b9dc2f79b927d5ad.1781809982.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit da0f622b344be769ed61e7c1caf95cd0cdb47964 ]
+
+As kaslr_offset() is architecture dependent and also may not be defined by
+all architectures, when zeroing out unused weak functions, do not check
+against kaslr_offset(), but instead check if the address is within the
+kernel text sections. If KASLR added a shift to the zeroed out function,
+it would still not be located in the kernel text. This is a more robust
+way to test if the text is valid or not.
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: "Arnd Bergmann" <arnd@arndb.de>
+Link: https://lore.kernel.org/20250225182054.471759017@goodmis.org
+Fixes: ef378c3b8233 ("scripts/sorttable: Zero out weak functions in mcount_loc table")
+Reported-by: Nathan Chancellor <nathan@kernel.org>
+Reported-by: Mark Brown <broonie@kernel.org>
+Tested-by: Nathan Chancellor <nathan@kernel.org>
+Closes: https://lore.kernel.org/all/20250224180805.GA1536711@ax162/
+Closes: https://lore.kernel.org/all/5225b07b-a9b2-4558-9d5f-aa60b19f6317@sirena.org.uk/
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/ftrace.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -7051,7 +7051,6 @@ static int ftrace_process_locs(struct mo
+ unsigned long count;
+ unsigned long *p;
+ unsigned long addr;
+- unsigned long kaslr;
+ unsigned long flags = 0; /* Shut up gcc */
+ unsigned long pages;
+ int ret = -ENOMEM;
+@@ -7101,9 +7100,6 @@ static int ftrace_process_locs(struct mo
+ ftrace_pages->next = start_pg;
+ }
+
+- /* For zeroed locations that were shifted for core kernel */
+- kaslr = !mod ? kaslr_offset() : 0;
+-
+ p = start;
+ pg = start_pg;
+ while (p < end) {
+@@ -7117,7 +7113,18 @@ static int ftrace_process_locs(struct mo
+ * object files to satisfy alignments.
+ * Skip any NULL pointers.
+ */
+- if (!addr || addr == kaslr) {
++ if (!addr) {
++ skipped++;
++ continue;
++ }
++
++ /*
++ * If this is core kernel, make sure the address is in core
++ * or inittext, as weak functions get zeroed and KASLR can
++ * move them to something other than zero. It just will not
++ * move it to an area where kernel text is.
++ */
++ if (!mod && !(is_kernel_text(addr) || is_kernel_inittext(addr))) {
+ skipped++;
+ continue;
+ }
--- /dev/null
+From stable+bounces-267222-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:31 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:36 -0400
+Subject: ftrace: Do not over-allocate ftrace memory
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <5b5d88723e570c56841c83c78147d9badd595e1d.1781809976.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit be55257fab181b93af38f8c4b1b3cb453a78d742 ]
+
+The pg_remaining calculation in ftrace_process_locs() assumes that
+ENTRIES_PER_PAGE multiplied by 2^order equals the actual capacity of the
+allocated page group. However, ENTRIES_PER_PAGE is PAGE_SIZE / ENTRY_SIZE
+(integer division). When PAGE_SIZE is not a multiple of ENTRY_SIZE (e.g.
+4096 / 24 = 170 with remainder 16), high-order allocations (like 256 pages)
+have significantly more capacity than 256 * 170. This leads to pg_remaining
+being underestimated, which in turn makes skip (derived from skipped -
+pg_remaining) larger than expected, causing the WARN(skip != remaining)
+to trigger.
+
+Extra allocated pages for ftrace: 2 with 654 skipped
+WARNING: CPU: 0 PID: 0 at kernel/trace/ftrace.c:7295 ftrace_process_locs+0x5bf/0x5e0
+
+A similar problem in ftrace_allocate_records() can result in allocating
+too many pages. This can trigger the second warning in
+ftrace_process_locs().
+
+Extra allocated pages for ftrace
+WARNING: CPU: 0 PID: 0 at kernel/trace/ftrace.c:7276 ftrace_process_locs+0x548/0x580
+
+Use the actual capacity of a page group to determine the number of pages
+to allocate. Have ftrace_allocate_pages() return the number of allocated
+pages to avoid having to calculate it. Use the actual page group capacity
+when validating the number of unused pages due to skipped entries.
+Drop the definition of ENTRIES_PER_PAGE since it is no longer used.
+
+Cc: stable@vger.kernel.org
+Fixes: 4a3efc6baff93 ("ftrace: Update the mcount_loc check of skipped entries")
+Link: https://patch.msgid.link/20260113152243.3557219-1-linux@roeck-us.net
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/ftrace.c | 29 +++++++++++++++--------------
+ 1 file changed, 15 insertions(+), 14 deletions(-)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -1122,7 +1122,6 @@ struct ftrace_page {
+ };
+
+ #define ENTRY_SIZE sizeof(struct dyn_ftrace)
+-#define ENTRIES_PER_PAGE (PAGE_SIZE / ENTRY_SIZE)
+
+ static struct ftrace_page *ftrace_pages_start;
+ static struct ftrace_page *ftrace_pages;
+@@ -3754,7 +3753,8 @@ static int ftrace_update_code(struct mod
+ return 0;
+ }
+
+-static int ftrace_allocate_records(struct ftrace_page *pg, int count)
++static int ftrace_allocate_records(struct ftrace_page *pg, int count,
++ unsigned long *num_pages)
+ {
+ int order;
+ int pages;
+@@ -3764,7 +3764,7 @@ static int ftrace_allocate_records(struc
+ return -EINVAL;
+
+ /* We want to fill as much as possible, with no empty pages */
+- pages = DIV_ROUND_UP(count, ENTRIES_PER_PAGE);
++ pages = DIV_ROUND_UP(count * ENTRY_SIZE, PAGE_SIZE);
+ order = fls(pages) - 1;
+
+ again:
+@@ -3779,6 +3779,7 @@ static int ftrace_allocate_records(struc
+ }
+
+ ftrace_number_of_pages += 1 << order;
++ *num_pages += 1 << order;
+ ftrace_number_of_groups++;
+
+ cnt = (PAGE_SIZE << order) / ENTRY_SIZE;
+@@ -3807,12 +3808,14 @@ static void ftrace_free_pages(struct ftr
+ }
+
+ static struct ftrace_page *
+-ftrace_allocate_pages(unsigned long num_to_init)
++ftrace_allocate_pages(unsigned long num_to_init, unsigned long *num_pages)
+ {
+ struct ftrace_page *start_pg;
+ struct ftrace_page *pg;
+ int cnt;
+
++ *num_pages = 0;
++
+ if (!num_to_init)
+ return NULL;
+
+@@ -3826,7 +3829,7 @@ ftrace_allocate_pages(unsigned long num_
+ * waste as little space as possible.
+ */
+ for (;;) {
+- cnt = ftrace_allocate_records(pg, num_to_init);
++ cnt = ftrace_allocate_records(pg, num_to_init, num_pages);
+ if (cnt < 0)
+ goto free_pages;
+
+@@ -7058,8 +7061,6 @@ static int ftrace_process_locs(struct mo
+ if (!count)
+ return 0;
+
+- pages = DIV_ROUND_UP(count, ENTRIES_PER_PAGE);
+-
+ /*
+ * Sorting mcount in vmlinux at build time depend on
+ * CONFIG_BUILDTIME_MCOUNT_SORT, while mcount loc in
+@@ -7072,7 +7073,7 @@ static int ftrace_process_locs(struct mo
+ test_is_sorted(start, count);
+ }
+
+- start_pg = ftrace_allocate_pages(count);
++ start_pg = ftrace_allocate_pages(count, &pages);
+ if (!start_pg)
+ return -ENOMEM;
+
+@@ -7159,27 +7160,27 @@ static int ftrace_process_locs(struct mo
+ /* We should have used all pages unless we skipped some */
+ if (pg_unuse) {
+ unsigned long pg_remaining, remaining = 0;
+- unsigned long skip;
++ long skip;
+
+ /* Count the number of entries unused and compare it to skipped. */
+- pg_remaining = (ENTRIES_PER_PAGE << pg->order) - pg->index;
++ pg_remaining = (PAGE_SIZE << pg->order) / ENTRY_SIZE - pg->index;
+
+ if (!WARN(skipped < pg_remaining, "Extra allocated pages for ftrace")) {
+
+ skip = skipped - pg_remaining;
+
+- for (pg = pg_unuse; pg; pg = pg->next)
++ for (pg = pg_unuse; pg && skip > 0; pg = pg->next) {
+ remaining += 1 << pg->order;
++ skip -= (PAGE_SIZE << pg->order) / ENTRY_SIZE;
++ }
+
+ pages -= remaining;
+
+- skip = DIV_ROUND_UP(skip, ENTRIES_PER_PAGE);
+-
+ /*
+ * Check to see if the number of pages remaining would
+ * just fit the number of entries skipped.
+ */
+- WARN(skip != remaining, "Extra allocated pages for ftrace: %lu with %lu skipped",
++ WARN(pg || skip > 0, "Extra allocated pages for ftrace: %lu with %lu skipped",
+ remaining, skipped);
+ }
+ /* Need to synchronize with ftrace_location_range() */
--- /dev/null
+From stable+bounces-267220-greg=kroah.com@vger.kernel.org Thu Jun 18 21:17:07 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:35 -0400
+Subject: ftrace: Have ftrace pages output reflect freed pages
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <5773e8c00a533a29c89b42522a16f2742b97c3af.1781809974.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 264143c4e54412095f4b615e65bf736fc3c60af0 ]
+
+The amount of memory that ftrace uses to save the descriptors to manage
+the functions it can trace is shown at output. But if there are a lot of
+functions that are skipped because they were weak or the architecture
+added holes into the tables, then the extra pages that were allocated are
+freed. But these freed pages are not reflected in the numbers shown, and
+they can even be inconsistent with what is reported:
+
+ ftrace: allocating 57482 entries in 225 pages
+ ftrace: allocated 224 pages with 3 groups
+
+The above shows the number of original entries that are in the mcount_loc
+section and the pages needed to save them (225), but the second output
+reflects the number of pages that were actually used. The two should be
+consistent as:
+
+ ftrace: allocating 56739 entries in 224 pages
+ ftrace: allocated 224 pages with 3 groups
+
+The above also shows the accurate number of entires that were actually
+stored and does not include the entries that were removed.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Alexander Gordeev <agordeev@linux.ibm.com>
+Link: https://lore.kernel.org/20250218200023.221100846@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/ftrace.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -7050,6 +7050,7 @@ static int ftrace_process_locs(struct mo
+ unsigned long addr;
+ unsigned long kaslr;
+ unsigned long flags = 0; /* Shut up gcc */
++ unsigned long pages;
+ int ret = -ENOMEM;
+
+ count = end - start;
+@@ -7057,6 +7058,8 @@ static int ftrace_process_locs(struct mo
+ if (!count)
+ return 0;
+
++ pages = DIV_ROUND_UP(count, ENTRIES_PER_PAGE);
++
+ /*
+ * Sorting mcount in vmlinux at build time depend on
+ * CONFIG_BUILDTIME_MCOUNT_SORT, while mcount loc in
+@@ -7168,6 +7171,8 @@ static int ftrace_process_locs(struct mo
+ for (pg = pg_unuse; pg; pg = pg->next)
+ remaining += 1 << pg->order;
+
++ pages -= remaining;
++
+ skip = DIV_ROUND_UP(skip, ENTRIES_PER_PAGE);
+
+ /*
+@@ -7181,6 +7186,13 @@ static int ftrace_process_locs(struct mo
+ synchronize_rcu();
+ ftrace_free_pages(pg_unuse);
+ }
++
++ if (!mod) {
++ count -= skipped;
++ pr_info("ftrace: allocating %ld entries in %ld pages\n",
++ count, pages);
++ }
++
+ return ret;
+ }
+
+@@ -7835,9 +7847,6 @@ void __init ftrace_init(void)
+ goto failed;
+ }
+
+- pr_info("ftrace: allocating %ld entries in %ld pages\n",
+- count, DIV_ROUND_UP(count, ENTRIES_PER_PAGE));
+-
+ ret = ftrace_process_locs(NULL,
+ __start_mcount_loc,
+ __stop_mcount_loc);
--- /dev/null
+From stable+bounces-267223-greg=kroah.com@vger.kernel.org Thu Jun 18 21:17:30 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:37 -0400
+Subject: ftrace: Test mcount_loc addr before calling ftrace_call_addr()
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <0e6f0c263a1c1b93f1fa6ae5310225e1e7300cde.1781809979.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 6eeca746fa5f1dd03c6ee05cb03f5eb1ddda1c81 ]
+
+The addresses in the mcount_loc can be zeroed and then moved by KASLR
+making them invalid addresses. ftrace_call_addr() for ARM 64 expects a
+valid address to kernel text. If the addr read from the mcount_loc section
+is invalid, it must not call ftrace_call_addr(). Move the addr check
+before calling ftrace_call_addr() in ftrace_process_locs().
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/20250225182054.290128736@goodmis.org
+Fixes: ef378c3b8233 ("scripts/sorttable: Zero out weak functions in mcount_loc table")
+Reported-by: Nathan Chancellor <nathan@kernel.org>
+Reported-by: "Arnd Bergmann" <arnd@arndb.de>
+Tested-by: Nathan Chancellor <nathan@kernel.org>
+Closes: https://lore.kernel.org/all/20250225025631.GA271248@ax162/
+Closes: https://lore.kernel.org/all/91523154-072b-437b-bbdc-0b70e9783fd0@app.fastmail.com/
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/ftrace.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -7108,7 +7108,9 @@ static int ftrace_process_locs(struct mo
+ pg = start_pg;
+ while (p < end) {
+ unsigned long end_offset;
+- addr = ftrace_call_adjust(*p++);
++
++ addr = *p++;
++
+ /*
+ * Some architecture linkers will pad between
+ * the different mcount_loc sections of different
+@@ -7120,6 +7122,8 @@ static int ftrace_process_locs(struct mo
+ continue;
+ }
+
++ addr = ftrace_call_adjust(addr);
++
+ end_offset = (pg->index+1) * sizeof(pg->records[0]);
+ if (end_offset > PAGE_SIZE << pg->order) {
+ /* We should have allocated enough */
--- /dev/null
+From stable+bounces-267221-greg=kroah.com@vger.kernel.org Thu Jun 18 21:17:10 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:34 -0400
+Subject: ftrace: Update the mcount_loc check of skipped entries
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <60ec429dd94faa00507cc8f10127ee80a89bd2d9.1781809971.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 4a3efc6baff931da9a85c6d2e42c87bd9a827399 ]
+
+Now that weak functions turn into skipped entries, update the check to
+make sure the amount that was allocated would fit both the entries that
+were allocated as well as those that were skipped.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Alexander Gordeev <agordeev@linux.ibm.com>
+Link: https://lore.kernel.org/20250218200023.055162048@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/ftrace.c | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -7155,7 +7155,28 @@ static int ftrace_process_locs(struct mo
+
+ /* We should have used all pages unless we skipped some */
+ if (pg_unuse) {
+- WARN_ON(!skipped);
++ unsigned long pg_remaining, remaining = 0;
++ unsigned long skip;
++
++ /* Count the number of entries unused and compare it to skipped. */
++ pg_remaining = (ENTRIES_PER_PAGE << pg->order) - pg->index;
++
++ if (!WARN(skipped < pg_remaining, "Extra allocated pages for ftrace")) {
++
++ skip = skipped - pg_remaining;
++
++ for (pg = pg_unuse; pg; pg = pg->next)
++ remaining += 1 << pg->order;
++
++ skip = DIV_ROUND_UP(skip, ENTRIES_PER_PAGE);
++
++ /*
++ * Check to see if the number of pages remaining would
++ * just fit the number of entries skipped.
++ */
++ WARN(skip != remaining, "Extra allocated pages for ftrace: %lu with %lu skipped",
++ remaining, skipped);
++ }
+ /* Need to synchronize with ftrace_location_range() */
+ synchronize_rcu();
+ ftrace_free_pages(pg_unuse);
--- /dev/null
+From stable+bounces-268302-greg=kroah.com@vger.kernel.org Thu Jun 25 09:28:55 2026
+From: Alexander Martyniuk <alexevgmart@gmail.com>
+Date: Thu, 25 Jun 2026 11:24:41 +0300
+Subject: net: ipv6: Make udp_tunnel6_xmit_skb() void
+To: stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Alexander Martyniuk <alexevgmart@gmail.com>, "David S. Miller" <davem@davemloft.net>, Eric Dumazet <edumazet@google.com>, Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>, David Ahern <dsahern@kernel.org>, Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>, Xin Long <lucien.xin@gmail.com>, Jon Maloy <jmaloy@redhat.com>, Ying Xue <ying.xue@windriver.com>, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sctp@vger.kernel.org, tipc-discussion@lists.sourceforge.net, Petr Machata <petrm@nvidia.com>, Ido Schimmel <idosch@nvidia.com>, Nikolay Aleksandrov <razor@blackwall.org>
+Message-ID: <20260625082442.96390-2-alexevgmart@gmail.com>
+
+From: Petr Machata <petrm@nvidia.com>
+
+commit 6a7d88ca15f73c5c570c372238f71d63da1fda55 upstream.
+
+The function always returns zero, thus the return value does not carry any
+signal. Just make it void.
+
+Most callers already ignore the return value. However:
+
+- Refold arguments of the call from sctp_v6_xmit() so that they fit into
+ the 80-column limit.
+
+- tipc_udp_xmit() initializes err from the return value, but that should
+ already be always zero at that point. So there's no practical change, but
+ elision of the assignment prompts a couple more tweaks to clean up the
+ function.
+
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Link: https://patch.msgid.link/7facacf9d8ca3ca9391a4aee88160913671b868d.1750113335.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Alexander Martyniuk <alexevgmart@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/udp_tunnel.h | 14 +++++++-------
+ net/ipv6/ip6_udp_tunnel.c | 15 +++++++--------
+ net/sctp/ipv6.c | 7 ++++---
+ net/tipc/udp_media.c | 10 +++++-----
+ 4 files changed, 23 insertions(+), 23 deletions(-)
+
+--- a/include/net/udp_tunnel.h
++++ b/include/net/udp_tunnel.h
+@@ -152,13 +152,13 @@ void udp_tunnel_xmit_skb(struct rtable *
+ __be16 df, __be16 src_port, __be16 dst_port,
+ bool xnet, bool nocheck);
+
+-int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
+- struct sk_buff *skb,
+- struct net_device *dev,
+- const struct in6_addr *saddr,
+- const struct in6_addr *daddr,
+- __u8 prio, __u8 ttl, __be32 label,
+- __be16 src_port, __be16 dst_port, bool nocheck);
++void udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
++ struct sk_buff *skb,
++ struct net_device *dev,
++ const struct in6_addr *saddr,
++ const struct in6_addr *daddr,
++ __u8 prio, __u8 ttl, __be32 label,
++ __be16 src_port, __be16 dst_port, bool nocheck);
+
+ void udp_tunnel_sock_release(struct socket *sock);
+
+--- a/net/ipv6/ip6_udp_tunnel.c
++++ b/net/ipv6/ip6_udp_tunnel.c
+@@ -74,13 +74,13 @@ error:
+ }
+ EXPORT_SYMBOL_GPL(udp_sock_create6);
+
+-int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
+- struct sk_buff *skb,
+- struct net_device *dev,
+- const struct in6_addr *saddr,
+- const struct in6_addr *daddr,
+- __u8 prio, __u8 ttl, __be32 label,
+- __be16 src_port, __be16 dst_port, bool nocheck)
++void udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
++ struct sk_buff *skb,
++ struct net_device *dev,
++ const struct in6_addr *saddr,
++ const struct in6_addr *daddr,
++ __u8 prio, __u8 ttl, __be32 label,
++ __be16 src_port, __be16 dst_port, bool nocheck)
+ {
+ struct udphdr *uh;
+ struct ipv6hdr *ip6h;
+@@ -109,7 +109,6 @@ int udp_tunnel6_xmit_skb(struct dst_entr
+ ip6h->saddr = *saddr;
+
+ ip6tunnel_xmit(sk, skb, dev);
+- return 0;
+ }
+ EXPORT_SYMBOL_GPL(udp_tunnel6_xmit_skb);
+
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -261,9 +261,10 @@ static int sctp_v6_xmit(struct sk_buff *
+ skb_set_inner_ipproto(skb, IPPROTO_SCTP);
+ label = ip6_make_flowlabel(sock_net(sk), skb, fl6->flowlabel, true, fl6);
+
+- return udp_tunnel6_xmit_skb(dst, sk, skb, NULL, &fl6->saddr,
+- &fl6->daddr, tclass, ip6_dst_hoplimit(dst),
+- label, sctp_sk(sk)->udp_port, t->encap_port, false);
++ udp_tunnel6_xmit_skb(dst, sk, skb, NULL, &fl6->saddr, &fl6->daddr,
++ tclass, ip6_dst_hoplimit(dst), label,
++ sctp_sk(sk)->udp_port, t->encap_port, false);
++ return 0;
+ }
+
+ /* Returns the dst cache entry for the given source and destination ip
+--- a/net/tipc/udp_media.c
++++ b/net/tipc/udp_media.c
+@@ -172,7 +172,7 @@ static int tipc_udp_xmit(struct net *net
+ struct udp_media_addr *dst, struct dst_cache *cache)
+ {
+ struct dst_entry *ndst;
+- int ttl, err = 0;
++ int ttl, err;
+
+ local_bh_disable();
+ ndst = dst_cache_get(cache);
+@@ -217,13 +217,13 @@ static int tipc_udp_xmit(struct net *net
+ dst_cache_set_ip6(cache, ndst, &fl6.saddr);
+ }
+ ttl = ip6_dst_hoplimit(ndst);
+- err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL,
+- &src->ipv6, &dst->ipv6, 0, ttl, 0,
+- src->port, dst->port, false);
++ udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL,
++ &src->ipv6, &dst->ipv6, 0, ttl, 0,
++ src->port, dst->port, false);
+ #endif
+ }
+ local_bh_enable();
+- return err;
++ return 0;
+
+ tx_error:
+ local_bh_enable();
--- /dev/null
+From prvs=262951c835=andrey.grodzovsky@crowdstrike.com Thu Jun 18 21:16:01 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:23 -0400
+Subject: scripts/sorttable: Add helper functions for Elf_Ehdr
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <0cc98e948927e588c76a9a6a8b695ceb74259c1f.1781809936.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 1dfb59a228dde59ad7d99b2fa2104e90004995c7 ]
+
+In order to remove the double #include of sorttable.h for 64 and 32 bit
+to create duplicate functions, add helper functions for Elf_Ehdr. This
+will create a function pointer for each helper that will get assigned to
+the appropriate function to handle either the 64bit or 32bit version.
+
+This also moves the _r()/r() wrappers for the Elf_Ehdr references that
+handle endian and size differences between the different architectures,
+into the helper function and out of the open code which is more error
+prone.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162345.736369526@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 25 +++++++++++++++++++++++++
+ scripts/sorttable.h | 20 ++++++++++++++++----
+ 2 files changed, 41 insertions(+), 4 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -85,6 +85,31 @@ static uint64_t (*r8)(const uint64_t *);
+ static void (*w)(uint32_t, uint32_t *);
+ typedef void (*table_sort_t)(char *, int);
+
++static uint64_t ehdr64_shoff(Elf_Ehdr *ehdr)
++{
++ return r8(&ehdr->e64.e_shoff);
++}
++
++static uint64_t ehdr32_shoff(Elf_Ehdr *ehdr)
++{
++ return r(&ehdr->e32.e_shoff);
++}
++
++#define EHDR_HALF(fn_name) \
++static uint16_t ehdr64_##fn_name(Elf_Ehdr *ehdr) \
++{ \
++ return r2(&ehdr->e64.e_##fn_name); \
++} \
++ \
++static uint16_t ehdr32_##fn_name(Elf_Ehdr *ehdr) \
++{ \
++ return r2(&ehdr->e32.e_##fn_name); \
++}
++
++EHDR_HALF(shentsize)
++EHDR_HALF(shstrndx)
++EHDR_HALF(shnum)
++
+ /*
+ * Get the whole file as a programming convenience in order to avoid
+ * malloc+lseek+read+free of many pieces. If successful, then mmap
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -27,6 +27,10 @@
+ #undef uint_t
+ #undef _r
+ #undef etype
++#undef ehdr_shoff
++#undef ehdr_shentsize
++#undef ehdr_shstrndx
++#undef ehdr_shnum
+
+ #ifdef SORTTABLE_64
+ # define extable_ent_size 16
+@@ -39,6 +43,10 @@
+ # define uint_t uint64_t
+ # define _r r8
+ # define etype e64
++# define ehdr_shoff ehdr64_shoff
++# define ehdr_shentsize ehdr64_shentsize
++# define ehdr_shstrndx ehdr64_shstrndx
++# define ehdr_shnum ehdr64_shnum
+ #else
+ # define extable_ent_size 8
+ # define compare_extable compare_extable_32
+@@ -50,6 +58,10 @@
+ # define uint_t uint32_t
+ # define _r r
+ # define etype e32
++# define ehdr_shoff ehdr32_shoff
++# define ehdr_shentsize ehdr32_shentsize
++# define ehdr_shstrndx ehdr32_shstrndx
++# define ehdr_shnum ehdr32_shnum
+ #endif
+
+ #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+@@ -250,16 +262,16 @@ static int do_sort(Elf_Ehdr *ehdr,
+ unsigned int orc_num_entries = 0;
+ #endif
+
+- shdr_start = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
+- shentsize = r2(&ehdr->etype.e_shentsize);
++ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
++ shentsize = ehdr_shentsize(ehdr);
+
+- shstrndx = r2(&ehdr->etype.e_shstrndx);
++ shstrndx = ehdr_shstrndx(ehdr);
+ if (shstrndx == SHN_XINDEX)
+ shstrndx = r(&shdr_start->etype.sh_link);
+ string_sec = get_index(shdr_start, shentsize, shstrndx);
+ secstrings = (const char *)ehdr + _r(&string_sec->etype.sh_offset);
+
+- shnum = r2(&ehdr->etype.e_shnum);
++ shnum = ehdr_shnum(ehdr);
+ if (shnum == SHN_UNDEF)
+ shnum = _r(&shdr_start->etype.sh_size);
+
--- /dev/null
+From stable+bounces-267211-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:11 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:24 -0400
+Subject: scripts/sorttable: Add helper functions for Elf_Shdr
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <67462057b3867a75adaa8de9b8a091c2787f7735.1781809940.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 67afb7f504400e5b4e5ff895459fbb3eb63d4450 ]
+
+In order to remove the double #include of sorttable.h for 64 and 32 bit
+to create duplicate functions, add helper functions for Elf_Shdr. This
+will create a function pointer for each helper that will get assigned to
+the appropriate function to handle either the 64bit or 32bit version.
+
+This also moves the _r()/r() wrappers for the Elf_Shdr references that
+handle endian and size differences between the different architectures,
+into the helper function and out of the open code which is more error
+prone.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162345.940924221@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 42 +++++++++++++++++++++++++++++++++
+ scripts/sorttable.h | 66 +++++++++++++++++++++++++++++++++-------------------
+ 2 files changed, 85 insertions(+), 23 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -110,6 +110,48 @@ EHDR_HALF(shentsize)
+ EHDR_HALF(shstrndx)
+ EHDR_HALF(shnum)
+
++#define SHDR_WORD(fn_name) \
++static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
++{ \
++ return r(&shdr->e64.sh_##fn_name); \
++} \
++ \
++static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
++{ \
++ return r(&shdr->e32.sh_##fn_name); \
++}
++
++#define SHDR_ADDR(fn_name) \
++static uint64_t shdr64_##fn_name(Elf_Shdr *shdr) \
++{ \
++ return r8(&shdr->e64.sh_##fn_name); \
++} \
++ \
++static uint64_t shdr32_##fn_name(Elf_Shdr *shdr) \
++{ \
++ return r(&shdr->e32.sh_##fn_name); \
++}
++
++#define SHDR_WORD(fn_name) \
++static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
++{ \
++ return r(&shdr->e64.sh_##fn_name); \
++} \
++ \
++static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
++{ \
++ return r(&shdr->e32.sh_##fn_name); \
++}
++
++SHDR_ADDR(addr)
++SHDR_ADDR(offset)
++SHDR_ADDR(size)
++SHDR_ADDR(entsize)
++
++SHDR_WORD(link)
++SHDR_WORD(name)
++SHDR_WORD(type)
++
+ /*
+ * Get the whole file as a programming convenience in order to avoid
+ * malloc+lseek+read+free of many pieces. If successful, then mmap
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -31,6 +31,13 @@
+ #undef ehdr_shentsize
+ #undef ehdr_shstrndx
+ #undef ehdr_shnum
++#undef shdr_addr
++#undef shdr_offset
++#undef shdr_link
++#undef shdr_size
++#undef shdr_name
++#undef shdr_type
++#undef shdr_entsize
+
+ #ifdef SORTTABLE_64
+ # define extable_ent_size 16
+@@ -47,6 +54,13 @@
+ # define ehdr_shentsize ehdr64_shentsize
+ # define ehdr_shstrndx ehdr64_shstrndx
+ # define ehdr_shnum ehdr64_shnum
++# define shdr_addr shdr64_addr
++# define shdr_offset shdr64_offset
++# define shdr_link shdr64_link
++# define shdr_size shdr64_size
++# define shdr_name shdr64_name
++# define shdr_type shdr64_type
++# define shdr_entsize shdr64_entsize
+ #else
+ # define extable_ent_size 8
+ # define compare_extable compare_extable_32
+@@ -62,6 +76,13 @@
+ # define ehdr_shentsize ehdr32_shentsize
+ # define ehdr_shstrndx ehdr32_shstrndx
+ # define ehdr_shnum ehdr32_shnum
++# define shdr_addr shdr32_addr
++# define shdr_offset shdr32_offset
++# define shdr_link shdr32_link
++# define shdr_size shdr32_size
++# define shdr_name shdr32_name
++# define shdr_type shdr32_type
++# define shdr_entsize shdr32_entsize
+ #endif
+
+ #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+@@ -177,8 +198,8 @@ struct elf_mcount_loc {
+ static void *sort_mcount_loc(void *arg)
+ {
+ struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
+- uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->etype.sh_addr)
+- + _r(&(emloc->init_data_sec)->etype.sh_offset);
++ uint_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
++ + shdr_offset(emloc->init_data_sec);
+ uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
+ unsigned char *start_loc = (void *)emloc->ehdr + offset;
+
+@@ -267,18 +288,18 @@ static int do_sort(Elf_Ehdr *ehdr,
+
+ shstrndx = ehdr_shstrndx(ehdr);
+ if (shstrndx == SHN_XINDEX)
+- shstrndx = r(&shdr_start->etype.sh_link);
++ shstrndx = shdr_link(shdr_start);
+ string_sec = get_index(shdr_start, shentsize, shstrndx);
+- secstrings = (const char *)ehdr + _r(&string_sec->etype.sh_offset);
++ secstrings = (const char *)ehdr + shdr_offset(string_sec);
+
+ shnum = ehdr_shnum(ehdr);
+ if (shnum == SHN_UNDEF)
+- shnum = _r(&shdr_start->etype.sh_size);
++ shnum = shdr_size(shdr_start);
+
+ for (i = 0; i < shnum; i++) {
+ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
+
+- idx = r(&shdr->etype.sh_name);
++ idx = shdr_name(shdr);
+ if (!strcmp(secstrings + idx, "__ex_table"))
+ extab_sec = shdr;
+ if (!strcmp(secstrings + idx, ".symtab"))
+@@ -286,9 +307,9 @@ static int do_sort(Elf_Ehdr *ehdr,
+ if (!strcmp(secstrings + idx, ".strtab"))
+ strtab_sec = shdr;
+
+- if (r(&shdr->etype.sh_type) == SHT_SYMTAB_SHNDX)
++ if (shdr_type(shdr) == SHT_SYMTAB_SHNDX)
+ symtab_shndx = (Elf32_Word *)((const char *)ehdr +
+- _r(&shdr->etype.sh_offset));
++ shdr_offset(shdr));
+
+ #ifdef MCOUNT_SORT_ENABLED
+ /* locate the .init.data section in vmlinux */
+@@ -304,14 +325,14 @@ static int do_sort(Elf_Ehdr *ehdr,
+ #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+ /* locate the ORC unwind tables */
+ if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
+- orc_ip_size = _r(&shdr->etype.sh_size);
++ orc_ip_size = shdr_size(shdr);
+ g_orc_ip_table = (int *)((void *)ehdr +
+- _r(&shdr->etype.sh_offset));
++ shdr_offset(shdr));
+ }
+ if (!strcmp(secstrings + idx, ".orc_unwind")) {
+- orc_size = _r(&shdr->etype.sh_size);
++ orc_size = shdr_size(shdr);
+ g_orc_table = (struct orc_entry *)((void *)ehdr +
+- _r(&shdr->etype.sh_offset));
++ shdr_offset(shdr));
+ }
+ #endif
+ } /* for loop */
+@@ -374,23 +395,22 @@ static int do_sort(Elf_Ehdr *ehdr,
+ goto out;
+ }
+
+- extab_image = (void *)ehdr + _r(&extab_sec->etype.sh_offset);
+- strtab = (const char *)ehdr + _r(&strtab_sec->etype.sh_offset);
+- symtab = (const Elf_Sym *)((const char *)ehdr +
+- _r(&symtab_sec->etype.sh_offset));
++ extab_image = (void *)ehdr + shdr_offset(extab_sec);
++ strtab = (const char *)ehdr + shdr_offset(strtab_sec);
++ symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec));
+
+ if (custom_sort) {
+- custom_sort(extab_image, _r(&extab_sec->etype.sh_size));
++ custom_sort(extab_image, shdr_size(extab_sec));
+ } else {
+- int num_entries = _r(&extab_sec->etype.sh_size) / extable_ent_size;
++ int num_entries = shdr_size(extab_sec) / extable_ent_size;
+ qsort(extab_image, num_entries,
+ extable_ent_size, compare_extable);
+ }
+
+ /* find the flag main_extable_sort_needed */
+- sym_start = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
+- sym_end = sym_start + _r(&symtab_sec->etype.sh_size);
+- symentsize = _r(&symtab_sec->etype.sh_entsize);
++ sym_start = (void *)ehdr + shdr_offset(symtab_sec);
++ sym_end = sym_start + shdr_size(symtab_sec);
++ symentsize = shdr_entsize(symtab_sec);
+
+ for (sym = sym_start; (void *)sym + symentsize < sym_end;
+ sym = (void *)sym + symentsize) {
+@@ -415,9 +435,9 @@ static int do_sort(Elf_Ehdr *ehdr,
+ symtab_shndx);
+ sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
+ sort_needed_loc = (void *)ehdr +
+- _r(&sort_needed_sec->etype.sh_offset) +
++ shdr_offset(sort_needed_sec) +
+ _r(&sort_needed_sym->etype.st_value) -
+- _r(&sort_needed_sec->etype.sh_addr);
++ shdr_addr(sort_needed_sec);
+
+ /* extable has been sorted, clear the flag */
+ w(0, sort_needed_loc);
--- /dev/null
+From prvs=262951c835=andrey.grodzovsky@crowdstrike.com Thu Jun 18 21:16:03 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:25 -0400
+Subject: scripts/sorttable: Add helper functions for Elf_Sym
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <3ef7d2f3e8d9dc192663d7270f7ecd41e78c80e1.1781809943.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 17bed33ac12f011f4695059960e1b1d6457229a7 ]
+
+In order to remove the double #include of sorttable.h for 64 and 32 bit
+to create duplicate functions, add helper functions for Elf_Sym. This
+will create a function pointer for each helper that will get assigned to
+the appropriate function to handle either the 64bit or 32bit version.
+
+This also removes the last references of etype and _r() macros from the
+sorttable.h file as their references are now just defined in the
+appropriate architecture version of the helper functions. All read
+functions now exist in the helper functions which makes it easier to
+maintain, as the helper functions define the necessary architecture sizes.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162346.185740651@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
+ scripts/sorttable.h | 30 ++++++++++++++++--------------
+ 2 files changed, 63 insertions(+), 14 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -152,6 +152,53 @@ SHDR_WORD(link)
+ SHDR_WORD(name)
+ SHDR_WORD(type)
+
++#define SYM_ADDR(fn_name) \
++static uint64_t sym64_##fn_name(Elf_Sym *sym) \
++{ \
++ return r8(&sym->e64.st_##fn_name); \
++} \
++ \
++static uint64_t sym32_##fn_name(Elf_Sym *sym) \
++{ \
++ return r(&sym->e32.st_##fn_name); \
++}
++
++#define SYM_WORD(fn_name) \
++static uint32_t sym64_##fn_name(Elf_Sym *sym) \
++{ \
++ return r(&sym->e64.st_##fn_name); \
++} \
++ \
++static uint32_t sym32_##fn_name(Elf_Sym *sym) \
++{ \
++ return r(&sym->e32.st_##fn_name); \
++}
++
++#define SYM_HALF(fn_name) \
++static uint16_t sym64_##fn_name(Elf_Sym *sym) \
++{ \
++ return r2(&sym->e64.st_##fn_name); \
++} \
++ \
++static uint16_t sym32_##fn_name(Elf_Sym *sym) \
++{ \
++ return r2(&sym->e32.st_##fn_name); \
++}
++
++static uint8_t sym64_type(Elf_Sym *sym)
++{
++ return ELF64_ST_TYPE(sym->e64.st_info);
++}
++
++static uint8_t sym32_type(Elf_Sym *sym)
++{
++ return ELF32_ST_TYPE(sym->e32.st_info);
++}
++
++SYM_ADDR(value)
++SYM_WORD(name)
++SYM_HALF(shndx)
++
+ /*
+ * Get the whole file as a programming convenience in order to avoid
+ * malloc+lseek+read+free of many pieces. If successful, then mmap
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -23,10 +23,7 @@
+ #undef sort_mcount_loc
+ #undef elf_mcount_loc
+ #undef do_sort
+-#undef ELF_ST_TYPE
+ #undef uint_t
+-#undef _r
+-#undef etype
+ #undef ehdr_shoff
+ #undef ehdr_shentsize
+ #undef ehdr_shstrndx
+@@ -38,6 +35,10 @@
+ #undef shdr_name
+ #undef shdr_type
+ #undef shdr_entsize
++#undef sym_type
++#undef sym_name
++#undef sym_value
++#undef sym_shndx
+
+ #ifdef SORTTABLE_64
+ # define extable_ent_size 16
+@@ -46,10 +47,7 @@
+ # define sort_mcount_loc sort_mcount_loc_64
+ # define elf_mcount_loc elf_mcount_loc_64
+ # define do_sort do_sort_64
+-# define ELF_ST_TYPE ELF64_ST_TYPE
+ # define uint_t uint64_t
+-# define _r r8
+-# define etype e64
+ # define ehdr_shoff ehdr64_shoff
+ # define ehdr_shentsize ehdr64_shentsize
+ # define ehdr_shstrndx ehdr64_shstrndx
+@@ -61,6 +59,10 @@
+ # define shdr_name shdr64_name
+ # define shdr_type shdr64_type
+ # define shdr_entsize shdr64_entsize
++# define sym_type sym64_type
++# define sym_name sym64_name
++# define sym_value sym64_value
++# define sym_shndx sym64_shndx
+ #else
+ # define extable_ent_size 8
+ # define compare_extable compare_extable_32
+@@ -68,10 +70,7 @@
+ # define sort_mcount_loc sort_mcount_loc_32
+ # define elf_mcount_loc elf_mcount_loc_32
+ # define do_sort do_sort_32
+-# define ELF_ST_TYPE ELF32_ST_TYPE
+ # define uint_t uint32_t
+-# define _r r
+-# define etype e32
+ # define ehdr_shoff ehdr32_shoff
+ # define ehdr_shentsize ehdr32_shentsize
+ # define ehdr_shstrndx ehdr32_shstrndx
+@@ -83,6 +82,10 @@
+ # define shdr_name shdr32_name
+ # define shdr_type shdr32_type
+ # define shdr_entsize shdr32_entsize
++# define sym_type sym32_type
++# define sym_name sym32_name
++# define sym_value sym32_value
++# define sym_shndx sym32_shndx
+ #endif
+
+ #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+@@ -414,9 +417,9 @@ static int do_sort(Elf_Ehdr *ehdr,
+
+ for (sym = sym_start; (void *)sym + symentsize < sym_end;
+ sym = (void *)sym + symentsize) {
+- if (ELF_ST_TYPE(sym->etype.st_info) != STT_OBJECT)
++ if (sym_type(sym) != STT_OBJECT)
+ continue;
+- if (!strcmp(strtab + r(&sym->etype.st_name),
++ if (!strcmp(strtab + sym_name(sym),
+ "main_extable_sort_needed")) {
+ sort_needed_sym = sym;
+ break;
+@@ -430,14 +433,13 @@ static int do_sort(Elf_Ehdr *ehdr,
+ goto out;
+ }
+
+- sort_need_index = get_secindex(r2(&sym->etype.st_shndx),
++ sort_need_index = get_secindex(sym_shndx(sym),
+ ((void *)sort_needed_sym - (void *)symtab) / symentsize,
+ symtab_shndx);
+ sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
+ sort_needed_loc = (void *)ehdr +
+ shdr_offset(sort_needed_sec) +
+- _r(&sort_needed_sym->etype.st_value) -
+- shdr_addr(sort_needed_sec);
++ sym_value(sort_needed_sym) - shdr_addr(sort_needed_sec);
+
+ /* extable has been sorted, clear the flag */
+ w(0, sort_needed_loc);
--- /dev/null
+From stable+bounces-267226-greg=kroah.com@vger.kernel.org Thu Jun 18 21:17:53 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:40 -0400
+Subject: scripts/sorttable: Allow matches to functions before function entry
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <7b17ef2d6c2be58e80c028343547c67c81de3d56.1781809987.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit dc208c69c033d3caba0509da1ae065d2b5ff165f ]
+
+ARM 64 uses -fpatchable-function-entry=4,2 which adds padding before the
+function and the addresses in the mcount_loc point there instead of the
+function entry that is returned by nm. In order to find a function from nm
+to make sure it's not an unused weak function, the entries in the
+mcount_loc section needs to match the entries from nm. Since it can be an
+instruction before the entry, add a before_func variable that ARM 64 can
+set to 8, and if the mcount_loc entry is within 8 bytes of the nm function
+entry, then it will be considered a match.
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: "Arnd Bergmann" <arnd@arndb.de>
+Cc: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/20250225182054.815536219@goodmis.org
+Fixes: ef378c3b82338 ("scripts/sorttable: Zero out weak functions in mcount_loc table")
+Tested-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -611,13 +611,16 @@ static int add_field(uint64_t addr, uint
+ return 0;
+ }
+
++/* Used for when mcount/fentry is before the function entry */
++static int before_func;
++
+ /* Only return match if the address lies inside the function size */
+ static int cmp_func_addr(const void *K, const void *A)
+ {
+ uint64_t key = *(const uint64_t *)K;
+ const struct func_info *a = A;
+
+- if (key < a->addr)
++ if (key + before_func < a->addr)
+ return -1;
+ return key >= a->addr + a->size;
+ }
+@@ -1253,6 +1256,8 @@ static int do_file(char const *const fna
+ #ifdef MCOUNT_SORT_ENABLED
+ sort_reloc = true;
+ rela_type = 0x403;
++ /* arm64 uses patchable function entry placing before function */
++ before_func = 8;
+ #endif
+ /* fallthrough */
+ case EM_386:
--- /dev/null
+From stable+bounces-267218-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:52 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:32 -0400
+Subject: scripts/sorttable: Always use an array for the mcount_loc sorting
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <64aae6881f5521a50e49dd5bf896da200f28a8d4.1781809963.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 5fb964f5ba53afda0e2b6dbc00b8205461ffe04a ]
+
+The sorting of the mcount_loc section is done directly to the section for
+x86 and arm32 but it uses a separate array for arm64 as arm64 has the
+values for the mcount_loc stored in the rela sections of the vmlinux ELF
+file.
+
+In order to use the same code to remove weak functions, always use a
+separate array to do the sorting. This requires splitting up the filling
+of the array into one function and the placing the contents of the array
+back into the rela sections or into the mcount_loc section into a separate
+file.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Alexander Gordeev <agordeev@linux.ibm.com>
+Link: https://lore.kernel.org/20250218200022.710676551@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 122 ++++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 90 insertions(+), 32 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -594,31 +594,19 @@ struct elf_mcount_loc {
+ uint64_t stop_mcount_loc;
+ };
+
+-/* Sort the relocations not the address itself */
+-static void *sort_relocs(Elf_Ehdr *ehdr, uint64_t start_loc, uint64_t size)
++/* Fill the array with the content of the relocs */
++static int fill_relocs(void *ptr, uint64_t size, Elf_Ehdr *ehdr, uint64_t start_loc)
+ {
+ Elf_Shdr *shdr_start;
+ Elf_Rela *rel;
+ unsigned int shnum;
+- unsigned int count;
++ unsigned int count = 0;
+ int shentsize;
+- void *vals;
+- void *ptr;
+-
+- compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
++ void *array_end = ptr + size;
+
+ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
+ shentsize = ehdr_shentsize(ehdr);
+
+- vals = malloc(long_size * size);
+- if (!vals) {
+- snprintf(m_err, ERRSTR_MAXSZ, "Failed to allocate sort array");
+- pthread_exit(m_err);
+- return NULL;
+- }
+-
+- ptr = vals;
+-
+ shnum = ehdr_shnum(ehdr);
+ if (shnum == SHN_UNDEF)
+ shnum = shdr_size(shdr_start);
+@@ -637,22 +625,18 @@ static void *sort_relocs(Elf_Ehdr *ehdr,
+ uint64_t offset = rela_offset(rel);
+
+ if (offset >= start_loc && offset < start_loc + size) {
+- if (ptr + long_size > vals + size) {
+- free(vals);
++ if (ptr + long_size > array_end) {
+ snprintf(m_err, ERRSTR_MAXSZ,
+ "Too many relocations");
+- pthread_exit(m_err);
+- return NULL;
++ return -1;
+ }
+
+ /* Make sure this has the correct type */
+ if (rela_info(rel) != rela_type) {
+- free(vals);
+ snprintf(m_err, ERRSTR_MAXSZ,
+ "rela has type %lx but expected %lx\n",
+ (long)rela_info(rel), rela_type);
+- pthread_exit(m_err);
+- return NULL;
++ return -1;
+ }
+
+ if (long_size == 4)
+@@ -660,13 +644,28 @@ static void *sort_relocs(Elf_Ehdr *ehdr,
+ else
+ *(uint64_t *)ptr = rela_addend(rel);
+ ptr += long_size;
++ count++;
+ }
+ }
+ }
+- count = ptr - vals;
+- qsort(vals, count / long_size, long_size, compare_values);
++ return count;
++}
++
++/* Put the sorted vals back into the relocation elements */
++static void replace_relocs(void *ptr, uint64_t size, Elf_Ehdr *ehdr, uint64_t start_loc)
++{
++ Elf_Shdr *shdr_start;
++ Elf_Rela *rel;
++ unsigned int shnum;
++ int shentsize;
++
++ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
++ shentsize = ehdr_shentsize(ehdr);
++
++ shnum = ehdr_shnum(ehdr);
++ if (shnum == SHN_UNDEF)
++ shnum = shdr_size(shdr_start);
+
+- ptr = vals;
+ for (int i = 0; i < shnum; i++) {
+ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
+ void *end;
+@@ -689,8 +688,32 @@ static void *sort_relocs(Elf_Ehdr *ehdr,
+ }
+ }
+ }
+- free(vals);
+- return NULL;
++}
++
++static int fill_addrs(void *ptr, uint64_t size, void *addrs)
++{
++ void *end = ptr + size;
++ int count = 0;
++
++ for (; ptr < end; ptr += long_size, addrs += long_size, count++) {
++ if (long_size == 4)
++ *(uint32_t *)ptr = r(addrs);
++ else
++ *(uint64_t *)ptr = r8(addrs);
++ }
++ return count;
++}
++
++static void replace_addrs(void *ptr, uint64_t size, void *addrs)
++{
++ void *end = ptr + size;
++
++ for (; ptr < end; ptr += long_size, addrs += long_size) {
++ if (long_size == 4)
++ w(*(uint32_t *)ptr, addrs);
++ else
++ w8(*(uint64_t *)ptr, addrs);
++ }
+ }
+
+ /* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
+@@ -699,14 +722,49 @@ static void *sort_mcount_loc(void *arg)
+ struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
+ uint64_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
+ + shdr_offset(emloc->init_data_sec);
+- uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
++ uint64_t size = emloc->stop_mcount_loc - emloc->start_mcount_loc;
+ unsigned char *start_loc = (void *)emloc->ehdr + offset;
++ Elf_Ehdr *ehdr = emloc->ehdr;
++ void *e_msg = NULL;
++ void *vals;
++ int count;
++
++ vals = malloc(long_size * size);
++ if (!vals) {
++ snprintf(m_err, ERRSTR_MAXSZ, "Failed to allocate sort array");
++ pthread_exit(m_err);
++ }
+
+ if (sort_reloc)
+- return sort_relocs(emloc->ehdr, emloc->start_mcount_loc, count);
++ count = fill_relocs(vals, size, ehdr, emloc->start_mcount_loc);
++ else
++ count = fill_addrs(vals, size, start_loc);
++
++ if (count < 0) {
++ e_msg = m_err;
++ goto out;
++ }
++
++ if (count != size / long_size) {
++ snprintf(m_err, ERRSTR_MAXSZ, "Expected %u mcount elements but found %u\n",
++ (int)(size / long_size), count);
++ e_msg = m_err;
++ goto out;
++ }
++
++ compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
++
++ qsort(vals, count, long_size, compare_values);
++
++ if (sort_reloc)
++ replace_relocs(vals, size, ehdr, emloc->start_mcount_loc);
++ else
++ replace_addrs(vals, size, start_loc);
++
++out:
++ free(vals);
+
+- qsort(start_loc, count/long_size, long_size, compare_extable);
+- return NULL;
++ pthread_exit(e_msg);
+ }
+
+ /* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
--- /dev/null
+From prvs=262951c835=andrey.grodzovsky@crowdstrike.com Thu Jun 18 21:16:03 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:20 -0400
+Subject: scripts/sorttable: Convert Elf_Ehdr to union
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <ffbf4890fa9bdef1135c98294fc40bbe5f918004.1781809926.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 157fb5b3cfd2cb5950314f926a76e567fc1921c5 ]
+
+In order to remove the double #include of sorttable.h for 64 and 32 bit
+to create duplicate functions for both, replace the Elf_Ehdr macro with a
+union that defines both Elf64_Ehdr and Elf32_Ehdr, with field e64 for the
+64bit version, and e32 for the 32bit version.
+
+Then a macro etype can be used instead to get to the proper value.
+
+This will eventually be replaced with just single functions that can
+handle both 32bit and 64bit ELF parsing.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162345.148224465@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 36 ++++++++++++++++++++----------------
+ scripts/sorttable.h | 12 ++++++------
+ 2 files changed, 26 insertions(+), 22 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -64,6 +64,11 @@
+ #define EM_LOONGARCH 258
+ #endif
+
++typedef union {
++ Elf32_Ehdr e32;
++ Elf64_Ehdr e64;
++} Elf_Ehdr;
++
+ static uint32_t (*r)(const uint32_t *);
+ static uint16_t (*r2)(const uint16_t *);
+ static uint64_t (*r8)(const uint64_t *);
+@@ -266,10 +271,10 @@ static void sort_relative_table_with_dat
+ static int do_file(char const *const fname, void *addr)
+ {
+ int rc = -1;
+- Elf32_Ehdr *ehdr = addr;
++ Elf_Ehdr *ehdr = addr;
+ table_sort_t custom_sort = NULL;
+
+- switch (ehdr->e_ident[EI_DATA]) {
++ switch (ehdr->e32.e_ident[EI_DATA]) {
+ case ELFDATA2LSB:
+ r = rle;
+ r2 = r2le;
+@@ -284,18 +289,18 @@ static int do_file(char const *const fna
+ break;
+ default:
+ fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
+- ehdr->e_ident[EI_DATA], fname);
++ ehdr->e32.e_ident[EI_DATA], fname);
+ return -1;
+ }
+
+- if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0 ||
+- (r2(&ehdr->e_type) != ET_EXEC && r2(&ehdr->e_type) != ET_DYN) ||
+- ehdr->e_ident[EI_VERSION] != EV_CURRENT) {
++ if (memcmp(ELFMAG, ehdr->e32.e_ident, SELFMAG) != 0 ||
++ (r2(&ehdr->e32.e_type) != ET_EXEC && r2(&ehdr->e32.e_type) != ET_DYN) ||
++ ehdr->e32.e_ident[EI_VERSION] != EV_CURRENT) {
+ fprintf(stderr, "unrecognized ET_EXEC/ET_DYN file %s\n", fname);
+ return -1;
+ }
+
+- switch (r2(&ehdr->e_machine)) {
++ switch (r2(&ehdr->e32.e_machine)) {
+ case EM_386:
+ case EM_AARCH64:
+ case EM_LOONGARCH:
+@@ -318,14 +323,14 @@ static int do_file(char const *const fna
+ break;
+ default:
+ fprintf(stderr, "unrecognized e_machine %d %s\n",
+- r2(&ehdr->e_machine), fname);
++ r2(&ehdr->e32.e_machine), fname);
+ return -1;
+ }
+
+- switch (ehdr->e_ident[EI_CLASS]) {
++ switch (ehdr->e32.e_ident[EI_CLASS]) {
+ case ELFCLASS32:
+- if (r2(&ehdr->e_ehsize) != sizeof(Elf32_Ehdr) ||
+- r2(&ehdr->e_shentsize) != sizeof(Elf32_Shdr)) {
++ if (r2(&ehdr->e32.e_ehsize) != sizeof(Elf32_Ehdr) ||
++ r2(&ehdr->e32.e_shentsize) != sizeof(Elf32_Shdr)) {
+ fprintf(stderr,
+ "unrecognized ET_EXEC/ET_DYN file: %s\n", fname);
+ break;
+@@ -334,20 +339,19 @@ static int do_file(char const *const fna
+ break;
+ case ELFCLASS64:
+ {
+- Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr;
+- if (r2(&ghdr->e_ehsize) != sizeof(Elf64_Ehdr) ||
+- r2(&ghdr->e_shentsize) != sizeof(Elf64_Shdr)) {
++ if (r2(&ehdr->e64.e_ehsize) != sizeof(Elf64_Ehdr) ||
++ r2(&ehdr->e64.e_shentsize) != sizeof(Elf64_Shdr)) {
+ fprintf(stderr,
+ "unrecognized ET_EXEC/ET_DYN file: %s\n",
+ fname);
+ break;
+ }
+- rc = do_sort_64(ghdr, fname, custom_sort);
++ rc = do_sort_64(ehdr, fname, custom_sort);
+ }
+ break;
+ default:
+ fprintf(stderr, "unrecognized ELF class %d %s\n",
+- ehdr->e_ident[EI_CLASS], fname);
++ ehdr->e32.e_ident[EI_CLASS], fname);
+ break;
+ }
+
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -23,12 +23,12 @@
+ #undef sort_mcount_loc
+ #undef elf_mcount_loc
+ #undef do_sort
+-#undef Elf_Ehdr
+ #undef Elf_Shdr
+ #undef Elf_Sym
+ #undef ELF_ST_TYPE
+ #undef uint_t
+ #undef _r
++#undef etype
+
+ #ifdef SORTTABLE_64
+ # define extable_ent_size 16
+@@ -37,12 +37,12 @@
+ # define sort_mcount_loc sort_mcount_loc_64
+ # define elf_mcount_loc elf_mcount_loc_64
+ # define do_sort do_sort_64
+-# define Elf_Ehdr Elf64_Ehdr
+ # define Elf_Shdr Elf64_Shdr
+ # define Elf_Sym Elf64_Sym
+ # define ELF_ST_TYPE ELF64_ST_TYPE
+ # define uint_t uint64_t
+ # define _r r8
++# define etype e64
+ #else
+ # define extable_ent_size 8
+ # define compare_extable compare_extable_32
+@@ -50,12 +50,12 @@
+ # define sort_mcount_loc sort_mcount_loc_32
+ # define elf_mcount_loc elf_mcount_loc_32
+ # define do_sort do_sort_32
+-# define Elf_Ehdr Elf32_Ehdr
+ # define Elf_Shdr Elf32_Shdr
+ # define Elf_Sym Elf32_Sym
+ # define ELF_ST_TYPE ELF32_ST_TYPE
+ # define uint_t uint32_t
+ # define _r r
++# define etype e32
+ #endif
+
+ #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+@@ -222,7 +222,7 @@ static int do_sort(Elf_Ehdr *ehdr,
+ table_sort_t custom_sort)
+ {
+ int rc = -1;
+- Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff));
++ Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
+ Elf_Shdr *strtab_sec = NULL;
+ Elf_Shdr *symtab_sec = NULL;
+ Elf_Shdr *extab_sec = NULL;
+@@ -249,12 +249,12 @@ static int do_sort(Elf_Ehdr *ehdr,
+ unsigned int orc_num_entries = 0;
+ #endif
+
+- shstrndx = r2(&ehdr->e_shstrndx);
++ shstrndx = r2(&ehdr->etype.e_shstrndx);
+ if (shstrndx == SHN_XINDEX)
+ shstrndx = r(&shdr[0].sh_link);
+ secstrings = (const char *)ehdr + _r(&shdr[shstrndx].sh_offset);
+
+- shnum = r2(&ehdr->e_shnum);
++ shnum = r2(&ehdr->etype.e_shnum);
+ if (shnum == SHN_UNDEF)
+ shnum = _r(&shdr[0].sh_size);
+
--- /dev/null
+From prvs=262951c835=andrey.grodzovsky@crowdstrike.com Thu Jun 18 21:16:00 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:22 -0400
+Subject: scripts/sorttable: Convert Elf_Sym MACRO over to a union
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <730403c91a917d659d9dfbf21ba9a57959ef1051.1781809932.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 200d015e73b4da69bcd8212a7c58695452b12bad ]
+
+In order to remove the double #include of sorttable.h for 64 and 32 bit
+to create duplicate functions for both, replace the Elf_Sym macro with a
+union that defines both Elf64_Sym and Elf32_Sym, with field e64 for the
+64bit version, and e32 for the 32bit version.
+
+It can then use the macro etype to get the proper value.
+
+This will eventually be replaced with just single functions that can
+handle both 32bit and 64bit ELF parsing.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162345.528626969@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 5 +++++
+ scripts/sorttable.h | 25 ++++++++++++++-----------
+ 2 files changed, 19 insertions(+), 11 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -74,6 +74,11 @@ typedef union {
+ Elf64_Shdr e64;
+ } Elf_Shdr;
+
++typedef union {
++ Elf32_Sym e32;
++ Elf64_Sym e64;
++} Elf_Sym;
++
+ static uint32_t (*r)(const uint32_t *);
+ static uint16_t (*r2)(const uint16_t *);
+ static uint64_t (*r8)(const uint64_t *);
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -23,7 +23,6 @@
+ #undef sort_mcount_loc
+ #undef elf_mcount_loc
+ #undef do_sort
+-#undef Elf_Sym
+ #undef ELF_ST_TYPE
+ #undef uint_t
+ #undef _r
+@@ -36,7 +35,6 @@
+ # define sort_mcount_loc sort_mcount_loc_64
+ # define elf_mcount_loc elf_mcount_loc_64
+ # define do_sort do_sort_64
+-# define Elf_Sym Elf64_Sym
+ # define ELF_ST_TYPE ELF64_ST_TYPE
+ # define uint_t uint64_t
+ # define _r r8
+@@ -48,7 +46,6 @@
+ # define sort_mcount_loc sort_mcount_loc_32
+ # define elf_mcount_loc elf_mcount_loc_32
+ # define do_sort do_sort_32
+-# define Elf_Sym Elf32_Sym
+ # define ELF_ST_TYPE ELF32_ST_TYPE
+ # define uint_t uint32_t
+ # define _r r
+@@ -230,10 +227,13 @@ static int do_sort(Elf_Ehdr *ehdr,
+ Elf_Sym *sort_needed_sym = NULL;
+ Elf_Shdr *sort_needed_sec;
+ uint32_t *sort_needed_loc;
++ void *sym_start;
++ void *sym_end;
+ const char *secstrings;
+ const char *strtab;
+ char *extab_image;
+ int sort_need_index;
++ int symentsize;
+ int shentsize;
+ int idx;
+ int i;
+@@ -376,12 +376,15 @@ static int do_sort(Elf_Ehdr *ehdr,
+ }
+
+ /* find the flag main_extable_sort_needed */
+- for (sym = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
+- sym < sym + _r(&symtab_sec->etype.sh_size) / sizeof(Elf_Sym);
+- sym++) {
+- if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
++ sym_start = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
++ sym_end = sym_start + _r(&symtab_sec->etype.sh_size);
++ symentsize = _r(&symtab_sec->etype.sh_entsize);
++
++ for (sym = sym_start; (void *)sym + symentsize < sym_end;
++ sym = (void *)sym + symentsize) {
++ if (ELF_ST_TYPE(sym->etype.st_info) != STT_OBJECT)
+ continue;
+- if (!strcmp(strtab + r(&sym->st_name),
++ if (!strcmp(strtab + r(&sym->etype.st_name),
+ "main_extable_sort_needed")) {
+ sort_needed_sym = sym;
+ break;
+@@ -395,13 +398,13 @@ static int do_sort(Elf_Ehdr *ehdr,
+ goto out;
+ }
+
+- sort_need_index = get_secindex(r2(&sym->st_shndx),
+- sort_needed_sym - symtab,
++ sort_need_index = get_secindex(r2(&sym->etype.st_shndx),
++ ((void *)sort_needed_sym - (void *)symtab) / symentsize,
+ symtab_shndx);
+ sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
+ sort_needed_loc = (void *)ehdr +
+ _r(&sort_needed_sec->etype.sh_offset) +
+- _r(&sort_needed_sym->st_value) -
++ _r(&sort_needed_sym->etype.st_value) -
+ _r(&sort_needed_sec->etype.sh_addr);
+
+ /* extable has been sorted, clear the flag */
--- /dev/null
+From stable+bounces-267227-greg=kroah.com@vger.kernel.org Thu Jun 18 21:17:57 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:41 -0400
+Subject: scripts/sorttable: Fix endianness handling in build-time mcount sort
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <260290837178d984dbf07c74176f8997b62b42d8.1781809990.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Vasily Gorbik <gor@linux.ibm.com>
+
+[ Upstream commit 023f124a64174c47e18340ded7e2a39b96eb9523 ]
+
+Kernel cross-compilation with BUILDTIME_MCOUNT_SORT produces zeroed
+mcount values if the build-host endianness does not match the ELF
+file endianness.
+
+The mcount values array is converted from ELF file
+endianness to build-host endianness during initialization in
+fill_relocs()/fill_addrs(). Avoid extra conversion of these values during
+weak-function zeroing; otherwise, they do not match nm-parsed addresses
+and all mcount values are zeroed out.
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Alexander Gordeev <agordeev@linux.ibm.com>
+Link: https://lore.kernel.org/patch.git-dca31444b0f1.your-ad-here.call-01743554658-ext-8692@work.hours
+Fixes: ef378c3b8233 ("scripts/sorttable: Zero out weak functions in mcount_loc table")
+Reported-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Reported-by: Ihor Solodrai <ihor.solodrai@linux.dev>
+Closes: https://lore.kernel.org/all/your-ad-here.call-01743522822-ext-4975@work.hours/
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -857,7 +857,7 @@ static void *sort_mcount_loc(void *arg)
+ for (void *ptr = vals; ptr < vals + size; ptr += long_size) {
+ uint64_t key;
+
+- key = long_size == 4 ? r((uint32_t *)ptr) : r8((uint64_t *)ptr);
++ key = long_size == 4 ? *(uint32_t *)ptr : *(uint64_t *)ptr;
+ if (!find_func(key)) {
+ if (long_size == 4)
+ *(uint32_t *)ptr = 0;
--- /dev/null
+From stable+bounces-267213-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:18 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:28 -0400
+Subject: scripts/sorttable: Get start/stop_mcount_loc from ELF file directly
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <1f651dfe741838b94ed8088cc3429b65768893ea.1781809952.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 4acda8edefa1ce66d3de845f1c12745721cd14c3 ]
+
+The get_mcount_loc() does a cheesy trick to find the start_mcount_loc and
+stop_mcount_loc values. That trick is:
+
+ file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r");
+
+and
+
+ file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r");
+
+Those values are stored in the Elf symbol table. Use that to capture those
+values. Using the symbol table is more efficient and more robust. The
+above could fail if another variable had "start_mcount" or "stop_mcount"
+as part of its name.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162346.817157047@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 95 ++++++++++++++++++++++++----------------------------
+ 1 file changed, 45 insertions(+), 50 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -472,42 +472,41 @@ static void *sort_mcount_loc(void *arg)
+ }
+
+ /* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
+-static void get_mcount_loc(uint64_t *_start, uint64_t *_stop)
++static void get_mcount_loc(struct elf_mcount_loc *emloc, Elf_Shdr *symtab_sec,
++ const char *strtab)
+ {
+- FILE *file_start, *file_stop;
+- char start_buff[20];
+- char stop_buff[20];
+- int len = 0;
++ Elf_Sym *sym, *end_sym;
++ int symentsize = shdr_entsize(symtab_sec);
++ int found = 0;
++
++ sym = (void *)emloc->ehdr + shdr_offset(symtab_sec);
++ end_sym = (void *)sym + shdr_size(symtab_sec);
++
++ while (sym < end_sym) {
++ if (!strcmp(strtab + sym_name(sym), "__start_mcount_loc")) {
++ emloc->start_mcount_loc = sym_value(sym);
++ if (++found == 2)
++ break;
++ } else if (!strcmp(strtab + sym_name(sym), "__stop_mcount_loc")) {
++ emloc->stop_mcount_loc = sym_value(sym);
++ if (++found == 2)
++ break;
++ }
++ sym = (void *)sym + symentsize;
++ }
+
+- file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r");
+- if (!file_start) {
++ if (!emloc->start_mcount_loc) {
+ fprintf(stderr, "get start_mcount_loc error!");
+ return;
+ }
+
+- file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r");
+- if (!file_stop) {
++ if (!emloc->stop_mcount_loc) {
+ fprintf(stderr, "get stop_mcount_loc error!");
+- pclose(file_start);
+ return;
+ }
+-
+- while (fgets(start_buff, sizeof(start_buff), file_start) != NULL) {
+- len = strlen(start_buff);
+- start_buff[len - 1] = '\0';
+- }
+- *_start = strtoul(start_buff, NULL, 16);
+-
+- while (fgets(stop_buff, sizeof(stop_buff), file_stop) != NULL) {
+- len = strlen(stop_buff);
+- stop_buff[len - 1] = '\0';
+- }
+- *_stop = strtoul(stop_buff, NULL, 16);
+-
+- pclose(file_start);
+- pclose(file_stop);
+ }
+ #endif
++
+ static int do_sort(Elf_Ehdr *ehdr,
+ char const *const fname,
+ table_sort_t custom_sort)
+@@ -538,8 +537,6 @@ static int do_sort(Elf_Ehdr *ehdr,
+ unsigned int shstrndx;
+ #ifdef MCOUNT_SORT_ENABLED
+ struct elf_mcount_loc mstruct = {0};
+- uint64_t _start_mcount_loc = 0;
+- uint64_t _stop_mcount_loc = 0;
+ #endif
+ #ifdef UNWINDER_ORC_ENABLED
+ unsigned int orc_ip_size = 0;
+@@ -577,13 +574,8 @@ static int do_sort(Elf_Ehdr *ehdr,
+
+ #ifdef MCOUNT_SORT_ENABLED
+ /* locate the .init.data section in vmlinux */
+- if (!strcmp(secstrings + idx, ".init.data")) {
+- get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
+- mstruct.ehdr = ehdr;
++ if (!strcmp(secstrings + idx, ".init.data"))
+ mstruct.init_data_sec = shdr;
+- mstruct.start_mcount_loc = _start_mcount_loc;
+- mstruct.stop_mcount_loc = _stop_mcount_loc;
+- }
+ #endif
+
+ #ifdef UNWINDER_ORC_ENABLED
+@@ -627,23 +619,6 @@ static int do_sort(Elf_Ehdr *ehdr,
+ goto out;
+ }
+ #endif
+-
+-#ifdef MCOUNT_SORT_ENABLED
+- if (!mstruct.init_data_sec || !_start_mcount_loc || !_stop_mcount_loc) {
+- fprintf(stderr,
+- "incomplete mcount's sort in file: %s\n",
+- fname);
+- goto out;
+- }
+-
+- /* create thread to sort mcount_loc concurrently */
+- if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
+- fprintf(stderr,
+- "pthread_create mcount_sort_thread failed '%s': %s\n",
+- strerror(errno), fname);
+- goto out;
+- }
+-#endif
+ if (!extab_sec) {
+ fprintf(stderr, "no __ex_table in file: %s\n", fname);
+ goto out;
+@@ -663,6 +638,26 @@ static int do_sort(Elf_Ehdr *ehdr,
+ strtab = (const char *)ehdr + shdr_offset(strtab_sec);
+ symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec));
+
++#ifdef MCOUNT_SORT_ENABLED
++ mstruct.ehdr = ehdr;
++ get_mcount_loc(&mstruct, symtab_sec, strtab);
++
++ if (!mstruct.init_data_sec || !mstruct.start_mcount_loc || !mstruct.stop_mcount_loc) {
++ fprintf(stderr,
++ "incomplete mcount's sort in file: %s\n",
++ fname);
++ goto out;
++ }
++
++ /* create thread to sort mcount_loc concurrently */
++ if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
++ fprintf(stderr,
++ "pthread_create mcount_sort_thread failed '%s': %s\n",
++ strerror(errno), fname);
++ goto out;
++ }
++#endif
++
+ if (custom_sort) {
+ custom_sort(extab_image, shdr_size(extab_sec));
+ } else {
--- /dev/null
+From stable+bounces-267217-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:18 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:31 -0400
+Subject: scripts/sorttable: Have mcount rela sort use direct values
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <08a39ed51d7a5c5b62f0ddf7e54f99e955ec0b15.1781809961.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit a0265659322540d656727b9e132edfb6f06b6c1a ]
+
+The mcount_loc sorting for when the values are stored in the Elf_Rela
+entries uses the compare_extable() function to do the compares in the
+qsort(). That function does handle byte swapping if the machine being
+compiled for is a different endian than the host machine. But the
+sort_relocs() function sorts an array that pulled in the values from the
+Elf_Rela section and has already done the swapping.
+
+Create two new compare functions that will sort the direct values. One
+will sort 32 bit values and the other will sort the 64 bit value. One of
+these will be assigned to a compare_values function pointer and that will
+be used for sorting the Elf_Rela mcount values.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Alexander Gordeev <agordeev@linux.ibm.com>
+Link: https://lore.kernel.org/20250218200022.538888594@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 26 +++++++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -552,6 +552,28 @@ static void *sort_orctable(void *arg)
+
+ #ifdef MCOUNT_SORT_ENABLED
+
++static int compare_values_64(const void *a, const void *b)
++{
++ uint64_t av = *(uint64_t *)a;
++ uint64_t bv = *(uint64_t *)b;
++
++ if (av < bv)
++ return -1;
++ return av > bv;
++}
++
++static int compare_values_32(const void *a, const void *b)
++{
++ uint32_t av = *(uint32_t *)a;
++ uint32_t bv = *(uint32_t *)b;
++
++ if (av < bv)
++ return -1;
++ return av > bv;
++}
++
++static int (*compare_values)(const void *a, const void *b);
++
+ /* Only used for sorting mcount table */
+ static void rela_write_addend(Elf_Rela *rela, uint64_t val)
+ {
+@@ -583,6 +605,8 @@ static void *sort_relocs(Elf_Ehdr *ehdr,
+ void *vals;
+ void *ptr;
+
++ compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
++
+ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
+ shentsize = ehdr_shentsize(ehdr);
+
+@@ -640,7 +664,7 @@ static void *sort_relocs(Elf_Ehdr *ehdr,
+ }
+ }
+ count = ptr - vals;
+- qsort(vals, count / long_size, long_size, compare_extable);
++ qsort(vals, count / long_size, long_size, compare_values);
+
+ ptr = vals;
+ for (int i = 0; i < shnum; i++) {
--- /dev/null
+From prvs=262951c835=andrey.grodzovsky@crowdstrike.com Thu Jun 18 21:16:01 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:18 -0400
+Subject: scripts/sorttable: Have the ORC code use the _r() functions to read
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <8192a8bd228bb0d727a7c048b2ec034f9e9ccc8b.1781809920.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 66990c003306c240d570b3ba274ec4f68cf18c91 ]
+
+The ORC code reads the section information directly from the file. This
+currently works because the default read function is for 64bit little
+endian machines. But if for some reason that ever changes, this will
+break. Instead of having a surprise breakage, use the _r() functions that
+will read the values from the file properly.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162344.721480386@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -299,14 +299,14 @@ static int do_sort(Elf_Ehdr *ehdr,
+ #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+ /* locate the ORC unwind tables */
+ if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
+- orc_ip_size = s->sh_size;
++ orc_ip_size = _r(&s->sh_size);
+ g_orc_ip_table = (int *)((void *)ehdr +
+- s->sh_offset);
++ _r(&s->sh_offset));
+ }
+ if (!strcmp(secstrings + idx, ".orc_unwind")) {
+- orc_size = s->sh_size;
++ orc_size = _r(&s->sh_size);
+ g_orc_table = (struct orc_entry *)((void *)ehdr +
+- s->sh_offset);
++ _r(&s->sh_offset));
+ }
+ #endif
+ } /* for loop */
--- /dev/null
+From stable+bounces-267209-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:04 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:19 -0400
+Subject: scripts/sorttable: Make compare_extable() into two functions
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <355a7e43ce293504ed0abde5792b981a7c317d51.1781809922.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 7ffc0d0819f438779ed592e2e2e3576f43ce14f0 ]
+
+Instead of having the compare_extable() part of the sorttable.h header
+where it get's defined twice, since it is a very simple function, just
+define it twice in sorttable.c, and then it can use the proper read
+functions for the word size and endianess and the Elf_Addr macro can be
+removed from sorttable.h.
+
+Also add a micro optimization. Instead of:
+
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+
+That can be shorten to:
+
+ if (a < b)
+ return -1;
+ return a > b;
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162344.945299671@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 20 ++++++++++++++++++++
+ scripts/sorttable.h | 14 --------------
+ 2 files changed, 20 insertions(+), 14 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -173,6 +173,26 @@ static inline unsigned int get_secindex(
+ return r(&symtab_shndx_start[sym_offs]);
+ }
+
++static int compare_extable_32(const void *a, const void *b)
++{
++ Elf32_Addr av = r(a);
++ Elf32_Addr bv = r(b);
++
++ if (av < bv)
++ return -1;
++ return av > bv;
++}
++
++static int compare_extable_64(const void *a, const void *b)
++{
++ Elf64_Addr av = r8(a);
++ Elf64_Addr bv = r8(b);
++
++ if (av < bv)
++ return -1;
++ return av > bv;
++}
++
+ /* 32 bit and 64 bit are very similar */
+ #include "sorttable.h"
+ #define SORTTABLE_64
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -23,7 +23,6 @@
+ #undef sort_mcount_loc
+ #undef elf_mcount_loc
+ #undef do_sort
+-#undef Elf_Addr
+ #undef Elf_Ehdr
+ #undef Elf_Shdr
+ #undef Elf_Sym
+@@ -38,7 +37,6 @@
+ # define sort_mcount_loc sort_mcount_loc_64
+ # define elf_mcount_loc elf_mcount_loc_64
+ # define do_sort do_sort_64
+-# define Elf_Addr Elf64_Addr
+ # define Elf_Ehdr Elf64_Ehdr
+ # define Elf_Shdr Elf64_Shdr
+ # define Elf_Sym Elf64_Sym
+@@ -52,7 +50,6 @@
+ # define sort_mcount_loc sort_mcount_loc_32
+ # define elf_mcount_loc elf_mcount_loc_32
+ # define do_sort do_sort_32
+-# define Elf_Addr Elf32_Addr
+ # define Elf_Ehdr Elf32_Ehdr
+ # define Elf_Shdr Elf32_Shdr
+ # define Elf_Sym Elf32_Sym
+@@ -160,17 +157,6 @@ static void *sort_orctable(void *arg)
+ }
+ #endif
+
+-static int compare_extable(const void *a, const void *b)
+-{
+- Elf_Addr av = _r(a);
+- Elf_Addr bv = _r(b);
+-
+- if (av < bv)
+- return -1;
+- if (av > bv)
+- return 1;
+- return 0;
+-}
+ #ifdef MCOUNT_SORT_ENABLED
+ pthread_t mcount_sort_thread;
+
--- /dev/null
+From stable+bounces-267214-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:22 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:27 -0400
+Subject: scripts/sorttable: Move code from sorttable.h into sorttable.c
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <6a5629fb83fc0a77348e1ecbf8b31b50b42db27a.1781809949.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 58d87678a0f46c6120904b4326aaf5ebf4454c69 ]
+
+Instead of having the main code live in a header file and included twice
+with MACROs that define the Elf structures for 64 bit or 32 bit, move the
+code in the C file now that the Elf structures are defined in a union that
+has both. All accesses to the Elf structure fields are done through helper
+function pointers. If the file being parsed if for a 64 bit architecture,
+all the helper functions point to the 64 bit versions to retrieve the Elf
+fields. The same is true if the architecture is 32 bit, where the function
+pointers will point to the 32 bit helper functions.
+
+Note, when the value of a field can be either 32 bit or 64 bit, a 64 bit
+is always returned, as it works for the 32 bit code as well.
+
+This makes the code easier to read and maintain, and it now all exists in
+sorttable.c and sorttable.h may be removed.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Stephen Rothwell <sfr@canb.auug.org.au>
+Link: https://lore.kernel.org/20250107223217.6f7f96a5@gandalf.local.home
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 473 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ scripts/sorttable.h | 485 ----------------------------------------------------
+ 2 files changed, 460 insertions(+), 498 deletions(-)
+ delete mode 100644 scripts/sorttable.h
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -327,10 +327,423 @@ static inline void *get_index(void *star
+ return start + (entsize * index);
+ }
+
+-/* 32 bit and 64 bit are very similar */
+-#include "sorttable.h"
+-#define SORTTABLE_64
+-#include "sorttable.h"
++
++static int (*compare_extable)(const void *a, const void *b);
++static uint64_t (*ehdr_shoff)(Elf_Ehdr *ehdr);
++static uint16_t (*ehdr_shstrndx)(Elf_Ehdr *ehdr);
++static uint16_t (*ehdr_shentsize)(Elf_Ehdr *ehdr);
++static uint16_t (*ehdr_shnum)(Elf_Ehdr *ehdr);
++static uint64_t (*shdr_addr)(Elf_Shdr *shdr);
++static uint64_t (*shdr_offset)(Elf_Shdr *shdr);
++static uint64_t (*shdr_size)(Elf_Shdr *shdr);
++static uint64_t (*shdr_entsize)(Elf_Shdr *shdr);
++static uint32_t (*shdr_link)(Elf_Shdr *shdr);
++static uint32_t (*shdr_name)(Elf_Shdr *shdr);
++static uint32_t (*shdr_type)(Elf_Shdr *shdr);
++static uint8_t (*sym_type)(Elf_Sym *sym);
++static uint32_t (*sym_name)(Elf_Sym *sym);
++static uint64_t (*sym_value)(Elf_Sym *sym);
++static uint16_t (*sym_shndx)(Elf_Sym *sym);
++
++static int extable_ent_size;
++static int long_size;
++
++
++#ifdef UNWINDER_ORC_ENABLED
++/* ORC unwinder only support X86_64 */
++#include <asm/orc_types.h>
++
++#define ERRSTR_MAXSZ 256
++
++static char g_err[ERRSTR_MAXSZ];
++static int *g_orc_ip_table;
++static struct orc_entry *g_orc_table;
++
++static pthread_t orc_sort_thread;
++
++static inline unsigned long orc_ip(const int *ip)
++{
++ return (unsigned long)ip + *ip;
++}
++
++static int orc_sort_cmp(const void *_a, const void *_b)
++{
++ struct orc_entry *orc_a, *orc_b;
++ const int *a = g_orc_ip_table + *(int *)_a;
++ const int *b = g_orc_ip_table + *(int *)_b;
++ unsigned long a_val = orc_ip(a);
++ unsigned long b_val = orc_ip(b);
++
++ if (a_val > b_val)
++ return 1;
++ if (a_val < b_val)
++ return -1;
++
++ /*
++ * The "weak" section terminator entries need to always be on the left
++ * to ensure the lookup code skips them in favor of real entries.
++ * These terminator entries exist to handle any gaps created by
++ * whitelisted .o files which didn't get objtool generation.
++ */
++ orc_a = g_orc_table + (a - g_orc_ip_table);
++ orc_b = g_orc_table + (b - g_orc_ip_table);
++ if (orc_a->type == ORC_TYPE_UNDEFINED && orc_b->type == ORC_TYPE_UNDEFINED)
++ return 0;
++ return orc_a->type == ORC_TYPE_UNDEFINED ? -1 : 1;
++}
++
++static void *sort_orctable(void *arg)
++{
++ int i;
++ int *idxs = NULL;
++ int *tmp_orc_ip_table = NULL;
++ struct orc_entry *tmp_orc_table = NULL;
++ unsigned int *orc_ip_size = (unsigned int *)arg;
++ unsigned int num_entries = *orc_ip_size / sizeof(int);
++ unsigned int orc_size = num_entries * sizeof(struct orc_entry);
++
++ idxs = (int *)malloc(*orc_ip_size);
++ if (!idxs) {
++ snprintf(g_err, ERRSTR_MAXSZ, "malloc idxs: %s",
++ strerror(errno));
++ pthread_exit(g_err);
++ }
++
++ tmp_orc_ip_table = (int *)malloc(*orc_ip_size);
++ if (!tmp_orc_ip_table) {
++ snprintf(g_err, ERRSTR_MAXSZ, "malloc tmp_orc_ip_table: %s",
++ strerror(errno));
++ pthread_exit(g_err);
++ }
++
++ tmp_orc_table = (struct orc_entry *)malloc(orc_size);
++ if (!tmp_orc_table) {
++ snprintf(g_err, ERRSTR_MAXSZ, "malloc tmp_orc_table: %s",
++ strerror(errno));
++ pthread_exit(g_err);
++ }
++
++ /* initialize indices array, convert ip_table to absolute address */
++ for (i = 0; i < num_entries; i++) {
++ idxs[i] = i;
++ tmp_orc_ip_table[i] = g_orc_ip_table[i] + i * sizeof(int);
++ }
++ memcpy(tmp_orc_table, g_orc_table, orc_size);
++
++ qsort(idxs, num_entries, sizeof(int), orc_sort_cmp);
++
++ for (i = 0; i < num_entries; i++) {
++ if (idxs[i] == i)
++ continue;
++
++ /* convert back to relative address */
++ g_orc_ip_table[i] = tmp_orc_ip_table[idxs[i]] - i * sizeof(int);
++ g_orc_table[i] = tmp_orc_table[idxs[i]];
++ }
++
++ free(idxs);
++ free(tmp_orc_ip_table);
++ free(tmp_orc_table);
++ pthread_exit(NULL);
++}
++#endif
++
++#ifdef MCOUNT_SORT_ENABLED
++static pthread_t mcount_sort_thread;
++
++struct elf_mcount_loc {
++ Elf_Ehdr *ehdr;
++ Elf_Shdr *init_data_sec;
++ uint64_t start_mcount_loc;
++ uint64_t stop_mcount_loc;
++};
++
++/* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
++static void *sort_mcount_loc(void *arg)
++{
++ struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
++ uint64_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
++ + shdr_offset(emloc->init_data_sec);
++ uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
++ unsigned char *start_loc = (void *)emloc->ehdr + offset;
++
++ qsort(start_loc, count/long_size, long_size, compare_extable);
++ return NULL;
++}
++
++/* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
++static void get_mcount_loc(uint64_t *_start, uint64_t *_stop)
++{
++ FILE *file_start, *file_stop;
++ char start_buff[20];
++ char stop_buff[20];
++ int len = 0;
++
++ file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r");
++ if (!file_start) {
++ fprintf(stderr, "get start_mcount_loc error!");
++ return;
++ }
++
++ file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r");
++ if (!file_stop) {
++ fprintf(stderr, "get stop_mcount_loc error!");
++ pclose(file_start);
++ return;
++ }
++
++ while (fgets(start_buff, sizeof(start_buff), file_start) != NULL) {
++ len = strlen(start_buff);
++ start_buff[len - 1] = '\0';
++ }
++ *_start = strtoul(start_buff, NULL, 16);
++
++ while (fgets(stop_buff, sizeof(stop_buff), file_stop) != NULL) {
++ len = strlen(stop_buff);
++ stop_buff[len - 1] = '\0';
++ }
++ *_stop = strtoul(stop_buff, NULL, 16);
++
++ pclose(file_start);
++ pclose(file_stop);
++}
++#endif
++static int do_sort(Elf_Ehdr *ehdr,
++ char const *const fname,
++ table_sort_t custom_sort)
++{
++ int rc = -1;
++ Elf_Shdr *shdr_start;
++ Elf_Shdr *strtab_sec = NULL;
++ Elf_Shdr *symtab_sec = NULL;
++ Elf_Shdr *extab_sec = NULL;
++ Elf_Shdr *string_sec;
++ Elf_Sym *sym;
++ const Elf_Sym *symtab;
++ Elf32_Word *symtab_shndx = NULL;
++ Elf_Sym *sort_needed_sym = NULL;
++ Elf_Shdr *sort_needed_sec;
++ uint32_t *sort_needed_loc;
++ void *sym_start;
++ void *sym_end;
++ const char *secstrings;
++ const char *strtab;
++ char *extab_image;
++ int sort_need_index;
++ int symentsize;
++ int shentsize;
++ int idx;
++ int i;
++ unsigned int shnum;
++ unsigned int shstrndx;
++#ifdef MCOUNT_SORT_ENABLED
++ struct elf_mcount_loc mstruct = {0};
++ uint64_t _start_mcount_loc = 0;
++ uint64_t _stop_mcount_loc = 0;
++#endif
++#ifdef UNWINDER_ORC_ENABLED
++ unsigned int orc_ip_size = 0;
++ unsigned int orc_size = 0;
++ unsigned int orc_num_entries = 0;
++#endif
++
++ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
++ shentsize = ehdr_shentsize(ehdr);
++
++ shstrndx = ehdr_shstrndx(ehdr);
++ if (shstrndx == SHN_XINDEX)
++ shstrndx = shdr_link(shdr_start);
++ string_sec = get_index(shdr_start, shentsize, shstrndx);
++ secstrings = (const char *)ehdr + shdr_offset(string_sec);
++
++ shnum = ehdr_shnum(ehdr);
++ if (shnum == SHN_UNDEF)
++ shnum = shdr_size(shdr_start);
++
++ for (i = 0; i < shnum; i++) {
++ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
++
++ idx = shdr_name(shdr);
++ if (!strcmp(secstrings + idx, "__ex_table"))
++ extab_sec = shdr;
++ if (!strcmp(secstrings + idx, ".symtab"))
++ symtab_sec = shdr;
++ if (!strcmp(secstrings + idx, ".strtab"))
++ strtab_sec = shdr;
++
++ if (shdr_type(shdr) == SHT_SYMTAB_SHNDX)
++ symtab_shndx = (Elf32_Word *)((const char *)ehdr +
++ shdr_offset(shdr));
++
++#ifdef MCOUNT_SORT_ENABLED
++ /* locate the .init.data section in vmlinux */
++ if (!strcmp(secstrings + idx, ".init.data")) {
++ get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
++ mstruct.ehdr = ehdr;
++ mstruct.init_data_sec = shdr;
++ mstruct.start_mcount_loc = _start_mcount_loc;
++ mstruct.stop_mcount_loc = _stop_mcount_loc;
++ }
++#endif
++
++#ifdef UNWINDER_ORC_ENABLED
++ /* locate the ORC unwind tables */
++ if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
++ orc_ip_size = shdr_size(shdr);
++ g_orc_ip_table = (int *)((void *)ehdr +
++ shdr_offset(shdr));
++ }
++ if (!strcmp(secstrings + idx, ".orc_unwind")) {
++ orc_size = shdr_size(shdr);
++ g_orc_table = (struct orc_entry *)((void *)ehdr +
++ shdr_offset(shdr));
++ }
++#endif
++ } /* for loop */
++
++#ifdef UNWINDER_ORC_ENABLED
++ if (!g_orc_ip_table || !g_orc_table) {
++ fprintf(stderr,
++ "incomplete ORC unwind tables in file: %s\n", fname);
++ goto out;
++ }
++
++ orc_num_entries = orc_ip_size / sizeof(int);
++ if (orc_ip_size % sizeof(int) != 0 ||
++ orc_size % sizeof(struct orc_entry) != 0 ||
++ orc_num_entries != orc_size / sizeof(struct orc_entry)) {
++ fprintf(stderr,
++ "inconsistent ORC unwind table entries in file: %s\n",
++ fname);
++ goto out;
++ }
++
++ /* create thread to sort ORC unwind tables concurrently */
++ if (pthread_create(&orc_sort_thread, NULL,
++ sort_orctable, &orc_ip_size)) {
++ fprintf(stderr,
++ "pthread_create orc_sort_thread failed '%s': %s\n",
++ strerror(errno), fname);
++ goto out;
++ }
++#endif
++
++#ifdef MCOUNT_SORT_ENABLED
++ if (!mstruct.init_data_sec || !_start_mcount_loc || !_stop_mcount_loc) {
++ fprintf(stderr,
++ "incomplete mcount's sort in file: %s\n",
++ fname);
++ goto out;
++ }
++
++ /* create thread to sort mcount_loc concurrently */
++ if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
++ fprintf(stderr,
++ "pthread_create mcount_sort_thread failed '%s': %s\n",
++ strerror(errno), fname);
++ goto out;
++ }
++#endif
++ if (!extab_sec) {
++ fprintf(stderr, "no __ex_table in file: %s\n", fname);
++ goto out;
++ }
++
++ if (!symtab_sec) {
++ fprintf(stderr, "no .symtab in file: %s\n", fname);
++ goto out;
++ }
++
++ if (!strtab_sec) {
++ fprintf(stderr, "no .strtab in file: %s\n", fname);
++ goto out;
++ }
++
++ extab_image = (void *)ehdr + shdr_offset(extab_sec);
++ strtab = (const char *)ehdr + shdr_offset(strtab_sec);
++ symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec));
++
++ if (custom_sort) {
++ custom_sort(extab_image, shdr_size(extab_sec));
++ } else {
++ int num_entries = shdr_size(extab_sec) / extable_ent_size;
++ qsort(extab_image, num_entries,
++ extable_ent_size, compare_extable);
++ }
++
++ /* find the flag main_extable_sort_needed */
++ sym_start = (void *)ehdr + shdr_offset(symtab_sec);
++ sym_end = sym_start + shdr_size(symtab_sec);
++ symentsize = shdr_entsize(symtab_sec);
++
++ for (sym = sym_start; (void *)sym + symentsize < sym_end;
++ sym = (void *)sym + symentsize) {
++ if (sym_type(sym) != STT_OBJECT)
++ continue;
++ if (!strcmp(strtab + sym_name(sym),
++ "main_extable_sort_needed")) {
++ sort_needed_sym = sym;
++ break;
++ }
++ }
++
++ if (!sort_needed_sym) {
++ fprintf(stderr,
++ "no main_extable_sort_needed symbol in file: %s\n",
++ fname);
++ goto out;
++ }
++
++ sort_need_index = get_secindex(sym_shndx(sym),
++ ((void *)sort_needed_sym - (void *)symtab) / symentsize,
++ symtab_shndx);
++ sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
++ sort_needed_loc = (void *)ehdr +
++ shdr_offset(sort_needed_sec) +
++ sym_value(sort_needed_sym) - shdr_addr(sort_needed_sec);
++
++ /* extable has been sorted, clear the flag */
++ w(0, sort_needed_loc);
++ rc = 0;
++
++out:
++#ifdef UNWINDER_ORC_ENABLED
++ if (orc_sort_thread) {
++ void *retval = NULL;
++ /* wait for ORC tables sort done */
++ rc = pthread_join(orc_sort_thread, &retval);
++ if (rc) {
++ fprintf(stderr,
++ "pthread_join failed '%s': %s\n",
++ strerror(errno), fname);
++ } else if (retval) {
++ rc = -1;
++ fprintf(stderr,
++ "failed to sort ORC tables '%s': %s\n",
++ (char *)retval, fname);
++ }
++ }
++#endif
++
++#ifdef MCOUNT_SORT_ENABLED
++ if (mcount_sort_thread) {
++ void *retval = NULL;
++ /* wait for mcount sort done */
++ rc = pthread_join(mcount_sort_thread, &retval);
++ if (rc) {
++ fprintf(stderr,
++ "pthread_join failed '%s': %s\n",
++ strerror(errno), fname);
++ } else if (retval) {
++ rc = -1;
++ fprintf(stderr,
++ "failed to sort mcount '%s': %s\n",
++ (char *)retval, fname);
++ }
++ }
++#endif
++ return rc;
++}
+
+ static int compare_relative_table(const void *a, const void *b)
+ {
+@@ -399,7 +812,6 @@ static void sort_relative_table_with_dat
+
+ static int do_file(char const *const fname, void *addr)
+ {
+- int rc = -1;
+ Elf_Ehdr *ehdr = addr;
+ table_sort_t custom_sort = NULL;
+
+@@ -462,29 +874,64 @@ static int do_file(char const *const fna
+ r2(&ehdr->e32.e_shentsize) != sizeof(Elf32_Shdr)) {
+ fprintf(stderr,
+ "unrecognized ET_EXEC/ET_DYN file: %s\n", fname);
+- break;
++ return -1;
+ }
+- rc = do_sort_32(ehdr, fname, custom_sort);
++
++ compare_extable = compare_extable_32;
++ ehdr_shoff = ehdr32_shoff;
++ ehdr_shentsize = ehdr32_shentsize;
++ ehdr_shstrndx = ehdr32_shstrndx;
++ ehdr_shnum = ehdr32_shnum;
++ shdr_addr = shdr32_addr;
++ shdr_offset = shdr32_offset;
++ shdr_link = shdr32_link;
++ shdr_size = shdr32_size;
++ shdr_name = shdr32_name;
++ shdr_type = shdr32_type;
++ shdr_entsize = shdr32_entsize;
++ sym_type = sym32_type;
++ sym_name = sym32_name;
++ sym_value = sym32_value;
++ sym_shndx = sym32_shndx;
++ long_size = 4;
++ extable_ent_size = 8;
+ break;
+ case ELFCLASS64:
+- {
+ if (r2(&ehdr->e64.e_ehsize) != sizeof(Elf64_Ehdr) ||
+ r2(&ehdr->e64.e_shentsize) != sizeof(Elf64_Shdr)) {
+ fprintf(stderr,
+ "unrecognized ET_EXEC/ET_DYN file: %s\n",
+ fname);
+- break;
+- }
+- rc = do_sort_64(ehdr, fname, custom_sort);
++ return -1;
+ }
++
++ compare_extable = compare_extable_64;
++ ehdr_shoff = ehdr64_shoff;
++ ehdr_shentsize = ehdr64_shentsize;
++ ehdr_shstrndx = ehdr64_shstrndx;
++ ehdr_shnum = ehdr64_shnum;
++ shdr_addr = shdr64_addr;
++ shdr_offset = shdr64_offset;
++ shdr_link = shdr64_link;
++ shdr_size = shdr64_size;
++ shdr_name = shdr64_name;
++ shdr_type = shdr64_type;
++ shdr_entsize = shdr64_entsize;
++ sym_type = sym64_type;
++ sym_name = sym64_name;
++ sym_value = sym64_value;
++ sym_shndx = sym64_shndx;
++ long_size = 8;
++ extable_ent_size = 16;
++
+ break;
+ default:
+ fprintf(stderr, "unrecognized ELF class %d %s\n",
+ ehdr->e32.e_ident[EI_CLASS], fname);
+- break;
++ return -1;
+ }
+
+- return rc;
++ return do_sort(ehdr, fname, custom_sort);
+ }
+
+ int main(int argc, char *argv[])
+--- a/scripts/sorttable.h
++++ /dev/null
+@@ -1,485 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-only */
+-/*
+- * sorttable.h
+- *
+- * Added ORC unwind tables sort support and other updates:
+- * Copyright (C) 1999-2019 Alibaba Group Holding Limited. by:
+- * Shile Zhang <shile.zhang@linux.alibaba.com>
+- *
+- * Copyright 2011 - 2012 Cavium, Inc.
+- *
+- * Some of code was taken out of arch/x86/kernel/unwind_orc.c, written by:
+- * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
+- *
+- * Some of this code was taken out of recordmcount.h written by:
+- *
+- * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved.
+- * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
+- */
+-
+-#undef extable_ent_size
+-#undef compare_extable
+-#undef get_mcount_loc
+-#undef sort_mcount_loc
+-#undef elf_mcount_loc
+-#undef do_sort
+-#undef ehdr_shoff
+-#undef ehdr_shentsize
+-#undef ehdr_shstrndx
+-#undef ehdr_shnum
+-#undef shdr_addr
+-#undef shdr_offset
+-#undef shdr_link
+-#undef shdr_size
+-#undef shdr_name
+-#undef shdr_type
+-#undef shdr_entsize
+-#undef sym_type
+-#undef sym_name
+-#undef sym_value
+-#undef sym_shndx
+-#undef long_size
+-
+-#ifdef SORTTABLE_64
+-# define extable_ent_size 16
+-# define compare_extable compare_extable_64
+-# define get_mcount_loc get_mcount_loc_64
+-# define sort_mcount_loc sort_mcount_loc_64
+-# define elf_mcount_loc elf_mcount_loc_64
+-# define do_sort do_sort_64
+-# define ehdr_shoff ehdr64_shoff
+-# define ehdr_shentsize ehdr64_shentsize
+-# define ehdr_shstrndx ehdr64_shstrndx
+-# define ehdr_shnum ehdr64_shnum
+-# define shdr_addr shdr64_addr
+-# define shdr_offset shdr64_offset
+-# define shdr_link shdr64_link
+-# define shdr_size shdr64_size
+-# define shdr_name shdr64_name
+-# define shdr_type shdr64_type
+-# define shdr_entsize shdr64_entsize
+-# define sym_type sym64_type
+-# define sym_name sym64_name
+-# define sym_value sym64_value
+-# define sym_shndx sym64_shndx
+-# define long_size 8
+-#else
+-# define extable_ent_size 8
+-# define compare_extable compare_extable_32
+-# define get_mcount_loc get_mcount_loc_32
+-# define sort_mcount_loc sort_mcount_loc_32
+-# define elf_mcount_loc elf_mcount_loc_32
+-# define do_sort do_sort_32
+-# define ehdr_shoff ehdr32_shoff
+-# define ehdr_shentsize ehdr32_shentsize
+-# define ehdr_shstrndx ehdr32_shstrndx
+-# define ehdr_shnum ehdr32_shnum
+-# define shdr_addr shdr32_addr
+-# define shdr_offset shdr32_offset
+-# define shdr_link shdr32_link
+-# define shdr_size shdr32_size
+-# define shdr_name shdr32_name
+-# define shdr_type shdr32_type
+-# define shdr_entsize shdr32_entsize
+-# define sym_type sym32_type
+-# define sym_name sym32_name
+-# define sym_value sym32_value
+-# define sym_shndx sym32_shndx
+-# define long_size 4
+-#endif
+-
+-#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+-/* ORC unwinder only support X86_64 */
+-#include <asm/orc_types.h>
+-
+-#define ERRSTR_MAXSZ 256
+-
+-char g_err[ERRSTR_MAXSZ];
+-int *g_orc_ip_table;
+-struct orc_entry *g_orc_table;
+-
+-pthread_t orc_sort_thread;
+-
+-static inline unsigned long orc_ip(const int *ip)
+-{
+- return (unsigned long)ip + *ip;
+-}
+-
+-static int orc_sort_cmp(const void *_a, const void *_b)
+-{
+- struct orc_entry *orc_a, *orc_b;
+- const int *a = g_orc_ip_table + *(int *)_a;
+- const int *b = g_orc_ip_table + *(int *)_b;
+- unsigned long a_val = orc_ip(a);
+- unsigned long b_val = orc_ip(b);
+-
+- if (a_val > b_val)
+- return 1;
+- if (a_val < b_val)
+- return -1;
+-
+- /*
+- * The "weak" section terminator entries need to always be on the left
+- * to ensure the lookup code skips them in favor of real entries.
+- * These terminator entries exist to handle any gaps created by
+- * whitelisted .o files which didn't get objtool generation.
+- */
+- orc_a = g_orc_table + (a - g_orc_ip_table);
+- orc_b = g_orc_table + (b - g_orc_ip_table);
+- if (orc_a->type == ORC_TYPE_UNDEFINED && orc_b->type == ORC_TYPE_UNDEFINED)
+- return 0;
+- return orc_a->type == ORC_TYPE_UNDEFINED ? -1 : 1;
+-}
+-
+-static void *sort_orctable(void *arg)
+-{
+- int i;
+- int *idxs = NULL;
+- int *tmp_orc_ip_table = NULL;
+- struct orc_entry *tmp_orc_table = NULL;
+- unsigned int *orc_ip_size = (unsigned int *)arg;
+- unsigned int num_entries = *orc_ip_size / sizeof(int);
+- unsigned int orc_size = num_entries * sizeof(struct orc_entry);
+-
+- idxs = (int *)malloc(*orc_ip_size);
+- if (!idxs) {
+- snprintf(g_err, ERRSTR_MAXSZ, "malloc idxs: %s",
+- strerror(errno));
+- pthread_exit(g_err);
+- }
+-
+- tmp_orc_ip_table = (int *)malloc(*orc_ip_size);
+- if (!tmp_orc_ip_table) {
+- snprintf(g_err, ERRSTR_MAXSZ, "malloc tmp_orc_ip_table: %s",
+- strerror(errno));
+- pthread_exit(g_err);
+- }
+-
+- tmp_orc_table = (struct orc_entry *)malloc(orc_size);
+- if (!tmp_orc_table) {
+- snprintf(g_err, ERRSTR_MAXSZ, "malloc tmp_orc_table: %s",
+- strerror(errno));
+- pthread_exit(g_err);
+- }
+-
+- /* initialize indices array, convert ip_table to absolute address */
+- for (i = 0; i < num_entries; i++) {
+- idxs[i] = i;
+- tmp_orc_ip_table[i] = g_orc_ip_table[i] + i * sizeof(int);
+- }
+- memcpy(tmp_orc_table, g_orc_table, orc_size);
+-
+- qsort(idxs, num_entries, sizeof(int), orc_sort_cmp);
+-
+- for (i = 0; i < num_entries; i++) {
+- if (idxs[i] == i)
+- continue;
+-
+- /* convert back to relative address */
+- g_orc_ip_table[i] = tmp_orc_ip_table[idxs[i]] - i * sizeof(int);
+- g_orc_table[i] = tmp_orc_table[idxs[i]];
+- }
+-
+- free(idxs);
+- free(tmp_orc_ip_table);
+- free(tmp_orc_table);
+- pthread_exit(NULL);
+-}
+-#endif
+-
+-#ifdef MCOUNT_SORT_ENABLED
+-pthread_t mcount_sort_thread;
+-
+-struct elf_mcount_loc {
+- Elf_Ehdr *ehdr;
+- Elf_Shdr *init_data_sec;
+- uint64_t start_mcount_loc;
+- uint64_t stop_mcount_loc;
+-};
+-
+-/* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
+-static void *sort_mcount_loc(void *arg)
+-{
+- struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
+- uint64_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
+- + shdr_offset(emloc->init_data_sec);
+- uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
+- unsigned char *start_loc = (void *)emloc->ehdr + offset;
+-
+- qsort(start_loc, count/long_size, long_size, compare_extable);
+- return NULL;
+-}
+-
+-/* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
+-static void get_mcount_loc(uint64_t *_start, uint64_t *_stop)
+-{
+- FILE *file_start, *file_stop;
+- char start_buff[20];
+- char stop_buff[20];
+- int len = 0;
+-
+- file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r");
+- if (!file_start) {
+- fprintf(stderr, "get start_mcount_loc error!");
+- return;
+- }
+-
+- file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r");
+- if (!file_stop) {
+- fprintf(stderr, "get stop_mcount_loc error!");
+- pclose(file_start);
+- return;
+- }
+-
+- while (fgets(start_buff, sizeof(start_buff), file_start) != NULL) {
+- len = strlen(start_buff);
+- start_buff[len - 1] = '\0';
+- }
+- *_start = strtoul(start_buff, NULL, 16);
+-
+- while (fgets(stop_buff, sizeof(stop_buff), file_stop) != NULL) {
+- len = strlen(stop_buff);
+- stop_buff[len - 1] = '\0';
+- }
+- *_stop = strtoul(stop_buff, NULL, 16);
+-
+- pclose(file_start);
+- pclose(file_stop);
+-}
+-#endif
+-static int do_sort(Elf_Ehdr *ehdr,
+- char const *const fname,
+- table_sort_t custom_sort)
+-{
+- int rc = -1;
+- Elf_Shdr *shdr_start;
+- Elf_Shdr *strtab_sec = NULL;
+- Elf_Shdr *symtab_sec = NULL;
+- Elf_Shdr *extab_sec = NULL;
+- Elf_Shdr *string_sec;
+- Elf_Sym *sym;
+- const Elf_Sym *symtab;
+- Elf32_Word *symtab_shndx = NULL;
+- Elf_Sym *sort_needed_sym = NULL;
+- Elf_Shdr *sort_needed_sec;
+- uint32_t *sort_needed_loc;
+- void *sym_start;
+- void *sym_end;
+- const char *secstrings;
+- const char *strtab;
+- char *extab_image;
+- int sort_need_index;
+- int symentsize;
+- int shentsize;
+- int idx;
+- int i;
+- unsigned int shnum;
+- unsigned int shstrndx;
+-#ifdef MCOUNT_SORT_ENABLED
+- struct elf_mcount_loc mstruct = {0};
+- uint64_t _start_mcount_loc = 0;
+- uint64_t _stop_mcount_loc = 0;
+-#endif
+-#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+- unsigned int orc_ip_size = 0;
+- unsigned int orc_size = 0;
+- unsigned int orc_num_entries = 0;
+-#endif
+-
+- shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
+- shentsize = ehdr_shentsize(ehdr);
+-
+- shstrndx = ehdr_shstrndx(ehdr);
+- if (shstrndx == SHN_XINDEX)
+- shstrndx = shdr_link(shdr_start);
+- string_sec = get_index(shdr_start, shentsize, shstrndx);
+- secstrings = (const char *)ehdr + shdr_offset(string_sec);
+-
+- shnum = ehdr_shnum(ehdr);
+- if (shnum == SHN_UNDEF)
+- shnum = shdr_size(shdr_start);
+-
+- for (i = 0; i < shnum; i++) {
+- Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
+-
+- idx = shdr_name(shdr);
+- if (!strcmp(secstrings + idx, "__ex_table"))
+- extab_sec = shdr;
+- if (!strcmp(secstrings + idx, ".symtab"))
+- symtab_sec = shdr;
+- if (!strcmp(secstrings + idx, ".strtab"))
+- strtab_sec = shdr;
+-
+- if (shdr_type(shdr) == SHT_SYMTAB_SHNDX)
+- symtab_shndx = (Elf32_Word *)((const char *)ehdr +
+- shdr_offset(shdr));
+-
+-#ifdef MCOUNT_SORT_ENABLED
+- /* locate the .init.data section in vmlinux */
+- if (!strcmp(secstrings + idx, ".init.data")) {
+- get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
+- mstruct.ehdr = ehdr;
+- mstruct.init_data_sec = shdr;
+- mstruct.start_mcount_loc = _start_mcount_loc;
+- mstruct.stop_mcount_loc = _stop_mcount_loc;
+- }
+-#endif
+-
+-#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+- /* locate the ORC unwind tables */
+- if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
+- orc_ip_size = shdr_size(shdr);
+- g_orc_ip_table = (int *)((void *)ehdr +
+- shdr_offset(shdr));
+- }
+- if (!strcmp(secstrings + idx, ".orc_unwind")) {
+- orc_size = shdr_size(shdr);
+- g_orc_table = (struct orc_entry *)((void *)ehdr +
+- shdr_offset(shdr));
+- }
+-#endif
+- } /* for loop */
+-
+-#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+- if (!g_orc_ip_table || !g_orc_table) {
+- fprintf(stderr,
+- "incomplete ORC unwind tables in file: %s\n", fname);
+- goto out;
+- }
+-
+- orc_num_entries = orc_ip_size / sizeof(int);
+- if (orc_ip_size % sizeof(int) != 0 ||
+- orc_size % sizeof(struct orc_entry) != 0 ||
+- orc_num_entries != orc_size / sizeof(struct orc_entry)) {
+- fprintf(stderr,
+- "inconsistent ORC unwind table entries in file: %s\n",
+- fname);
+- goto out;
+- }
+-
+- /* create thread to sort ORC unwind tables concurrently */
+- if (pthread_create(&orc_sort_thread, NULL,
+- sort_orctable, &orc_ip_size)) {
+- fprintf(stderr,
+- "pthread_create orc_sort_thread failed '%s': %s\n",
+- strerror(errno), fname);
+- goto out;
+- }
+-#endif
+-
+-#ifdef MCOUNT_SORT_ENABLED
+- if (!mstruct.init_data_sec || !_start_mcount_loc || !_stop_mcount_loc) {
+- fprintf(stderr,
+- "incomplete mcount's sort in file: %s\n",
+- fname);
+- goto out;
+- }
+-
+- /* create thread to sort mcount_loc concurrently */
+- if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
+- fprintf(stderr,
+- "pthread_create mcount_sort_thread failed '%s': %s\n",
+- strerror(errno), fname);
+- goto out;
+- }
+-#endif
+- if (!extab_sec) {
+- fprintf(stderr, "no __ex_table in file: %s\n", fname);
+- goto out;
+- }
+-
+- if (!symtab_sec) {
+- fprintf(stderr, "no .symtab in file: %s\n", fname);
+- goto out;
+- }
+-
+- if (!strtab_sec) {
+- fprintf(stderr, "no .strtab in file: %s\n", fname);
+- goto out;
+- }
+-
+- extab_image = (void *)ehdr + shdr_offset(extab_sec);
+- strtab = (const char *)ehdr + shdr_offset(strtab_sec);
+- symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec));
+-
+- if (custom_sort) {
+- custom_sort(extab_image, shdr_size(extab_sec));
+- } else {
+- int num_entries = shdr_size(extab_sec) / extable_ent_size;
+- qsort(extab_image, num_entries,
+- extable_ent_size, compare_extable);
+- }
+-
+- /* find the flag main_extable_sort_needed */
+- sym_start = (void *)ehdr + shdr_offset(symtab_sec);
+- sym_end = sym_start + shdr_size(symtab_sec);
+- symentsize = shdr_entsize(symtab_sec);
+-
+- for (sym = sym_start; (void *)sym + symentsize < sym_end;
+- sym = (void *)sym + symentsize) {
+- if (sym_type(sym) != STT_OBJECT)
+- continue;
+- if (!strcmp(strtab + sym_name(sym),
+- "main_extable_sort_needed")) {
+- sort_needed_sym = sym;
+- break;
+- }
+- }
+-
+- if (!sort_needed_sym) {
+- fprintf(stderr,
+- "no main_extable_sort_needed symbol in file: %s\n",
+- fname);
+- goto out;
+- }
+-
+- sort_need_index = get_secindex(sym_shndx(sym),
+- ((void *)sort_needed_sym - (void *)symtab) / symentsize,
+- symtab_shndx);
+- sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
+- sort_needed_loc = (void *)ehdr +
+- shdr_offset(sort_needed_sec) +
+- sym_value(sort_needed_sym) - shdr_addr(sort_needed_sec);
+-
+- /* extable has been sorted, clear the flag */
+- w(0, sort_needed_loc);
+- rc = 0;
+-
+-out:
+-#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+- if (orc_sort_thread) {
+- void *retval = NULL;
+- /* wait for ORC tables sort done */
+- rc = pthread_join(orc_sort_thread, &retval);
+- if (rc) {
+- fprintf(stderr,
+- "pthread_join failed '%s': %s\n",
+- strerror(errno), fname);
+- } else if (retval) {
+- rc = -1;
+- fprintf(stderr,
+- "failed to sort ORC tables '%s': %s\n",
+- (char *)retval, fname);
+- }
+- }
+-#endif
+-
+-#ifdef MCOUNT_SORT_ENABLED
+- if (mcount_sort_thread) {
+- void *retval = NULL;
+- /* wait for mcount sort done */
+- rc = pthread_join(mcount_sort_thread, &retval);
+- if (rc) {
+- fprintf(stderr,
+- "pthread_join failed '%s': %s\n",
+- strerror(errno), fname);
+- } else if (retval) {
+- rc = -1;
+- fprintf(stderr,
+- "failed to sort mcount '%s': %s\n",
+- (char *)retval, fname);
+- }
+- }
+-#endif
+- return rc;
+-}
--- /dev/null
+From prvs=262951c835=andrey.grodzovsky@crowdstrike.com Thu Jun 18 21:16:00 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:17 -0400
+Subject: scripts/sorttable: Remove unneeded Elf_Rel
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <984bf8d32a9080de6819dede14055b154f6d619d.1781809917.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 6f2c2f93a190467cebd6ebd03feb49514fead5ca ]
+
+The code had references to initialize the Elf_Rel relocation tables, but
+it was never used. Remove it.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162344.515342233@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.h | 23 ++---------------------
+ 1 file changed, 2 insertions(+), 21 deletions(-)
+
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -26,7 +26,6 @@
+ #undef Elf_Addr
+ #undef Elf_Ehdr
+ #undef Elf_Shdr
+-#undef Elf_Rel
+ #undef Elf_Sym
+ #undef ELF_ST_TYPE
+ #undef uint_t
+@@ -42,7 +41,6 @@
+ # define Elf_Addr Elf64_Addr
+ # define Elf_Ehdr Elf64_Ehdr
+ # define Elf_Shdr Elf64_Shdr
+-# define Elf_Rel Elf64_Rel
+ # define Elf_Sym Elf64_Sym
+ # define ELF_ST_TYPE ELF64_ST_TYPE
+ # define uint_t uint64_t
+@@ -57,7 +55,6 @@
+ # define Elf_Addr Elf32_Addr
+ # define Elf_Ehdr Elf32_Ehdr
+ # define Elf_Shdr Elf32_Shdr
+-# define Elf_Rel Elf32_Rel
+ # define Elf_Sym Elf32_Sym
+ # define ELF_ST_TYPE ELF32_ST_TYPE
+ # define uint_t uint32_t
+@@ -248,14 +245,10 @@ static int do_sort(Elf_Ehdr *ehdr,
+ Elf32_Word *symtab_shndx = NULL;
+ Elf_Sym *sort_needed_sym = NULL;
+ Elf_Shdr *sort_needed_sec;
+- Elf_Rel *relocs = NULL;
+- int relocs_size = 0;
+ uint32_t *sort_needed_loc;
+ const char *secstrings;
+ const char *strtab;
+ char *extab_image;
+- int extab_index = 0;
+- int i;
+ int idx;
+ unsigned int shnum;
+ unsigned int shstrndx;
+@@ -279,23 +272,15 @@ static int do_sort(Elf_Ehdr *ehdr,
+ if (shnum == SHN_UNDEF)
+ shnum = _r(&shdr[0].sh_size);
+
+- for (i = 0, s = shdr; s < shdr + shnum; i++, s++) {
++ for (s = shdr; s < shdr + shnum; s++) {
+ idx = r(&s->sh_name);
+- if (!strcmp(secstrings + idx, "__ex_table")) {
++ if (!strcmp(secstrings + idx, "__ex_table"))
+ extab_sec = s;
+- extab_index = i;
+- }
+ if (!strcmp(secstrings + idx, ".symtab"))
+ symtab_sec = s;
+ if (!strcmp(secstrings + idx, ".strtab"))
+ strtab_sec = s;
+
+- if ((r(&s->sh_type) == SHT_REL ||
+- r(&s->sh_type) == SHT_RELA) &&
+- r(&s->sh_info) == extab_index) {
+- relocs = (void *)ehdr + _r(&s->sh_offset);
+- relocs_size = _r(&s->sh_size);
+- }
+ if (r(&s->sh_type) == SHT_SYMTAB_SHNDX)
+ symtab_shndx = (Elf32_Word *)((const char *)ehdr +
+ _r(&s->sh_offset));
+@@ -397,10 +382,6 @@ static int do_sort(Elf_Ehdr *ehdr,
+ extable_ent_size, compare_extable);
+ }
+
+- /* If there were relocations, we no longer need them. */
+- if (relocs)
+- memset(relocs, 0, relocs_size);
+-
+ /* find the flag main_extable_sort_needed */
+ for (sym = (void *)ehdr + _r(&symtab_sec->sh_offset);
+ sym < sym + _r(&symtab_sec->sh_size) / sizeof(Elf_Sym);
--- /dev/null
+From prvs=262951c835=andrey.grodzovsky@crowdstrike.com Thu Jun 18 21:15:58 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:15 -0400
+Subject: scripts/sorttable: Remove unused macro defines
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <f1cd060da6cd86ab48f12660a85f7059f3aa016c.1781809913.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 28b24394c6e9a3166fcb4480cba054562526657c ]
+
+The code of sorttable.h was copied from the recordmcount.h which defined
+a bunch of Elf MACROs so that they could be used between 32bit and 64bit
+functions. But there's several MACROs that sorttable.h does not use but
+was copied over. Remove them to clean up the code.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162344.128870118@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.h | 27 ---------------------------
+ 1 file changed, 27 deletions(-)
+
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -27,19 +27,10 @@
+ #undef Elf_Ehdr
+ #undef Elf_Shdr
+ #undef Elf_Rel
+-#undef Elf_Rela
+ #undef Elf_Sym
+-#undef ELF_R_SYM
+-#undef Elf_r_sym
+-#undef ELF_R_INFO
+-#undef Elf_r_info
+-#undef ELF_ST_BIND
+ #undef ELF_ST_TYPE
+-#undef fn_ELF_R_SYM
+-#undef fn_ELF_R_INFO
+ #undef uint_t
+ #undef _r
+-#undef _w
+
+ #ifdef SORTTABLE_64
+ # define extable_ent_size 16
+@@ -52,19 +43,10 @@
+ # define Elf_Ehdr Elf64_Ehdr
+ # define Elf_Shdr Elf64_Shdr
+ # define Elf_Rel Elf64_Rel
+-# define Elf_Rela Elf64_Rela
+ # define Elf_Sym Elf64_Sym
+-# define ELF_R_SYM ELF64_R_SYM
+-# define Elf_r_sym Elf64_r_sym
+-# define ELF_R_INFO ELF64_R_INFO
+-# define Elf_r_info Elf64_r_info
+-# define ELF_ST_BIND ELF64_ST_BIND
+ # define ELF_ST_TYPE ELF64_ST_TYPE
+-# define fn_ELF_R_SYM fn_ELF64_R_SYM
+-# define fn_ELF_R_INFO fn_ELF64_R_INFO
+ # define uint_t uint64_t
+ # define _r r8
+-# define _w w8
+ #else
+ # define extable_ent_size 8
+ # define compare_extable compare_extable_32
+@@ -76,19 +58,10 @@
+ # define Elf_Ehdr Elf32_Ehdr
+ # define Elf_Shdr Elf32_Shdr
+ # define Elf_Rel Elf32_Rel
+-# define Elf_Rela Elf32_Rela
+ # define Elf_Sym Elf32_Sym
+-# define ELF_R_SYM ELF32_R_SYM
+-# define Elf_r_sym Elf32_r_sym
+-# define ELF_R_INFO ELF32_R_INFO
+-# define Elf_r_info Elf32_r_info
+-# define ELF_ST_BIND ELF32_ST_BIND
+ # define ELF_ST_TYPE ELF32_ST_TYPE
+-# define fn_ELF_R_SYM fn_ELF32_R_SYM
+-# define fn_ELF_R_INFO fn_ELF32_R_INFO
+ # define uint_t uint32_t
+ # define _r r
+-# define _w w
+ #endif
+
+ #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
--- /dev/null
+From stable+bounces-267208-greg=kroah.com@vger.kernel.org Thu Jun 18 21:15:59 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:16 -0400
+Subject: scripts/sorttable: Remove unused write functions
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <b4b7893593e70929d097a18d2838814bee99b631.1781809915.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 4f48a28b37d594dab38092514a42ae9f4b781553 ]
+
+The code of sorttable.h was copied from the recordmcount.h which defined
+various write functions for different sizes (2, 4, 8 byte lengths). But
+sorttable only uses the 4 byte writes. Remove the extra versions as they
+are not used.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162344.314385504@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 26 --------------------------
+ 1 file changed, 26 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -68,8 +68,6 @@ static uint32_t (*r)(const uint32_t *);
+ static uint16_t (*r2)(const uint16_t *);
+ static uint64_t (*r8)(const uint64_t *);
+ static void (*w)(uint32_t, uint32_t *);
+-static void (*w2)(uint16_t, uint16_t *);
+-static void (*w8)(uint64_t, uint64_t *);
+ typedef void (*table_sort_t)(char *, int);
+
+ /*
+@@ -146,31 +144,11 @@ static void wbe(uint32_t val, uint32_t *
+ put_unaligned_be32(val, x);
+ }
+
+-static void w2be(uint16_t val, uint16_t *x)
+-{
+- put_unaligned_be16(val, x);
+-}
+-
+-static void w8be(uint64_t val, uint64_t *x)
+-{
+- put_unaligned_be64(val, x);
+-}
+-
+ static void wle(uint32_t val, uint32_t *x)
+ {
+ put_unaligned_le32(val, x);
+ }
+
+-static void w2le(uint16_t val, uint16_t *x)
+-{
+- put_unaligned_le16(val, x);
+-}
+-
+-static void w8le(uint64_t val, uint64_t *x)
+-{
+- put_unaligned_le64(val, x);
+-}
+-
+ /*
+ * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
+ * the way to -256..-1, to avoid conflicting with real section
+@@ -277,16 +255,12 @@ static int do_file(char const *const fna
+ r2 = r2le;
+ r8 = r8le;
+ w = wle;
+- w2 = w2le;
+- w8 = w8le;
+ break;
+ case ELFDATA2MSB:
+ r = rbe;
+ r2 = r2be;
+ r8 = r8be;
+ w = wbe;
+- w2 = w2be;
+- w8 = w8be;
+ break;
+ default:
+ fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
--- /dev/null
+From stable+bounces-267210-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:06 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:21 -0400
+Subject: scripts/sorttable: Replace Elf_Shdr Macro with a union
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <a5f3a078f5a3b599df8fb883345b4aff36b7d3d8.1781809929.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 545f6cf8f4c9a268e0bab2637f1d279679befdbf ]
+
+In order to remove the double #include of sorttable.h for 64 and 32 bit
+to create duplicate functions for both, replace the Elf_Shdr macro with a
+union that defines both Elf64_Shdr and Elf32_Shdr, with field e64 for the
+64bit version, and e32 for the 32bit version.
+
+It can then use the macro etype to get the proper value.
+
+This will eventually be replaced with just single functions that can
+handle both 32bit and 64bit ELF parsing.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162345.339462681@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 10 +++++++
+ scripts/sorttable.h | 74 ++++++++++++++++++++++++++++------------------------
+ 2 files changed, 51 insertions(+), 33 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -69,6 +69,11 @@ typedef union {
+ Elf64_Ehdr e64;
+ } Elf_Ehdr;
+
++typedef union {
++ Elf32_Shdr e32;
++ Elf64_Shdr e64;
++} Elf_Shdr;
++
+ static uint32_t (*r)(const uint32_t *);
+ static uint16_t (*r2)(const uint16_t *);
+ static uint64_t (*r8)(const uint64_t *);
+@@ -198,6 +203,11 @@ static int compare_extable_64(const void
+ return av > bv;
+ }
+
++static inline void *get_index(void *start, int entsize, int index)
++{
++ return start + (entsize * index);
++}
++
+ /* 32 bit and 64 bit are very similar */
+ #include "sorttable.h"
+ #define SORTTABLE_64
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -23,7 +23,6 @@
+ #undef sort_mcount_loc
+ #undef elf_mcount_loc
+ #undef do_sort
+-#undef Elf_Shdr
+ #undef Elf_Sym
+ #undef ELF_ST_TYPE
+ #undef uint_t
+@@ -37,7 +36,6 @@
+ # define sort_mcount_loc sort_mcount_loc_64
+ # define elf_mcount_loc elf_mcount_loc_64
+ # define do_sort do_sort_64
+-# define Elf_Shdr Elf64_Shdr
+ # define Elf_Sym Elf64_Sym
+ # define ELF_ST_TYPE ELF64_ST_TYPE
+ # define uint_t uint64_t
+@@ -50,7 +48,6 @@
+ # define sort_mcount_loc sort_mcount_loc_32
+ # define elf_mcount_loc elf_mcount_loc_32
+ # define do_sort do_sort_32
+-# define Elf_Shdr Elf32_Shdr
+ # define Elf_Sym Elf32_Sym
+ # define ELF_ST_TYPE ELF32_ST_TYPE
+ # define uint_t uint32_t
+@@ -171,8 +168,8 @@ struct elf_mcount_loc {
+ static void *sort_mcount_loc(void *arg)
+ {
+ struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
+- uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->sh_addr)
+- + _r(&(emloc->init_data_sec)->sh_offset);
++ uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->etype.sh_addr)
++ + _r(&(emloc->init_data_sec)->etype.sh_offset);
+ uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
+ unsigned char *start_loc = (void *)emloc->ehdr + offset;
+
+@@ -222,10 +219,11 @@ static int do_sort(Elf_Ehdr *ehdr,
+ table_sort_t custom_sort)
+ {
+ int rc = -1;
+- Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
++ Elf_Shdr *shdr_start;
+ Elf_Shdr *strtab_sec = NULL;
+ Elf_Shdr *symtab_sec = NULL;
+ Elf_Shdr *extab_sec = NULL;
++ Elf_Shdr *string_sec;
+ Elf_Sym *sym;
+ const Elf_Sym *symtab;
+ Elf32_Word *symtab_shndx = NULL;
+@@ -235,7 +233,10 @@ static int do_sort(Elf_Ehdr *ehdr,
+ const char *secstrings;
+ const char *strtab;
+ char *extab_image;
++ int sort_need_index;
++ int shentsize;
+ int idx;
++ int i;
+ unsigned int shnum;
+ unsigned int shstrndx;
+ #ifdef MCOUNT_SORT_ENABLED
+@@ -249,34 +250,40 @@ static int do_sort(Elf_Ehdr *ehdr,
+ unsigned int orc_num_entries = 0;
+ #endif
+
++ shdr_start = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
++ shentsize = r2(&ehdr->etype.e_shentsize);
++
+ shstrndx = r2(&ehdr->etype.e_shstrndx);
+ if (shstrndx == SHN_XINDEX)
+- shstrndx = r(&shdr[0].sh_link);
+- secstrings = (const char *)ehdr + _r(&shdr[shstrndx].sh_offset);
++ shstrndx = r(&shdr_start->etype.sh_link);
++ string_sec = get_index(shdr_start, shentsize, shstrndx);
++ secstrings = (const char *)ehdr + _r(&string_sec->etype.sh_offset);
+
+ shnum = r2(&ehdr->etype.e_shnum);
+ if (shnum == SHN_UNDEF)
+- shnum = _r(&shdr[0].sh_size);
++ shnum = _r(&shdr_start->etype.sh_size);
++
++ for (i = 0; i < shnum; i++) {
++ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
+
+- for (s = shdr; s < shdr + shnum; s++) {
+- idx = r(&s->sh_name);
++ idx = r(&shdr->etype.sh_name);
+ if (!strcmp(secstrings + idx, "__ex_table"))
+- extab_sec = s;
++ extab_sec = shdr;
+ if (!strcmp(secstrings + idx, ".symtab"))
+- symtab_sec = s;
++ symtab_sec = shdr;
+ if (!strcmp(secstrings + idx, ".strtab"))
+- strtab_sec = s;
++ strtab_sec = shdr;
+
+- if (r(&s->sh_type) == SHT_SYMTAB_SHNDX)
++ if (r(&shdr->etype.sh_type) == SHT_SYMTAB_SHNDX)
+ symtab_shndx = (Elf32_Word *)((const char *)ehdr +
+- _r(&s->sh_offset));
++ _r(&shdr->etype.sh_offset));
+
+ #ifdef MCOUNT_SORT_ENABLED
+ /* locate the .init.data section in vmlinux */
+ if (!strcmp(secstrings + idx, ".init.data")) {
+ get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
+ mstruct.ehdr = ehdr;
+- mstruct.init_data_sec = s;
++ mstruct.init_data_sec = shdr;
+ mstruct.start_mcount_loc = _start_mcount_loc;
+ mstruct.stop_mcount_loc = _stop_mcount_loc;
+ }
+@@ -285,14 +292,14 @@ static int do_sort(Elf_Ehdr *ehdr,
+ #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+ /* locate the ORC unwind tables */
+ if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
+- orc_ip_size = _r(&s->sh_size);
++ orc_ip_size = _r(&shdr->etype.sh_size);
+ g_orc_ip_table = (int *)((void *)ehdr +
+- _r(&s->sh_offset));
++ _r(&shdr->etype.sh_offset));
+ }
+ if (!strcmp(secstrings + idx, ".orc_unwind")) {
+- orc_size = _r(&s->sh_size);
++ orc_size = _r(&shdr->etype.sh_size);
+ g_orc_table = (struct orc_entry *)((void *)ehdr +
+- _r(&s->sh_offset));
++ _r(&shdr->etype.sh_offset));
+ }
+ #endif
+ } /* for loop */
+@@ -355,22 +362,22 @@ static int do_sort(Elf_Ehdr *ehdr,
+ goto out;
+ }
+
+- extab_image = (void *)ehdr + _r(&extab_sec->sh_offset);
+- strtab = (const char *)ehdr + _r(&strtab_sec->sh_offset);
++ extab_image = (void *)ehdr + _r(&extab_sec->etype.sh_offset);
++ strtab = (const char *)ehdr + _r(&strtab_sec->etype.sh_offset);
+ symtab = (const Elf_Sym *)((const char *)ehdr +
+- _r(&symtab_sec->sh_offset));
++ _r(&symtab_sec->etype.sh_offset));
+
+ if (custom_sort) {
+- custom_sort(extab_image, _r(&extab_sec->sh_size));
++ custom_sort(extab_image, _r(&extab_sec->etype.sh_size));
+ } else {
+- int num_entries = _r(&extab_sec->sh_size) / extable_ent_size;
++ int num_entries = _r(&extab_sec->etype.sh_size) / extable_ent_size;
+ qsort(extab_image, num_entries,
+ extable_ent_size, compare_extable);
+ }
+
+ /* find the flag main_extable_sort_needed */
+- for (sym = (void *)ehdr + _r(&symtab_sec->sh_offset);
+- sym < sym + _r(&symtab_sec->sh_size) / sizeof(Elf_Sym);
++ for (sym = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
++ sym < sym + _r(&symtab_sec->etype.sh_size) / sizeof(Elf_Sym);
+ sym++) {
+ if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
+ continue;
+@@ -388,13 +395,14 @@ static int do_sort(Elf_Ehdr *ehdr,
+ goto out;
+ }
+
+- sort_needed_sec = &shdr[get_secindex(r2(&sym->st_shndx),
+- sort_needed_sym - symtab,
+- symtab_shndx)];
++ sort_need_index = get_secindex(r2(&sym->st_shndx),
++ sort_needed_sym - symtab,
++ symtab_shndx);
++ sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
+ sort_needed_loc = (void *)ehdr +
+- _r(&sort_needed_sec->sh_offset) +
++ _r(&sort_needed_sec->etype.sh_offset) +
+ _r(&sort_needed_sym->st_value) -
+- _r(&sort_needed_sec->sh_addr);
++ _r(&sort_needed_sec->etype.sh_addr);
+
+ /* extable has been sorted, clear the flag */
+ w(0, sort_needed_loc);
--- /dev/null
+From stable+bounces-267215-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:21 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:29 -0400
+Subject: scripts/sorttable: Use a structure of function pointers for elf helpers
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <9d973657ac0dc3be317cf635d9d78cca849760f1.1781809954.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 1e5f6771c247b28135307058d2cfe3b0153733dc ]
+
+Instead of having a series of function pointers that gets assigned to the
+Elf64 or Elf32 versions, put them all into a single structure and use
+that. Add the helper function that chooses the structure into the macros
+that build the different versions of the elf functions.
+
+Link: https://lore.kernel.org/all/CAHk-=wiafEyX7UgOeZgvd6fvuByE5WXUPh9599kwOc_d-pdeug@mail.gmail.com/
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Stephen Rothwell <sfr@canb.auug.org.au>
+Link: https://lore.kernel.org/20250110075459.13d4b94c@gandalf.local.home
+Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 175 +++++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 118 insertions(+), 57 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -85,6 +85,25 @@ static uint64_t (*r8)(const uint64_t *);
+ static void (*w)(uint32_t, uint32_t *);
+ typedef void (*table_sort_t)(char *, int);
+
++static struct elf_funcs {
++ int (*compare_extable)(const void *a, const void *b);
++ uint64_t (*ehdr_shoff)(Elf_Ehdr *ehdr);
++ uint16_t (*ehdr_shstrndx)(Elf_Ehdr *ehdr);
++ uint16_t (*ehdr_shentsize)(Elf_Ehdr *ehdr);
++ uint16_t (*ehdr_shnum)(Elf_Ehdr *ehdr);
++ uint64_t (*shdr_addr)(Elf_Shdr *shdr);
++ uint64_t (*shdr_offset)(Elf_Shdr *shdr);
++ uint64_t (*shdr_size)(Elf_Shdr *shdr);
++ uint64_t (*shdr_entsize)(Elf_Shdr *shdr);
++ uint32_t (*shdr_link)(Elf_Shdr *shdr);
++ uint32_t (*shdr_name)(Elf_Shdr *shdr);
++ uint32_t (*shdr_type)(Elf_Shdr *shdr);
++ uint8_t (*sym_type)(Elf_Sym *sym);
++ uint32_t (*sym_name)(Elf_Sym *sym);
++ uint64_t (*sym_value)(Elf_Sym *sym);
++ uint16_t (*sym_shndx)(Elf_Sym *sym);
++} e;
++
+ static uint64_t ehdr64_shoff(Elf_Ehdr *ehdr)
+ {
+ return r8(&ehdr->e64.e_shoff);
+@@ -95,6 +114,11 @@ static uint64_t ehdr32_shoff(Elf_Ehdr *e
+ return r(&ehdr->e32.e_shoff);
+ }
+
++static uint64_t ehdr_shoff(Elf_Ehdr *ehdr)
++{
++ return e.ehdr_shoff(ehdr);
++}
++
+ #define EHDR_HALF(fn_name) \
+ static uint16_t ehdr64_##fn_name(Elf_Ehdr *ehdr) \
+ { \
+@@ -104,6 +128,11 @@ static uint16_t ehdr64_##fn_name(Elf_Ehd
+ static uint16_t ehdr32_##fn_name(Elf_Ehdr *ehdr) \
+ { \
+ return r2(&ehdr->e32.e_##fn_name); \
++} \
++ \
++static uint16_t ehdr_##fn_name(Elf_Ehdr *ehdr) \
++{ \
++ return e.ehdr_##fn_name(ehdr); \
+ }
+
+ EHDR_HALF(shentsize)
+@@ -119,6 +148,11 @@ static uint32_t shdr64_##fn_name(Elf_Shd
+ static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
+ { \
+ return r(&shdr->e32.sh_##fn_name); \
++} \
++ \
++static uint32_t shdr_##fn_name(Elf_Shdr *shdr) \
++{ \
++ return e.shdr_##fn_name(shdr); \
+ }
+
+ #define SHDR_ADDR(fn_name) \
+@@ -130,6 +164,11 @@ static uint64_t shdr64_##fn_name(Elf_Shd
+ static uint64_t shdr32_##fn_name(Elf_Shdr *shdr) \
+ { \
+ return r(&shdr->e32.sh_##fn_name); \
++} \
++ \
++static uint64_t shdr_##fn_name(Elf_Shdr *shdr) \
++{ \
++ return e.shdr_##fn_name(shdr); \
+ }
+
+ #define SHDR_WORD(fn_name) \
+@@ -141,6 +180,10 @@ static uint32_t shdr64_##fn_name(Elf_Shd
+ static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
+ { \
+ return r(&shdr->e32.sh_##fn_name); \
++} \
++static uint32_t shdr_##fn_name(Elf_Shdr *shdr) \
++{ \
++ return e.shdr_##fn_name(shdr); \
+ }
+
+ SHDR_ADDR(addr)
+@@ -161,6 +204,11 @@ static uint64_t sym64_##fn_name(Elf_Sym
+ static uint64_t sym32_##fn_name(Elf_Sym *sym) \
+ { \
+ return r(&sym->e32.st_##fn_name); \
++} \
++ \
++static uint64_t sym_##fn_name(Elf_Sym *sym) \
++{ \
++ return e.sym_##fn_name(sym); \
+ }
+
+ #define SYM_WORD(fn_name) \
+@@ -172,6 +220,11 @@ static uint32_t sym64_##fn_name(Elf_Sym
+ static uint32_t sym32_##fn_name(Elf_Sym *sym) \
+ { \
+ return r(&sym->e32.st_##fn_name); \
++} \
++ \
++static uint32_t sym_##fn_name(Elf_Sym *sym) \
++{ \
++ return e.sym_##fn_name(sym); \
+ }
+
+ #define SYM_HALF(fn_name) \
+@@ -183,6 +236,11 @@ static uint16_t sym64_##fn_name(Elf_Sym
+ static uint16_t sym32_##fn_name(Elf_Sym *sym) \
+ { \
+ return r2(&sym->e32.st_##fn_name); \
++} \
++ \
++static uint16_t sym_##fn_name(Elf_Sym *sym) \
++{ \
++ return e.sym_##fn_name(sym); \
+ }
+
+ static uint8_t sym64_type(Elf_Sym *sym)
+@@ -195,6 +253,11 @@ static uint8_t sym32_type(Elf_Sym *sym)
+ return ELF32_ST_TYPE(sym->e32.st_info);
+ }
+
++static uint8_t sym_type(Elf_Sym *sym)
++{
++ return e.sym_type(sym);
++}
++
+ SYM_ADDR(value)
+ SYM_WORD(name)
+ SYM_HALF(shndx)
+@@ -322,29 +385,16 @@ static int compare_extable_64(const void
+ return av > bv;
+ }
+
++static int compare_extable(const void *a, const void *b)
++{
++ return e.compare_extable(a, b);
++}
++
+ static inline void *get_index(void *start, int entsize, int index)
+ {
+ return start + (entsize * index);
+ }
+
+-
+-static int (*compare_extable)(const void *a, const void *b);
+-static uint64_t (*ehdr_shoff)(Elf_Ehdr *ehdr);
+-static uint16_t (*ehdr_shstrndx)(Elf_Ehdr *ehdr);
+-static uint16_t (*ehdr_shentsize)(Elf_Ehdr *ehdr);
+-static uint16_t (*ehdr_shnum)(Elf_Ehdr *ehdr);
+-static uint64_t (*shdr_addr)(Elf_Shdr *shdr);
+-static uint64_t (*shdr_offset)(Elf_Shdr *shdr);
+-static uint64_t (*shdr_size)(Elf_Shdr *shdr);
+-static uint64_t (*shdr_entsize)(Elf_Shdr *shdr);
+-static uint32_t (*shdr_link)(Elf_Shdr *shdr);
+-static uint32_t (*shdr_name)(Elf_Shdr *shdr);
+-static uint32_t (*shdr_type)(Elf_Shdr *shdr);
+-static uint8_t (*sym_type)(Elf_Sym *sym);
+-static uint32_t (*sym_name)(Elf_Sym *sym);
+-static uint64_t (*sym_value)(Elf_Sym *sym);
+-static uint16_t (*sym_shndx)(Elf_Sym *sym);
+-
+ static int extable_ent_size;
+ static int long_size;
+
+@@ -864,7 +914,30 @@ static int do_file(char const *const fna
+ }
+
+ switch (ehdr->e32.e_ident[EI_CLASS]) {
+- case ELFCLASS32:
++ case ELFCLASS32: {
++ struct elf_funcs efuncs = {
++ .compare_extable = compare_extable_32,
++ .ehdr_shoff = ehdr32_shoff,
++ .ehdr_shentsize = ehdr32_shentsize,
++ .ehdr_shstrndx = ehdr32_shstrndx,
++ .ehdr_shnum = ehdr32_shnum,
++ .shdr_addr = shdr32_addr,
++ .shdr_offset = shdr32_offset,
++ .shdr_link = shdr32_link,
++ .shdr_size = shdr32_size,
++ .shdr_name = shdr32_name,
++ .shdr_type = shdr32_type,
++ .shdr_entsize = shdr32_entsize,
++ .sym_type = sym32_type,
++ .sym_name = sym32_name,
++ .sym_value = sym32_value,
++ .sym_shndx = sym32_shndx,
++ };
++
++ e = efuncs;
++ long_size = 4;
++ extable_ent_size = 8;
++
+ if (r2(&ehdr->e32.e_ehsize) != sizeof(Elf32_Ehdr) ||
+ r2(&ehdr->e32.e_shentsize) != sizeof(Elf32_Shdr)) {
+ fprintf(stderr,
+@@ -872,26 +945,32 @@ static int do_file(char const *const fna
+ return -1;
+ }
+
+- compare_extable = compare_extable_32;
+- ehdr_shoff = ehdr32_shoff;
+- ehdr_shentsize = ehdr32_shentsize;
+- ehdr_shstrndx = ehdr32_shstrndx;
+- ehdr_shnum = ehdr32_shnum;
+- shdr_addr = shdr32_addr;
+- shdr_offset = shdr32_offset;
+- shdr_link = shdr32_link;
+- shdr_size = shdr32_size;
+- shdr_name = shdr32_name;
+- shdr_type = shdr32_type;
+- shdr_entsize = shdr32_entsize;
+- sym_type = sym32_type;
+- sym_name = sym32_name;
+- sym_value = sym32_value;
+- sym_shndx = sym32_shndx;
+- long_size = 4;
+- extable_ent_size = 8;
++ }
+ break;
+- case ELFCLASS64:
++ case ELFCLASS64: {
++ struct elf_funcs efuncs = {
++ .compare_extable = compare_extable_64,
++ .ehdr_shoff = ehdr64_shoff,
++ .ehdr_shentsize = ehdr64_shentsize,
++ .ehdr_shstrndx = ehdr64_shstrndx,
++ .ehdr_shnum = ehdr64_shnum,
++ .shdr_addr = shdr64_addr,
++ .shdr_offset = shdr64_offset,
++ .shdr_link = shdr64_link,
++ .shdr_size = shdr64_size,
++ .shdr_name = shdr64_name,
++ .shdr_type = shdr64_type,
++ .shdr_entsize = shdr64_entsize,
++ .sym_type = sym64_type,
++ .sym_name = sym64_name,
++ .sym_value = sym64_value,
++ .sym_shndx = sym64_shndx,
++ };
++
++ e = efuncs;
++ long_size = 8;
++ extable_ent_size = 16;
++
+ if (r2(&ehdr->e64.e_ehsize) != sizeof(Elf64_Ehdr) ||
+ r2(&ehdr->e64.e_shentsize) != sizeof(Elf64_Shdr)) {
+ fprintf(stderr,
+@@ -900,25 +979,7 @@ static int do_file(char const *const fna
+ return -1;
+ }
+
+- compare_extable = compare_extable_64;
+- ehdr_shoff = ehdr64_shoff;
+- ehdr_shentsize = ehdr64_shentsize;
+- ehdr_shstrndx = ehdr64_shstrndx;
+- ehdr_shnum = ehdr64_shnum;
+- shdr_addr = shdr64_addr;
+- shdr_offset = shdr64_offset;
+- shdr_link = shdr64_link;
+- shdr_size = shdr64_size;
+- shdr_name = shdr64_name;
+- shdr_type = shdr64_type;
+- shdr_entsize = shdr64_entsize;
+- sym_type = sym64_type;
+- sym_name = sym64_name;
+- sym_value = sym64_value;
+- sym_shndx = sym64_shndx;
+- long_size = 8;
+- extable_ent_size = 16;
+-
++ }
+ break;
+ default:
+ fprintf(stderr, "unrecognized ELF class %d %s\n",
--- /dev/null
+From stable+bounces-267225-greg=kroah.com@vger.kernel.org Thu Jun 18 21:17:50 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:39 -0400
+Subject: scripts/sorttable: Use normal sort if theres no relocs in the mcount section
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <d99230ce57a655ac9f9478d03717763f9c16b896.1781809985.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 46514b3c2c17c67cefe84b0c1a59e0aaf6093131 ]
+
+When ARM 64 is compiled with gcc, the mcount_loc section will be filled
+with zeros and the addresses will be located in the Elf_Rela sections. To
+sort the mcount_loc section, the addresses from the Elf_Rela need to be
+placed into an array and that is sorted.
+
+But when ARM 64 is compiled with clang, it does it the same way as other
+architectures and leaves the addresses as is in the mcount_loc section.
+
+To handle both cases, ARM 64 will first try to sort the Elf_Rela section,
+and if it doesn't find any functions, it will then fall back to the
+sorting of the addresses in the mcount_loc section itself.
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/20250225182054.648398403@goodmis.org
+Fixes: b3d09d06e052 ("arm64: scripts/sorttable: Implement sorting mcount_loc at boot for arm64")
+Reported-by: "Arnd Bergmann" <arnd@arndb.de>
+Tested-by: Nathan Chancellor <nathan@kernel.org>
+Closes: https://lore.kernel.org/all/893cd8f1-8585-4d25-bf0f-4197bf872465@app.fastmail.com/
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -827,9 +827,14 @@ static void *sort_mcount_loc(void *arg)
+ pthread_exit(m_err);
+ }
+
+- if (sort_reloc)
++ if (sort_reloc) {
+ count = fill_relocs(vals, size, ehdr, emloc->start_mcount_loc);
+- else
++ /* gcc may use relocs to save the addresses, but clang does not. */
++ if (!count) {
++ count = fill_addrs(vals, size, start_loc);
++ sort_reloc = 0;
++ }
++ } else
+ count = fill_addrs(vals, size, start_loc);
+
+ if (count < 0) {
--- /dev/null
+From stable+bounces-267212-greg=kroah.com@vger.kernel.org Thu Jun 18 21:16:14 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:26 -0400
+Subject: scripts/sorttable: Use uint64_t for mcount sorting
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <e6b5f67222359383911a6f5e6b28cd192cb6a18a.1781809947.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 1b649e6ab8dc9188d82c64069493afe66ca0edad ]
+
+The mcount sorting defines uint_t to uint64_t on 64bit architectures and
+uint32_t on 32bit architectures. It can work with just using uint64_t as
+that will hold the values of both, and they are not used to point into the
+ELF file.
+
+sizeof(uint_t) is used for defining the size of the mcount_loc section.
+Instead of using a type, define long_size and use that instead. This will
+allow the header code to be moved into the C file as generic functions and
+not need to include sorttable.h twice, once for 64bit and once for 32bit.
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/20250105162346.373528925@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.h | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -23,7 +23,6 @@
+ #undef sort_mcount_loc
+ #undef elf_mcount_loc
+ #undef do_sort
+-#undef uint_t
+ #undef ehdr_shoff
+ #undef ehdr_shentsize
+ #undef ehdr_shstrndx
+@@ -39,6 +38,7 @@
+ #undef sym_name
+ #undef sym_value
+ #undef sym_shndx
++#undef long_size
+
+ #ifdef SORTTABLE_64
+ # define extable_ent_size 16
+@@ -47,7 +47,6 @@
+ # define sort_mcount_loc sort_mcount_loc_64
+ # define elf_mcount_loc elf_mcount_loc_64
+ # define do_sort do_sort_64
+-# define uint_t uint64_t
+ # define ehdr_shoff ehdr64_shoff
+ # define ehdr_shentsize ehdr64_shentsize
+ # define ehdr_shstrndx ehdr64_shstrndx
+@@ -63,6 +62,7 @@
+ # define sym_name sym64_name
+ # define sym_value sym64_value
+ # define sym_shndx sym64_shndx
++# define long_size 8
+ #else
+ # define extable_ent_size 8
+ # define compare_extable compare_extable_32
+@@ -70,7 +70,6 @@
+ # define sort_mcount_loc sort_mcount_loc_32
+ # define elf_mcount_loc elf_mcount_loc_32
+ # define do_sort do_sort_32
+-# define uint_t uint32_t
+ # define ehdr_shoff ehdr32_shoff
+ # define ehdr_shentsize ehdr32_shentsize
+ # define ehdr_shstrndx ehdr32_shstrndx
+@@ -86,6 +85,7 @@
+ # define sym_name sym32_name
+ # define sym_value sym32_value
+ # define sym_shndx sym32_shndx
++# define long_size 4
+ #endif
+
+ #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+@@ -193,25 +193,25 @@ pthread_t mcount_sort_thread;
+ struct elf_mcount_loc {
+ Elf_Ehdr *ehdr;
+ Elf_Shdr *init_data_sec;
+- uint_t start_mcount_loc;
+- uint_t stop_mcount_loc;
++ uint64_t start_mcount_loc;
++ uint64_t stop_mcount_loc;
+ };
+
+ /* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
+ static void *sort_mcount_loc(void *arg)
+ {
+ struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
+- uint_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
++ uint64_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
+ + shdr_offset(emloc->init_data_sec);
+- uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
++ uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
+ unsigned char *start_loc = (void *)emloc->ehdr + offset;
+
+- qsort(start_loc, count/sizeof(uint_t), sizeof(uint_t), compare_extable);
++ qsort(start_loc, count/long_size, long_size, compare_extable);
+ return NULL;
+ }
+
+ /* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
+-static void get_mcount_loc(uint_t *_start, uint_t *_stop)
++static void get_mcount_loc(uint64_t *_start, uint64_t *_stop)
+ {
+ FILE *file_start, *file_stop;
+ char start_buff[20];
+@@ -277,8 +277,8 @@ static int do_sort(Elf_Ehdr *ehdr,
+ unsigned int shstrndx;
+ #ifdef MCOUNT_SORT_ENABLED
+ struct elf_mcount_loc mstruct = {0};
+- uint_t _start_mcount_loc = 0;
+- uint_t _stop_mcount_loc = 0;
++ uint64_t _start_mcount_loc = 0;
++ uint64_t _stop_mcount_loc = 0;
+ #endif
+ #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
+ unsigned int orc_ip_size = 0;
--- /dev/null
+From stable+bounces-267219-greg=kroah.com@vger.kernel.org Thu Jun 18 21:17:01 2026
+From: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Date: Thu, 18 Jun 2026 16:15:33 -0400
+Subject: scripts/sorttable: Zero out weak functions in mcount_loc table
+To: <stable@vger.kernel.org>
+Cc: <gregkh@linuxfoundation.org>, <sashal@kernel.org>, <rostedt@goodmis.org>, <vmalik@redhat.com>, <jmarchan@redhat.com>, <martin.kelly@crowdstrike.com>, <justin.deschamp@crowdstrike.com>, <linux-open-source@crowdstrike.com>
+Message-ID: <ec4eda957478678f39fc5cfe27a29ab345e1bb51.1781809966.git.andrey.grodzovsky@crowdstrike.com>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit ef378c3b8233855497a414b9d67bf22592c928a4 ]
+
+When a function is annotated as "weak" and is overridden, the code is not
+removed. If it is traced, the fentry/mcount location in the weak function
+will be referenced by the "__mcount_loc" section. This will then be added
+to the available_filter_functions list. Since only the address of the
+functions are listed, to find the name to show, a search of kallsyms is
+used.
+
+Since kallsyms will return the function by simply finding the function
+that the address is after but before the next function, an address of a
+weak function will show up as the function before it. This is because
+kallsyms does not save names of weak functions. This has caused issues in
+the past, as now the traced weak function will be listed in
+available_filter_functions with the name of the function before it.
+
+At best, this will cause the previous function's name to be listed twice.
+At worse, if the previous function was marked notrace, it will now show up
+as a function that can be traced. Note that it only shows up that it can
+be traced but will not be if enabled, which causes confusion.
+
+ https://lore.kernel.org/all/20220412094923.0abe90955e5db486b7bca279@kernel.org/
+
+The commit b39181f7c6907 ("ftrace: Add FTRACE_MCOUNT_MAX_OFFSET to avoid
+adding weak function") was a workaround to this by checking the function
+address before printing its name. If the address was too far from the
+function given by the name then instead of printing the name it would
+print: __ftrace_invalid_address___<invalid-offset>
+
+The real issue is that these invalid addresses are listed in the ftrace
+table look up which available_filter_functions is derived from. A place
+holder must be listed in that file because set_ftrace_filter may take a
+series of indexes into that file instead of names to be able to do O(1)
+lookups to enable filtering (many tools use this method).
+
+Even if kallsyms saved the size of the function, it does not remove the
+need of having these place holders. The real solution is to not add a weak
+function into the ftrace table in the first place.
+
+To solve this, the sorttable.c code that sorts the mcount regions during
+the build is modified to take a "nm -S vmlinux" input, sort it, and any
+function listed in the mcount_loc section that is not within a boundary of
+the function list given by nm is considered a weak function and is zeroed
+out.
+
+Note, this does not mean they will remain zero when booting as KASLR
+will still shift those addresses. To handle this, the entries in the
+mcount_loc section will be ignored if they are zero or match the
+kaslr_offset() value.
+
+Before:
+
+ ~# grep __ftrace_invalid_address___ /sys/kernel/tracing/available_filter_functions | wc -l
+ 551
+
+After:
+
+ ~# grep __ftrace_invalid_address___ /sys/kernel/tracing/available_filter_functions | wc -l
+ 0
+
+Cc: bpf <bpf@vger.kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Martin Kelly <martin.kelly@crowdstrike.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Alexander Gordeev <agordeev@linux.ibm.com>
+Link: https://lore.kernel.org/20250218200022.883095980@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/ftrace.c | 6 +-
+ scripts/link-vmlinux.sh | 4 +
+ scripts/sorttable.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 134 insertions(+), 4 deletions(-)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -7048,6 +7048,7 @@ static int ftrace_process_locs(struct mo
+ unsigned long count;
+ unsigned long *p;
+ unsigned long addr;
++ unsigned long kaslr;
+ unsigned long flags = 0; /* Shut up gcc */
+ int ret = -ENOMEM;
+
+@@ -7096,6 +7097,9 @@ static int ftrace_process_locs(struct mo
+ ftrace_pages->next = start_pg;
+ }
+
++ /* For zeroed locations that were shifted for core kernel */
++ kaslr = !mod ? kaslr_offset() : 0;
++
+ p = start;
+ pg = start_pg;
+ while (p < end) {
+@@ -7107,7 +7111,7 @@ static int ftrace_process_locs(struct mo
+ * object files to satisfy alignments.
+ * Skip any NULL pointers.
+ */
+- if (!addr) {
++ if (!addr || addr == kaslr) {
+ skipped++;
+ continue;
+ }
+--- a/scripts/link-vmlinux.sh
++++ b/scripts/link-vmlinux.sh
+@@ -173,12 +173,14 @@ mksysmap()
+
+ sorttable()
+ {
+- ${objtree}/scripts/sorttable ${1}
++ ${NM} -S ${1} > .tmp_vmlinux.nm-sort
++ ${objtree}/scripts/sorttable -s .tmp_vmlinux.nm-sort ${1}
+ }
+
+ cleanup()
+ {
+ rm -f .btf.*
++ rm -f .tmp_vmlinux.nm-sort
+ rm -f System.map
+ rm -f vmlinux
+ rm -f vmlinux.map
+--- a/scripts/sorttable.c
++++ b/scripts/sorttable.c
+@@ -580,6 +580,98 @@ static void rela_write_addend(Elf_Rela *
+ e.rela_write_addend(rela, val);
+ }
+
++struct func_info {
++ uint64_t addr;
++ uint64_t size;
++};
++
++/* List of functions created by: nm -S vmlinux */
++static struct func_info *function_list;
++static int function_list_size;
++
++/* Allocate functions in 1k blocks */
++#define FUNC_BLK_SIZE 1024
++#define FUNC_BLK_MASK (FUNC_BLK_SIZE - 1)
++
++static int add_field(uint64_t addr, uint64_t size)
++{
++ struct func_info *fi;
++ int fsize = function_list_size;
++
++ if (!(fsize & FUNC_BLK_MASK)) {
++ fsize += FUNC_BLK_SIZE;
++ fi = realloc(function_list, fsize * sizeof(struct func_info));
++ if (!fi)
++ return -1;
++ function_list = fi;
++ }
++ fi = &function_list[function_list_size++];
++ fi->addr = addr;
++ fi->size = size;
++ return 0;
++}
++
++/* Only return match if the address lies inside the function size */
++static int cmp_func_addr(const void *K, const void *A)
++{
++ uint64_t key = *(const uint64_t *)K;
++ const struct func_info *a = A;
++
++ if (key < a->addr)
++ return -1;
++ return key >= a->addr + a->size;
++}
++
++/* Find the function in function list that is bounded by the function size */
++static int find_func(uint64_t key)
++{
++ return bsearch(&key, function_list, function_list_size,
++ sizeof(struct func_info), cmp_func_addr) != NULL;
++}
++
++static int cmp_funcs(const void *A, const void *B)
++{
++ const struct func_info *a = A;
++ const struct func_info *b = B;
++
++ if (a->addr < b->addr)
++ return -1;
++ return a->addr > b->addr;
++}
++
++static int parse_symbols(const char *fname)
++{
++ FILE *fp;
++ char addr_str[20]; /* Only need 17, but round up to next int size */
++ char size_str[20];
++ char type;
++
++ fp = fopen(fname, "r");
++ if (!fp) {
++ perror(fname);
++ return -1;
++ }
++
++ while (fscanf(fp, "%16s %16s %c %*s\n", addr_str, size_str, &type) == 3) {
++ uint64_t addr;
++ uint64_t size;
++
++ /* Only care about functions */
++ if (type != 't' && type != 'T' && type != 'W')
++ continue;
++
++ addr = strtoull(addr_str, NULL, 16);
++ size = strtoull(size_str, NULL, 16);
++ if (add_field(addr, size) < 0)
++ return -1;
++ }
++ fclose(fp);
++
++ qsort(function_list, function_list_size, sizeof(struct func_info), cmp_funcs);
++
++ return 0;
++}
++
+ static pthread_t mcount_sort_thread;
+ static bool sort_reloc;
+
+@@ -752,6 +844,21 @@ static void *sort_mcount_loc(void *arg)
+ goto out;
+ }
+
++ /* zero out any locations not found by function list */
++ if (function_list_size) {
++ for (void *ptr = vals; ptr < vals + size; ptr += long_size) {
++ uint64_t key;
++
++ key = long_size == 4 ? r((uint32_t *)ptr) : r8((uint64_t *)ptr);
++ if (!find_func(key)) {
++ if (long_size == 4)
++ *(uint32_t *)ptr = 0;
++ else
++ *(uint64_t *)ptr = 0;
++ }
++ }
++ }
++
+ compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
+
+ qsort(vals, count, long_size, compare_values);
+@@ -801,6 +908,8 @@ static void get_mcount_loc(struct elf_mc
+ return;
+ }
+ }
++#else /* MCOUNT_SORT_ENABLED */
++static inline int parse_symbols(const char *fname) { return 0; }
+ #endif
+
+ static int do_sort(Elf_Ehdr *ehdr,
+@@ -1256,14 +1365,29 @@ int main(int argc, char *argv[])
+ int i, n_error = 0; /* gcc-4.3.0 false positive complaint */
+ size_t size = 0;
+ void *addr = NULL;
++ int c;
++
++ while ((c = getopt(argc, argv, "s:")) >= 0) {
++ switch (c) {
++ case 's':
++ if (parse_symbols(optarg) < 0) {
++ fprintf(stderr, "Could not parse %s\n", optarg);
++ return -1;
++ }
++ break;
++ default:
++ fprintf(stderr, "usage: sorttable [-s nm-file] vmlinux...\n");
++ return 0;
++ }
++ }
+
+- if (argc < 2) {
++ if ((argc - optind) < 1) {
+ fprintf(stderr, "usage: sorttable vmlinux...\n");
+ return 0;
+ }
+
+ /* Process each file in turn, allowing deep failure. */
+- for (i = 1; i < argc; i++) {
++ for (i = optind; i < argc; i++) {
+ addr = mmap_file(argv[i], &size);
+ if (!addr) {
+ ++n_error;
--- /dev/null
+From stable+bounces-268303-greg=kroah.com@vger.kernel.org Thu Jun 25 09:25:37 2026
+From: Alexander Martyniuk <alexevgmart@gmail.com>
+Date: Thu, 25 Jun 2026 11:24:42 +0300
+Subject: sctp: disable BH before calling udp_tunnel_xmit_skb()
+To: stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Alexander Martyniuk <alexevgmart@gmail.com>, Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>, Xin Long <lucien.xin@gmail.com>, "David S. Miller" <davem@davemloft.net>, Eric Dumazet <edumazet@google.com>, Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>, Weiming Shi <bestswngs@gmail.com>, linux-sctp@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org
+Message-ID: <20260625082442.96390-3-alexevgmart@gmail.com>
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit 2cd7e6971fc2787408ceef17906ea152791448cf upstream.
+
+udp_tunnel_xmit_skb() / udp_tunnel6_xmit_skb() are expected to run with
+BH disabled. After commit 6f1a9140ecda ("add xmit recursion limit to
+tunnel xmit functions"), on the path:
+
+ udp(6)_tunnel_xmit_skb() -> ip(6)tunnel_xmit()
+
+dev_xmit_recursion_inc()/dec() must stay balanced on the same CPU.
+
+Without local_bh_disable(), the context may move between CPUs, which can
+break the inc/dec pairing. This may lead to incorrect recursion level
+detection and cause packets to be dropped in ip(6)_tunnel_xmit() or
+__dev_queue_xmit().
+
+Fix it by disabling BH around both IPv4 and IPv6 SCTP UDP xmit paths.
+
+In my testing, after enabling the SCTP over UDP:
+
+ # ip net exec ha sysctl -w net.sctp.udp_port=9899
+ # ip net exec ha sysctl -w net.sctp.encap_port=9899
+ # ip net exec hb sysctl -w net.sctp.udp_port=9899
+ # ip net exec hb sysctl -w net.sctp.encap_port=9899
+
+ # ip net exec ha iperf3 -s
+
+- without this patch:
+
+ # ip net exec hb iperf3 -c 192.168.0.1 --sctp
+ [ 5] 0.00-10.00 sec 37.2 MBytes 31.2 Mbits/sec sender
+ [ 5] 0.00-10.00 sec 37.1 MBytes 31.1 Mbits/sec receiver
+
+- with this patch:
+
+ # ip net exec hb iperf3 -c 192.168.0.1 --sctp
+ [ 5] 0.00-10.00 sec 3.14 GBytes 2.69 Gbits/sec sender
+ [ 5] 0.00-10.00 sec 3.14 GBytes 2.69 Gbits/sec receiver
+
+Fixes: 6f1a9140ecda ("net: add xmit recursion limit to tunnel xmit functions")
+Fixes: 046c052b475e ("sctp: enable udp tunneling socks")
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Link: https://patch.msgid.link/c874a8548221dcd56ff03c65ba75a74e6cf99119.1776017727.git.lucien.xin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Alexander Martyniuk <alexevgmart@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ net/sctp/protocol.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -261,9 +261,11 @@ static int sctp_v6_xmit(struct sk_buff *
+ skb_set_inner_ipproto(skb, IPPROTO_SCTP);
+ label = ip6_make_flowlabel(sock_net(sk), skb, fl6->flowlabel, true, fl6);
+
++ local_bh_disable();
+ udp_tunnel6_xmit_skb(dst, sk, skb, NULL, &fl6->saddr, &fl6->daddr,
+ tclass, ip6_dst_hoplimit(dst), label,
+ sctp_sk(sk)->udp_port, t->encap_port, false);
++ local_bh_enable();
+ return 0;
+ }
+
+--- a/net/sctp/protocol.c
++++ b/net/sctp/protocol.c
+@@ -1086,9 +1086,11 @@ static inline int sctp_v4_xmit(struct sk
+ skb_reset_inner_mac_header(skb);
+ skb_reset_inner_transport_header(skb);
+ skb_set_inner_ipproto(skb, IPPROTO_SCTP);
++ local_bh_disable();
+ udp_tunnel_xmit_skb(dst_rtable(dst), sk, skb, fl4->saddr,
+ fl4->daddr, dscp, ip4_dst_hoplimit(dst), df,
+ sctp_sk(sk)->udp_port, t->encap_port, false, false);
++ local_bh_enable();
+ return 0;
+ }
+
net-phonet-free-phonet_device-after-rcu-grace-period.patch
rxrpc-fix-the-ack-parser-to-extract-the-sack-table-for-parsing.patch
fuse-re-lock-request-before-replacing-page-cache-folio.patch
+scripts-sorttable-remove-unused-macro-defines.patch
+scripts-sorttable-remove-unused-write-functions.patch
+scripts-sorttable-remove-unneeded-elf_rel.patch
+scripts-sorttable-have-the-orc-code-use-the-_r-functions-to-read.patch
+scripts-sorttable-make-compare_extable-into-two-functions.patch
+scripts-sorttable-convert-elf_ehdr-to-union.patch
+scripts-sorttable-replace-elf_shdr-macro-with-a-union.patch
+scripts-sorttable-convert-elf_sym-macro-over-to-a-union.patch
+scripts-sorttable-add-helper-functions-for-elf_ehdr.patch
+scripts-sorttable-add-helper-functions-for-elf_shdr.patch
+scripts-sorttable-add-helper-functions-for-elf_sym.patch
+scripts-sorttable-use-uint64_t-for-mcount-sorting.patch
+scripts-sorttable-move-code-from-sorttable.h-into-sorttable.c.patch
+scripts-sorttable-get-start-stop_mcount_loc-from-elf-file-directly.patch
+scripts-sorttable-use-a-structure-of-function-pointers-for-elf-helpers.patch
+arm64-scripts-sorttable-implement-sorting-mcount_loc-at-boot-for-arm64.patch
+scripts-sorttable-have-mcount-rela-sort-use-direct-values.patch
+scripts-sorttable-always-use-an-array-for-the-mcount_loc-sorting.patch
+scripts-sorttable-zero-out-weak-functions-in-mcount_loc-table.patch
+ftrace-update-the-mcount_loc-check-of-skipped-entries.patch
+ftrace-have-ftrace-pages-output-reflect-freed-pages.patch
+ftrace-do-not-over-allocate-ftrace-memory.patch
+ftrace-test-mcount_loc-addr-before-calling-ftrace_call_addr.patch
+ftrace-check-against-is_kernel_text-instead-of-kaslr_offset.patch
+scripts-sorttable-use-normal-sort-if-theres-no-relocs-in-the-mcount-section.patch
+scripts-sorttable-allow-matches-to-functions-before-function-entry.patch
+scripts-sorttable-fix-endianness-handling-in-build-time-mcount-sort.patch
+net-ipv6-make-udp_tunnel6_xmit_skb-void.patch
+sctp-disable-bh-before-calling-udp_tunnel_xmit_skb.patch