[RFC PATCH 32/56] x86/alternative: Add module param

David Kaplan
2025-10-13T14:35:59Z

Add a struct module* param to the apply_alternatives(), apply_returns(),
and apply_retpolines() functions. This will later be used to help store
the old instruction bytes to support re-patching.

Signed-off-by: David Kaplan <david.kaplan@amd.com>
---
arch/x86/entry/vdso/vma.c | 2 +-
arch/x86/include/asm/alternative.h | 11 ++++++-----
arch/x86/kernel/alternative.c | 19 ++++++++++---------
arch/x86/kernel/module.c | 6 +++---
4 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index afe105b2f907..2451a8007854 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -42,7 +42,7 @@ int __init init_vdso_image(const struct vdso_image *image)

apply_alternatives((struct alt_instr *)(image->data + image->alt),
(struct alt_instr *)(image->data + image->alt +
- image->alt_len));
+ image->alt_len), NULL);

return 0;
}
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 15bc07a5ebb3..73fd8ebdf8d9 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -95,16 +95,17 @@ extern s32 __smp_locks[], __smp_locks_end[];
*/
extern int alternatives_patched;

+struct module;
+
extern void alternative_instructions(void);
-extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
-extern void apply_retpolines(s32 *start, s32 *end);
-extern void apply_returns(s32 *start, s32 *end);
+extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end,
+ struct module *mod);
+extern void apply_retpolines(s32 *start, s32 *end, struct module *mod);
+extern void apply_returns(s32 *start, s32 *end, struct module *mod);
extern void apply_seal_endbr(s32 *start, s32 *end);
extern void apply_fineibt(s32 *start_retpoline, s32 *end_retpoine,
s32 *start_cfi, s32 *end_cfi);

-struct module;
-
struct callthunk_sites {
s32 *call_start, *call_end;
};
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 7a1f17078581..9fbec219e98e 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -615,7 +615,8 @@ static inline u8 * instr_va(struct alt_instr *i)
* to refetch changed I$ lines.
*/
void __init_or_module noinline apply_alternatives(struct alt_instr *start,
- struct alt_instr *end)
+ struct alt_instr *end,
+ struct module *mod)
{
u8 insn_buff[MAX_PATCH_LEN];
u8 *instr, *replacement;
@@ -972,7 +973,7 @@ static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes)
/*
* Generated by 'objtool --retpoline'.
*/
-void __init_or_module noinline apply_retpolines(s32 *start, s32 *end)
+void __init_or_module noinline apply_retpolines(s32 *start, s32 *end, struct module *mod)
{
s32 *s;

@@ -1076,7 +1077,7 @@ static int patch_return(void *addr, struct insn *insn, u8 *bytes)
return i;
}

-void __init_or_module noinline apply_returns(s32 *start, s32 *end)
+void __init_or_module noinline apply_returns(s32 *start, s32 *end, struct module *mod)
{
s32 *s;

@@ -1117,13 +1118,13 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end)
}
}
#else /* !CONFIG_MITIGATION_RETHUNK: */
-void __init_or_module noinline apply_returns(s32 *start, s32 *end) { }
+void __init_or_module noinline apply_returns(s32 *start, s32 *end, struct module *mod) { }
#endif /* !CONFIG_MITIGATION_RETHUNK */

#else /* !CONFIG_MITIGATION_RETPOLINE || !CONFIG_OBJTOOL */

-void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) { }
-void __init_or_module noinline apply_returns(s32 *start, s32 *end) { }
+void __init_or_module noinline apply_retpolines(s32 *start, s32 *end, struct module *mod) { }
+void __init_or_module noinline apply_returns(s32 *start, s32 *end, struct module *mod) { }

#endif /* !CONFIG_MITIGATION_RETPOLINE || !CONFIG_OBJTOOL */

@@ -2407,8 +2408,8 @@ void __init alternative_instructions(void)
* Rewrite the retpolines, must be done before alternatives since
* those can rewrite the retpoline thunks.
*/
- apply_retpolines(__retpoline_sites, __retpoline_sites_end);
- apply_returns(__return_sites, __return_sites_end);
+ apply_retpolines(__retpoline_sites, __retpoline_sites_end, NULL);
+ apply_returns(__return_sites, __return_sites_end, NULL);

its_fini_core();

@@ -2418,7 +2419,7 @@ void __init alternative_instructions(void)
*/
callthunks_patch_builtin_calls();

- apply_alternatives(__alt_instructions, __alt_instructions_end);
+ apply_alternatives(__alt_instructions, __alt_instructions_end, NULL);

/*
* Seal all functions that do not have their address taken.
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 0ffbae902e2f..0765d2360a33 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -286,14 +286,14 @@ int module_finalize(const Elf_Ehdr *hdr,
}
if (retpolines) {
void *rseg = (void *)retpolines->sh_addr;
- apply_retpolines(rseg, rseg + retpolines->sh_size);
+ apply_retpolines(rseg, rseg + retpolines->sh_size, me);
}

its_fini_mod(me);

if (returns) {
void *rseg = (void *)returns->sh_addr;
- apply_returns(rseg, rseg + returns->sh_size);
+ apply_returns(rseg, rseg + returns->sh_size, me);
}
if (calls) {
struct callthunk_sites cs = {};
@@ -306,7 +306,7 @@ int module_finalize(const Elf_Ehdr *hdr,
if (alt) {
/* patch .altinstructions */
void *aseg = (void *)alt->sh_addr;
- apply_alternatives(aseg, aseg + alt->sh_size);
+ apply_alternatives(aseg, aseg + alt->sh_size, me);
}
if (ibt_endbr) {
void *iseg = (void *)ibt_endbr->sh_addr;
--
2.34.1