From: Hao Ge <hao.ge@linux.dev>
To: Luis Chamberlain <mcgrof@kernel.org>,
Petr Pavlu <petr.pavlu@suse.com>,
Daniel Gomez <da.gomez@kernel.org>,
Sami Tolvanen <samitolvanen@google.com>,
Aaron Tomlin <atomlin@atomlin.com>,
Suren Baghdasaryan <surenb@google.com>, Hao Ge <hao.ge@linux.dev>,
Andrew Morton <akpm@linux-foundation.org>
Cc: linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, Sashiko <sashiko-bot@kernel.org>,
stable@vger.kernel.org
Subject: [PATCH v7 2/4] module: introduce SH_ENTSIZE_STANDALONE for separately allocated sections
Date: Wed, 2 Sep 2026 16:18:00 +0800 [thread overview]
Message-ID: <20260902081802.146145-3-hao.ge@linux.dev> (raw)
In-Reply-To: <20260902081802.146145-1-hao.ge@linux.dev>
SHF_ALLOC means, per the ELF spec, that a section occupies memory
during process execution. Some module sections occupy memory
outside the regular module layout, for example the percpu section
with its per-CPU allocations. The loader currently excludes such
a section from the layout by clearing its SHF_ALLOC, which
overloads the flag with a loader-internal meaning.
apply_relocations() needs a special case for the section, and
find_sec(".data..percpu") returns different results before and
after layout_and_allocate().
Introduce SH_ENTSIZE_STANDALONE to mark sections with a separate
allocation. The percpu section is its first user. layout_sections()
and move_module() skip marked sections, and apply_relocations() goes
back to testing only SHF_ALLOC.
No functional change intended.
Fixes: 4835f747d3ed ("alloc_tag: support for page allocation tag compression")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Based-on-a-patch-by: Petr Pavlu <petr.pavlu@suse.com>
Link: https://lore.kernel.org/all/499bb60c-c6e3-43a3-bd92-95a0567ece5e@suse.com/
Cc: stable@vger.kernel.org
Signed-off-by: Hao Ge <hao.ge@linux.dev>
---
include/linux/module.h | 2 ++
kernel/module/internal.h | 8 ++++++++
kernel/module/main.c | 31 +++++++++++++------------------
3 files changed, 23 insertions(+), 18 deletions(-)
diff --git a/include/linux/module.h b/include/linux/module.h
index 7566815fabbe..33548daa31a3 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -325,6 +325,8 @@ enum mod_mem_type {
MOD_INIT_RODATA,
MOD_MEM_NUM_TYPES,
+
+ MOD_STANDALONE = -2,
MOD_INVALID = -1,
};
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index 061161cc79d9..4c738074a27b 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -29,6 +29,14 @@
#define SH_ENTSIZE_TYPE_MASK ((1UL << SH_ENTSIZE_TYPE_BITS) - 1)
#define SH_ENTSIZE_OFFSET_MASK ((1UL << (BITS_PER_LONG - SH_ENTSIZE_TYPE_BITS)) - 1)
+/*
+ * Marker for sections with a separate allocation, which are not placed
+ * into mod->mem[].
+ */
+#define SH_ENTSIZE_STANDALONE \
+ (((unsigned long)MOD_STANDALONE & SH_ENTSIZE_TYPE_MASK) \
+ << SH_ENTSIZE_TYPE_SHIFT)
+
/* Maximum number of characters written by module_flags() */
#define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4)
diff --git a/kernel/module/main.c b/kernel/module/main.c
index c32f1d370b73..078dae188aba 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -1618,14 +1618,8 @@ static int apply_relocations(struct module *mod, const struct load_info *info)
if (infosec >= info->hdr->e_shnum)
continue;
- /*
- * Don't bother with non-allocated sections.
- * An exception is the percpu section, which has separate allocations
- * for individual CPUs. We relocate the percpu section in the initial
- * ELF template and subsequently copy it to the per-CPU destinations.
- */
- if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC) &&
- (!infosec || infosec != info->index.pcpu))
+ /* Don't bother with non-allocated sections. */
+ if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC))
continue;
if (info->sechdrs[i].sh_flags & SHF_RELA_LIVEPATCH)
@@ -1716,7 +1710,7 @@ static void __layout_sections(struct module *mod, struct load_info *info, bool i
if ((s->sh_flags & masks[m][0]) != masks[m][0]
|| (s->sh_flags & masks[m][1])
- || s->sh_entsize != ~0UL
+ || s->sh_entsize != ~0UL /* offset or standalone */
|| is_init != module_init_layout_section(sname))
continue;
@@ -1746,16 +1740,10 @@ static void __layout_sections(struct module *mod, struct load_info *info, bool i
/*
* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld
* might -- code, read-only data, read-write data, small data. Tally
- * sizes, and place the offsets into sh_entsize fields: high bit means it
- * belongs in init.
+ * sizes, and place the offsets into sh_entsize fields.
*/
static void layout_sections(struct module *mod, struct load_info *info)
{
- unsigned int i;
-
- for (i = 0; i < info->hdr->e_shnum; i++)
- info->sechdrs[i].sh_entsize = ~0UL;
-
pr_debug("Core section allocation order for %s:\n", mod->name);
__layout_sections(mod, info, false);
@@ -2811,7 +2799,8 @@ static int move_module(struct module *mod, struct load_info *info)
Elf_Shdr *shdr = &info->sechdrs[i];
const char *sname;
- if (!(shdr->sh_flags & SHF_ALLOC))
+ if (!(shdr->sh_flags & SHF_ALLOC)
+ || shdr->sh_entsize == SH_ENTSIZE_STANDALONE)
continue;
sname = info->secstrings + shdr->sh_name;
@@ -2943,6 +2932,7 @@ core_param(module_blacklist, module_blacklist, charp, 0400);
static struct module *layout_and_allocate(struct load_info *info, int flags)
{
struct module *mod;
+ unsigned int i;
int err;
/* Allow arches to frob section contents and sizes. */
@@ -2956,8 +2946,13 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
if (err < 0)
return ERR_PTR(err);
+ /* Repurpose sh_entsize to track where each section is allocated. */
+ for (i = 0; i < info->hdr->e_shnum; i++)
+ info->sechdrs[i].sh_entsize = ~0UL;
+
/* We will do a special allocation for per-cpu sections later. */
- info->sechdrs[info->index.pcpu].sh_flags &= ~(unsigned long)SHF_ALLOC;
+ if (info->index.pcpu)
+ info->sechdrs[info->index.pcpu].sh_entsize = SH_ENTSIZE_STANDALONE;
/*
* Mark relevant sections as SHF_RO_AFTER_INIT so layout_sections() can
--
2.25.1
next prev parent reply other threads:[~2026-09-02 8:17 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 8:17 [PATCH v7 0/4] alloc_tag and module codetag section fixes Hao Ge
2026-09-02 8:17 ` [PATCH v7 1/4] alloc_tag: move release_module_tags() above reserve_module_tags() Hao Ge
2026-09-02 8:18 ` Hao Ge [this message]
2026-09-04 16:10 ` [PATCH v7 2/4] module: introduce SH_ENTSIZE_STANDALONE for separately allocated sections Petr Pavlu
2026-09-02 8:18 ` [PATCH v7 3/4] module: allocate codetag sections before the regular module layout Hao Ge
2026-09-02 8:18 ` [PATCH v7 4/4] alloc_tag: release the reservation when populate fails Hao Ge
2026-09-02 22:05 ` [PATCH v7 0/4] alloc_tag and module codetag section fixes Andrew Morton
2026-09-03 6:30 ` Hao Ge
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260902081802.146145-3-hao.ge@linux.dev \
--to=hao.ge@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=atomlin@atomlin.com \
--cc=da.gomez@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-modules@vger.kernel.org \
--cc=mcgrof@kernel.org \
--cc=petr.pavlu@suse.com \
--cc=samitolvanen@google.com \
--cc=sashiko-bot@kernel.org \
--cc=stable@vger.kernel.org \
--cc=surenb@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®