-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
x86/static_call: Add out-of-line static call implementation
Add the x86 out-of-line static call implementation. For each key, a permanent trampoline is created which is the destination for all static calls for the given key. The trampoline has a direct jump which gets patched by static_call_update() when the destination function changes. [peterz: fixed trampoline, rewrote patching code] Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Link: https://lore.kernel.org/r/20200818135804.804315175@infradead.org
- Loading branch information
Josh Poimboeuf
authored and
Ingo Molnar
committed
Sep 1, 2020
1 parent
6333e8f
commit e6d6c07
Showing
4 changed files
with
56 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#ifndef _ASM_STATIC_CALL_H | ||
#define _ASM_STATIC_CALL_H | ||
|
||
#include <asm/text-patching.h> | ||
|
||
/* | ||
* For CONFIG_HAVE_STATIC_CALL, this is a permanent trampoline which | ||
* does a direct jump to the function. The direct jump gets patched by | ||
* static_call_update(). | ||
*/ | ||
#define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func) \ | ||
asm(".pushsection .text, \"ax\" \n" \ | ||
".align 4 \n" \ | ||
".globl " STATIC_CALL_TRAMP_STR(name) " \n" \ | ||
STATIC_CALL_TRAMP_STR(name) ": \n" \ | ||
" .byte 0xe9 # jmp.d32 \n" \ | ||
" .long " #func " - (. + 4) \n" \ | ||
".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \ | ||
".size " STATIC_CALL_TRAMP_STR(name) ", . - " STATIC_CALL_TRAMP_STR(name) " \n" \ | ||
".popsection \n") | ||
|
||
#endif /* _ASM_STATIC_CALL_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
#include <linux/static_call.h> | ||
#include <linux/memory.h> | ||
#include <linux/bug.h> | ||
#include <asm/text-patching.h> | ||
|
||
static void __static_call_transform(void *insn, u8 opcode, void *func) | ||
{ | ||
const void *code = text_gen_insn(opcode, insn, func); | ||
|
||
if (WARN_ONCE(*(u8 *)insn != opcode, | ||
"unexpected static call insn opcode 0x%x at %pS\n", | ||
opcode, insn)) | ||
return; | ||
|
||
if (memcmp(insn, code, CALL_INSN_SIZE) == 0) | ||
return; | ||
|
||
text_poke_bp(insn, code, CALL_INSN_SIZE, NULL); | ||
} | ||
|
||
void arch_static_call_transform(void *site, void *tramp, void *func) | ||
{ | ||
mutex_lock(&text_mutex); | ||
|
||
if (tramp) | ||
__static_call_transform(tramp, JMP32_INSN_OPCODE, func); | ||
|
||
mutex_unlock(&text_mutex); | ||
} | ||
EXPORT_SYMBOL_GPL(arch_static_call_transform); |