]>
Commit | Line | Data |
---|---|---|
115284d8 JP |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _STATIC_CALL_TYPES_H | |
3 | #define _STATIC_CALL_TYPES_H | |
4 | ||
9183c3f9 | 5 | #include <linux/types.h> |
115284d8 | 6 | #include <linux/stringify.h> |
880cfed3 | 7 | #include <linux/compiler.h> |
115284d8 JP |
8 | |
9 | #define STATIC_CALL_KEY_PREFIX __SCK__ | |
9183c3f9 JP |
10 | #define STATIC_CALL_KEY_PREFIX_STR __stringify(STATIC_CALL_KEY_PREFIX) |
11 | #define STATIC_CALL_KEY_PREFIX_LEN (sizeof(STATIC_CALL_KEY_PREFIX_STR) - 1) | |
115284d8 | 12 | #define STATIC_CALL_KEY(name) __PASTE(STATIC_CALL_KEY_PREFIX, name) |
73f44fe1 | 13 | #define STATIC_CALL_KEY_STR(name) __stringify(STATIC_CALL_KEY(name)) |
115284d8 JP |
14 | |
15 | #define STATIC_CALL_TRAMP_PREFIX __SCT__ | |
16 | #define STATIC_CALL_TRAMP_PREFIX_STR __stringify(STATIC_CALL_TRAMP_PREFIX) | |
9183c3f9 | 17 | #define STATIC_CALL_TRAMP_PREFIX_LEN (sizeof(STATIC_CALL_TRAMP_PREFIX_STR) - 1) |
115284d8 JP |
18 | #define STATIC_CALL_TRAMP(name) __PASTE(STATIC_CALL_TRAMP_PREFIX, name) |
19 | #define STATIC_CALL_TRAMP_STR(name) __stringify(STATIC_CALL_TRAMP(name)) | |
20 | ||
5b06fd3b PZ |
21 | /* |
22 | * Flags in the low bits of static_call_site::key. | |
23 | */ | |
24 | #define STATIC_CALL_SITE_TAIL 1UL /* tail call */ | |
25 | #define STATIC_CALL_SITE_INIT 2UL /* init section */ | |
26 | #define STATIC_CALL_SITE_FLAGS 3UL | |
27 | ||
9183c3f9 JP |
28 | /* |
29 | * The static call site table needs to be created by external tooling (objtool | |
30 | * or a compiler plugin). | |
31 | */ | |
32 | struct static_call_site { | |
33 | s32 addr; | |
34 | s32 key; | |
35 | }; | |
36 | ||
880cfed3 PZ |
37 | #define DECLARE_STATIC_CALL(name, func) \ |
38 | extern struct static_call_key STATIC_CALL_KEY(name); \ | |
39 | extern typeof(func) STATIC_CALL_TRAMP(name); | |
40 | ||
41 | #ifdef CONFIG_HAVE_STATIC_CALL | |
42 | ||
73f44fe1 JP |
43 | #define __raw_static_call(name) (&STATIC_CALL_TRAMP(name)) |
44 | ||
45 | #ifdef CONFIG_HAVE_STATIC_CALL_INLINE | |
46 | ||
880cfed3 PZ |
47 | /* |
48 | * __ADDRESSABLE() is used to ensure the key symbol doesn't get stripped from | |
49 | * the symbol table so that objtool can reference it when it generates the | |
50 | * .static_call_sites section. | |
51 | */ | |
73f44fe1 JP |
52 | #define __STATIC_CALL_ADDRESSABLE(name) \ |
53 | __ADDRESSABLE(STATIC_CALL_KEY(name)) | |
54 | ||
880cfed3 PZ |
55 | #define __static_call(name) \ |
56 | ({ \ | |
73f44fe1 JP |
57 | __STATIC_CALL_ADDRESSABLE(name); \ |
58 | __raw_static_call(name); \ | |
880cfed3 PZ |
59 | }) |
60 | ||
b0466648 JG |
61 | struct static_call_key { |
62 | void *func; | |
63 | union { | |
64 | /* bit 0: 0 = mods, 1 = sites */ | |
65 | unsigned long type; | |
66 | struct static_call_mod *mods; | |
67 | struct static_call_site *sites; | |
68 | }; | |
69 | }; | |
70 | ||
73f44fe1 JP |
71 | #else /* !CONFIG_HAVE_STATIC_CALL_INLINE */ |
72 | ||
73 | #define __STATIC_CALL_ADDRESSABLE(name) | |
74 | #define __static_call(name) __raw_static_call(name) | |
75 | ||
b0466648 JG |
76 | struct static_call_key { |
77 | void *func; | |
78 | }; | |
79 | ||
73f44fe1 JP |
80 | #endif /* CONFIG_HAVE_STATIC_CALL_INLINE */ |
81 | ||
82 | #ifdef MODULE | |
83 | #define __STATIC_CALL_MOD_ADDRESSABLE(name) | |
84 | #define static_call_mod(name) __raw_static_call(name) | |
85 | #else | |
86 | #define __STATIC_CALL_MOD_ADDRESSABLE(name) __STATIC_CALL_ADDRESSABLE(name) | |
87 | #define static_call_mod(name) __static_call(name) | |
88 | #endif | |
89 | ||
880cfed3 PZ |
90 | #define static_call(name) __static_call(name) |
91 | ||
92 | #else | |
93 | ||
b0466648 JG |
94 | struct static_call_key { |
95 | void *func; | |
96 | }; | |
97 | ||
880cfed3 PZ |
98 | #define static_call(name) \ |
99 | ((typeof(STATIC_CALL_TRAMP(name))*)(STATIC_CALL_KEY(name).func)) | |
100 | ||
101 | #endif /* CONFIG_HAVE_STATIC_CALL */ | |
102 | ||
115284d8 | 103 | #endif /* _STATIC_CALL_TYPES_H */ |