1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _STATIC_CALL_TYPES_H |
3 | #define _STATIC_CALL_TYPES_H |
4 | |
5 | #include <linux/types.h> |
6 | #include <linux/stringify.h> |
7 | #include <linux/compiler.h> |
8 | |
9 | #define STATIC_CALL_KEY_PREFIX __SCK__ |
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) |
12 | #define STATIC_CALL_KEY(name) __PASTE(STATIC_CALL_KEY_PREFIX, name) |
13 | #define STATIC_CALL_KEY_STR(name) __stringify(STATIC_CALL_KEY(name)) |
14 | |
15 | #define STATIC_CALL_TRAMP_PREFIX __SCT__ |
16 | #define STATIC_CALL_TRAMP_PREFIX_STR __stringify(STATIC_CALL_TRAMP_PREFIX) |
17 | #define STATIC_CALL_TRAMP_PREFIX_LEN (sizeof(STATIC_CALL_TRAMP_PREFIX_STR) - 1) |
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 | |
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 | |
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 | |
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 | |
43 | #define __raw_static_call(name) (&STATIC_CALL_TRAMP(name)) |
44 | |
45 | #ifdef CONFIG_HAVE_STATIC_CALL_INLINE |
46 | |
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 | */ |
52 | #define __STATIC_CALL_ADDRESSABLE(name) \ |
53 | __ADDRESSABLE(STATIC_CALL_KEY(name)) |
54 | |
55 | #define __static_call(name) \ |
56 | ({ \ |
57 | __STATIC_CALL_ADDRESSABLE(name); \ |
58 | __raw_static_call(name); \ |
59 | }) |
60 | |
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 | |
71 | #else /* !CONFIG_HAVE_STATIC_CALL_INLINE */ |
72 | |
73 | #define __STATIC_CALL_ADDRESSABLE(name) |
74 | #define __static_call(name) __raw_static_call(name) |
75 | |
76 | struct static_call_key { |
77 | void *func; |
78 | }; |
79 | |
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 | |
90 | #define static_call(name) __static_call(name) |
91 | |
92 | #else |
93 | |
94 | struct static_call_key { |
95 | void *func; |
96 | }; |
97 | |
98 | #define static_call(name) \ |
99 | ((typeof(STATIC_CALL_TRAMP(name))*)(STATIC_CALL_KEY(name).func)) |
100 | |
101 | #endif /* CONFIG_HAVE_STATIC_CALL */ |
102 | |
103 | #endif /* _STATIC_CALL_TYPES_H */ |
104 | |