]>
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 | ||
73f44fe1 JP |
61 | #else /* !CONFIG_HAVE_STATIC_CALL_INLINE */ |
62 | ||
63 | #define __STATIC_CALL_ADDRESSABLE(name) | |
64 | #define __static_call(name) __raw_static_call(name) | |
65 | ||
66 | #endif /* CONFIG_HAVE_STATIC_CALL_INLINE */ | |
67 | ||
68 | #ifdef MODULE | |
69 | #define __STATIC_CALL_MOD_ADDRESSABLE(name) | |
70 | #define static_call_mod(name) __raw_static_call(name) | |
71 | #else | |
72 | #define __STATIC_CALL_MOD_ADDRESSABLE(name) __STATIC_CALL_ADDRESSABLE(name) | |
73 | #define static_call_mod(name) __static_call(name) | |
74 | #endif | |
75 | ||
880cfed3 PZ |
76 | #define static_call(name) __static_call(name) |
77 | ||
78 | #else | |
79 | ||
80 | #define static_call(name) \ | |
81 | ((typeof(STATIC_CALL_TRAMP(name))*)(STATIC_CALL_KEY(name).func)) | |
82 | ||
83 | #endif /* CONFIG_HAVE_STATIC_CALL */ | |
84 | ||
115284d8 | 85 | #endif /* _STATIC_CALL_TYPES_H */ |