[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251013143444.3999-42-david.kaplan@amd.com>
Date: Mon, 13 Oct 2025 09:34:29 -0500
From: David Kaplan <david.kaplan@....com>
To: Thomas Gleixner <tglx@...utronix.de>, Borislav Petkov <bp@...en8.de>,
Peter Zijlstra <peterz@...radead.org>, Josh Poimboeuf <jpoimboe@...nel.org>,
Pawan Gupta <pawan.kumar.gupta@...ux.intel.com>, Ingo Molnar
<mingo@...hat.com>, Dave Hansen <dave.hansen@...ux.intel.com>,
<x86@...nel.org>, "H . Peter Anvin" <hpa@...or.com>
CC: Alexander Graf <graf@...zon.com>, Boris Ostrovsky
<boris.ostrovsky@...cle.com>, <linux-kernel@...r.kernel.org>
Subject: [RFC PATCH 41/56] static_call: Add update_all_static_calls()
The update_all_static_calls() function re-scans all static call sites and
re-patches them. This is used during re-patching.
Signed-off-by: David Kaplan <david.kaplan@....com>
---
arch/x86/kernel/static_call.c | 3 ++-
include/linux/static_call.h | 2 ++
kernel/static_call_inline.c | 22 ++++++++++++++++++++++
3 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c
index 378c388d1b31..2d16d69b17d0 100644
--- a/arch/x86/kernel/static_call.c
+++ b/arch/x86/kernel/static_call.c
@@ -105,7 +105,8 @@ static void __ref __static_call_transform(void *insn, enum insn_type type,
if (memcmp(insn, code, size) == 0)
return;
- if (system_state == SYSTEM_BOOTING || modinit)
+ /* alternatives_patched is false if we are doing dynamic re-patching. */
+ if (system_state == SYSTEM_BOOTING || modinit || !alternatives_patched)
return text_poke_early(insn, code, size);
smp_text_poke_single(insn, code, size, emulate);
diff --git a/include/linux/static_call.h b/include/linux/static_call.h
index 78a77a4ae0ea..cc5f28a04539 100644
--- a/include/linux/static_call.h
+++ b/include/linux/static_call.h
@@ -181,6 +181,8 @@ struct static_call_tramp_key {
extern void __static_call_update(struct static_call_key *key, void *tramp, void *func);
extern int static_call_mod_init(struct module *mod);
extern int static_call_text_reserved(void *start, void *end);
+extern void update_all_static_calls(struct static_call_site *start,
+ struct static_call_site *stop, struct module *mod);
extern long __static_call_return0(void);
diff --git a/kernel/static_call_inline.c b/kernel/static_call_inline.c
index 269683d41aa9..504b69496711 100644
--- a/kernel/static_call_inline.c
+++ b/kernel/static_call_inline.c
@@ -9,6 +9,7 @@
#include <linux/cpu.h>
#include <linux/processor.h>
#include <asm/sections.h>
+#include <linux/kallsyms.h>
extern struct static_call_site __start_static_call_sites[],
__stop_static_call_sites[];
@@ -492,6 +493,27 @@ int static_call_text_reserved(void *start, void *end)
return __static_call_mod_text_reserved(start, end);
}
+void update_all_static_calls(struct static_call_site *start,
+ struct static_call_site *stop,
+ struct module *mod)
+{
+ struct static_call_site *site;
+ struct static_call_key *key;
+
+ for (site = start; site < stop; site++) {
+ void *site_addr = static_call_addr(site);
+
+ /* All init code is gone when this function is called. */
+ if (is_kernel_text((u64) site_addr) ||
+ (mod &&
+ within_module_mem_type((u64) site_addr, mod, MOD_TEXT))) {
+ key = static_call_key(site);
+ arch_static_call_transform(site_addr, NULL, key->func,
+ static_call_is_tail(site));
+ }
+ }
+}
+
int __init static_call_init(void)
{
int ret;
--
2.34.1
Powered by blists - more mailing lists