static_call_types.h (2809B)
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 */ 32struct 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 61struct 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 76struct 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 94struct 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 */