aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/kernel/static_call.c
diff options
context:
space:
mode:
authorGravatar Peter Zijlstra <peterz@infradead.org> 2020-08-18 15:57:51 +0200
committerGravatar Ingo Molnar <mingo@kernel.org> 2020-09-01 09:58:06 +0200
commita945c8345ec0decb2f1a7f19a8c5e60bcb1dd1eb (patch)
tree11d4ff482c11945ef30fe5c88493a2b49202ad27 /arch/x86/kernel/static_call.c
parentstatic_call: Add some validation (diff)
downloadlinux-a945c8345ec0decb2f1a7f19a8c5e60bcb1dd1eb.tar.gz
linux-a945c8345ec0decb2f1a7f19a8c5e60bcb1dd1eb.tar.bz2
linux-a945c8345ec0decb2f1a7f19a8c5e60bcb1dd1eb.zip
static_call: Allow early init
In order to use static_call() to wire up x86_pmu, we need to initialize earlier, specifically before memory allocation works; copy some of the tricks from jump_label to enable this. Primarily we overload key->next to store a sites pointer when there are no modules, this avoids having to use kmalloc() to initialize the sites and allows us to run much earlier. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> Link: https://lore.kernel.org/r/20200818135805.220737930@infradead.org
Diffstat (limited to 'arch/x86/kernel/static_call.c')
-rw-r--r--arch/x86/kernel/static_call.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c
index 55140d8db106..ca9a380d9c0b 100644
--- a/arch/x86/kernel/static_call.c
+++ b/arch/x86/kernel/static_call.c
@@ -11,7 +11,7 @@ enum insn_type {
RET = 3, /* tramp / site cond-tail-call */
};
-static void __static_call_transform(void *insn, enum insn_type type, void *func)
+static void __ref __static_call_transform(void *insn, enum insn_type type, void *func)
{
int size = CALL_INSN_SIZE;
const void *code;
@@ -38,6 +38,9 @@ static void __static_call_transform(void *insn, enum insn_type type, void *func)
if (memcmp(insn, code, size) == 0)
return;
+ if (unlikely(system_state == SYSTEM_BOOTING))
+ return text_poke_early(insn, code, size);
+
text_poke_bp(insn, code, size, NULL);
}