Commit | Line | Data |
---|---|---|
e6d6c071 JP |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _ASM_STATIC_CALL_H | |
3 | #define _ASM_STATIC_CALL_H | |
4 | ||
5 | #include <asm/text-patching.h> | |
6 | ||
7 | /* | |
1e7e4788 JP |
8 | * For CONFIG_HAVE_STATIC_CALL_INLINE, this is a temporary trampoline which |
9 | * uses the current value of the key->func pointer to do an indirect jump to | |
10 | * the function. This trampoline is only used during boot, before the call | |
11 | * sites get patched by static_call_update(). The name of this trampoline has | |
12 | * a magical aspect: objtool uses it to find static call sites so it can create | |
13 | * the .static_call_sites section. | |
14 | * | |
e6d6c071 JP |
15 | * For CONFIG_HAVE_STATIC_CALL, this is a permanent trampoline which |
16 | * does a direct jump to the function. The direct jump gets patched by | |
17 | * static_call_update(). | |
1e7e4788 JP |
18 | * |
19 | * Having the trampoline in a special section forces GCC to emit a JMP.d32 when | |
20 | * it does tail-call optimization on the call; since you cannot compute the | |
21 | * relative displacement across sections. | |
e6d6c071 | 22 | */ |
452cddbf | 23 | |
ee88d363 PZ |
24 | /* |
25 | * The trampoline is 8 bytes and of the general form: | |
26 | * | |
27 | * jmp.d32 \func | |
28 | * ud1 %esp, %ecx | |
29 | * | |
30 | * That trailing #UD provides both a speculation stop and serves as a unique | |
31 | * 3 byte signature identifying static call trampolines. Also see tramp_ud[] | |
32 | * and __static_call_fixup(). | |
33 | */ | |
452cddbf | 34 | #define __ARCH_DEFINE_STATIC_CALL_TRAMP(name, insns) \ |
1e7e4788 | 35 | asm(".pushsection .static_call.text, \"ax\" \n" \ |
e6d6c071 JP |
36 | ".align 4 \n" \ |
37 | ".globl " STATIC_CALL_TRAMP_STR(name) " \n" \ | |
38 | STATIC_CALL_TRAMP_STR(name) ": \n" \ | |
613871cd | 39 | ANNOTATE_NOENDBR \ |
452cddbf | 40 | insns " \n" \ |
ee88d363 | 41 | ".byte 0x0f, 0xb9, 0xcc \n" \ |
e6d6c071 JP |
42 | ".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \ |
43 | ".size " STATIC_CALL_TRAMP_STR(name) ", . - " STATIC_CALL_TRAMP_STR(name) " \n" \ | |
44 | ".popsection \n") | |
45 | ||
452cddbf PZ |
46 | #define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func) \ |
47 | __ARCH_DEFINE_STATIC_CALL_TRAMP(name, ".byte 0xe9; .long " #func " - (. + 4)") | |
48 | ||
f43b9876 | 49 | #ifdef CONFIG_RETHUNK |
ee88d363 PZ |
50 | #define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) \ |
51 | __ARCH_DEFINE_STATIC_CALL_TRAMP(name, "jmp __x86_return_thunk") | |
52 | #else | |
452cddbf | 53 | #define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) \ |
e463a09a | 54 | __ARCH_DEFINE_STATIC_CALL_TRAMP(name, "ret; int3; nop; nop; nop") |
ee88d363 | 55 | #endif |
452cddbf | 56 | |
5517d500 CL |
57 | #define ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name) \ |
58 | ARCH_DEFINE_STATIC_CALL_TRAMP(name, __static_call_return0) | |
73f44fe1 JP |
59 | |
60 | #define ARCH_ADD_TRAMP_KEY(name) \ | |
61 | asm(".pushsection .static_call_tramp_key, \"a\" \n" \ | |
62 | ".long " STATIC_CALL_TRAMP_STR(name) " - . \n" \ | |
63 | ".long " STATIC_CALL_KEY_STR(name) " - . \n" \ | |
64 | ".popsection \n") | |
65 | ||
ee88d363 PZ |
66 | extern bool __static_call_fixup(void *tramp, u8 op, void *dest); |
67 | ||
e6d6c071 | 68 | #endif /* _ASM_STATIC_CALL_H */ |