From: Petr Pavlu <petr.pavlu@suse.com>
To: Josh Poimboeuf <jpoimboe@kernel.org>,
Jiri Kosina <jikos@kernel.org>, Miroslav Benes <mbenes@suse.cz>,
Petr Mladek <pmladek@suse.com>,
Joe Lawrence <joe.lawrence@redhat.com>
Cc: 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>,
Peter Zijlstra <peterz@infradead.org>,
live-patching@vger.kernel.org, linux-modules@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH v2 1/2] livepatch: Fix having __klp_objects relics in non-livepatch modules
Date: Wed, 21 Jan 2026 09:28:16 +0100 [thread overview]
Message-ID: <20260121082842.3050453-2-petr.pavlu@suse.com> (raw)
In-Reply-To: <20260121082842.3050453-1-petr.pavlu@suse.com>
The linker script scripts/module.lds.S specifies that all input
__klp_objects sections should be consolidated into an output section of
the same name, and start/stop symbols should be created to enable
scripts/livepatch/init.c to locate this data.
This start/stop pattern is not ideal for modules because the symbols are
created even if no __klp_objects input sections are present.
Consequently, a dummy __klp_objects section also appears in the
resulting module. This unnecessarily pollutes non-livepatch modules.
Instead, since modules are relocatable files, the usual method for
locating consolidated data in a module is to read its section table.
This approach avoids the aforementioned problem.
The klp_modinfo already stores a copy of the entire section table with
the final addresses. Introduce a helper function that
scripts/livepatch/init.c can call to obtain the location of the
__klp_objects section from this data.
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
---
include/linux/livepatch.h | 3 +++
kernel/livepatch/core.c | 20 ++++++++++++++++++++
scripts/livepatch/init.c | 18 +++++++-----------
scripts/module.lds.S | 7 +------
4 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h
index 772919e8096a..0a663e5911f4 100644
--- a/include/linux/livepatch.h
+++ b/include/linux/livepatch.h
@@ -175,6 +175,9 @@ int klp_enable_patch(struct klp_patch *);
int klp_module_coming(struct module *mod);
void klp_module_going(struct module *mod);
+void *klp_locate_section_objs(const struct module *mod, const char *name,
+ size_t object_size, unsigned int *nr_objs);
+
void klp_copy_process(struct task_struct *child);
void klp_update_patch_state(struct task_struct *task);
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 9917756dae46..85925abfca0f 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -1356,6 +1356,26 @@ void klp_module_going(struct module *mod)
mutex_unlock(&klp_mutex);
}
+void *klp_locate_section_objs(const struct module *mod, const char *name,
+ size_t object_size, unsigned int *nr_objs)
+{
+ struct klp_modinfo *info = mod->klp_info;
+
+ for (int i = 1; i < info->hdr.e_shnum; i++) {
+ Elf_Shdr *shdr = &info->sechdrs[i];
+
+ if (strcmp(info->secstrings + shdr->sh_name, name))
+ continue;
+
+ *nr_objs = shdr->sh_size / object_size;
+ return (void *)shdr->sh_addr;
+ }
+
+ *nr_objs = 0;
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(klp_locate_section_objs);
+
static int __init klp_init(void)
{
klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj);
diff --git a/scripts/livepatch/init.c b/scripts/livepatch/init.c
index 2274d8f5a482..a02252e1de03 100644
--- a/scripts/livepatch/init.c
+++ b/scripts/livepatch/init.c
@@ -9,19 +9,17 @@
#include <linux/slab.h>
#include <linux/livepatch.h>
-extern struct klp_object_ext __start_klp_objects[];
-extern struct klp_object_ext __stop_klp_objects[];
-
static struct klp_patch *patch;
static int __init livepatch_mod_init(void)
{
+ struct klp_object_ext *obj_exts;
struct klp_object *objs;
unsigned int nr_objs;
int ret;
- nr_objs = __stop_klp_objects - __start_klp_objects;
-
+ obj_exts = klp_locate_section_objs(THIS_MODULE, "__klp_objects",
+ sizeof(*obj_exts), &nr_objs);
if (!nr_objs) {
pr_err("nothing to patch!\n");
ret = -EINVAL;
@@ -41,7 +39,7 @@ static int __init livepatch_mod_init(void)
}
for (int i = 0; i < nr_objs; i++) {
- struct klp_object_ext *obj_ext = __start_klp_objects + i;
+ struct klp_object_ext *obj_ext = obj_exts + i;
struct klp_func_ext *funcs_ext = obj_ext->funcs;
unsigned int nr_funcs = obj_ext->nr_funcs;
struct klp_func *funcs = objs[i].funcs;
@@ -90,12 +88,10 @@ static int __init livepatch_mod_init(void)
static void __exit livepatch_mod_exit(void)
{
- unsigned int nr_objs;
-
- nr_objs = __stop_klp_objects - __start_klp_objects;
+ struct klp_object *obj;
- for (int i = 0; i < nr_objs; i++)
- kfree(patch->objs[i].funcs);
+ klp_for_each_object_static(patch, obj)
+ kfree(obj->funcs);
kfree(patch->objs);
kfree(patch);
diff --git a/scripts/module.lds.S b/scripts/module.lds.S
index 3037d5e5527c..383d19beffb4 100644
--- a/scripts/module.lds.S
+++ b/scripts/module.lds.S
@@ -35,12 +35,7 @@ SECTIONS {
__patchable_function_entries : { *(__patchable_function_entries) }
__klp_funcs 0: ALIGN(8) { KEEP(*(__klp_funcs)) }
-
- __klp_objects 0: ALIGN(8) {
- __start_klp_objects = .;
- KEEP(*(__klp_objects))
- __stop_klp_objects = .;
- }
+ __klp_objects 0: ALIGN(8) { KEEP(*(__klp_objects)) }
#ifdef CONFIG_ARCH_USES_CFI_TRAPS
__kcfi_traps : { KEEP(*(.kcfi_traps)) }
--
2.52.0
next prev parent reply other threads:[~2026-01-21 8:29 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-21 8:28 [PATCH v2 0/2] Improve handling of the __klp_{objects,funcs} sections in modules Petr Pavlu
2026-01-21 8:28 ` Petr Pavlu [this message]
2026-01-21 21:04 ` [PATCH v2 1/2] livepatch: Fix having __klp_objects relics in non-livepatch modules Josh Poimboeuf
2026-01-22 8:34 ` Petr Pavlu
2026-01-21 8:28 ` [PATCH v2 2/2] livepatch: Free klp_{object,func}_ext data after initialization Petr Pavlu
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=20260121082842.3050453-2-petr.pavlu@suse.com \
--to=petr.pavlu@suse.com \
--cc=atomlin@atomlin.com \
--cc=da.gomez@kernel.org \
--cc=jikos@kernel.org \
--cc=joe.lawrence@redhat.com \
--cc=jpoimboe@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-modules@vger.kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=mcgrof@kernel.org \
--cc=peterz@infradead.org \
--cc=pmladek@suse.com \
--cc=samitolvanen@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