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 #ifndef __ASSEMBLER__ 29 30 /* 31 * The static call site table needs to be created by external tooling (objtool 32 * or a compiler plugin). 33 */ 34 struct static_call_site { 35 s32 addr; 36 s32 key; 37 }; 38 39 #define DECLARE_STATIC_CALL(name, func) \ 40 extern struct static_call_key STATIC_CALL_KEY(name); \ 41 extern typeof(func) STATIC_CALL_TRAMP(name); 42 43 #ifdef CONFIG_HAVE_STATIC_CALL 44 45 #define __raw_static_call(name) (&STATIC_CALL_TRAMP(name)) 46 47 #ifdef CONFIG_HAVE_STATIC_CALL_INLINE 48 49 /* 50 * __ADDRESSABLE() is used to ensure the key symbol doesn't get stripped from 51 * the symbol table so that objtool can reference it when it generates the 52 * .static_call_sites section. 53 */ 54 #define __STATIC_CALL_ADDRESSABLE(name) \ 55 __ADDRESSABLE(STATIC_CALL_KEY(name)) 56 57 #define __static_call(name) \ 58 ({ \ 59 __STATIC_CALL_ADDRESSABLE(name); \ 60 __raw_static_call(name); \ 61 }) 62 63 struct static_call_key { 64 void *func; 65 union { 66 /* bit 0: 0 = mods, 1 = sites */ 67 unsigned long type; 68 struct static_call_mod *mods; 69 struct static_call_site *sites; 70 }; 71 }; 72 73 #else /* !CONFIG_HAVE_STATIC_CALL_INLINE */ 74 75 #define __STATIC_CALL_ADDRESSABLE(name) 76 #define __static_call(name) __raw_static_call(name) 77 78 struct static_call_key { 79 void *func; 80 }; 81 82 #endif /* CONFIG_HAVE_STATIC_CALL_INLINE */ 83 84 #ifdef MODULE 85 #define __STATIC_CALL_MOD_ADDRESSABLE(name) 86 #define static_call_mod(name) __raw_static_call(name) 87 #else 88 #define __STATIC_CALL_MOD_ADDRESSABLE(name) __STATIC_CALL_ADDRESSABLE(name) 89 #define static_call_mod(name) __static_call(name) 90 #endif 91 92 #define static_call(name) __static_call(name) 93 94 #else 95 96 struct static_call_key { 97 void *func; 98 }; 99 100 #define static_call(name) \ 101 ((typeof(STATIC_CALL_TRAMP(name))*)(STATIC_CALL_KEY(name).func)) 102 103 #endif /* CONFIG_HAVE_STATIC_CALL */ 104 105 #endif /* __ASSEMBLER__ */ 106 107 #endif /* _STATIC_CALL_TYPES_H */ 108