mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-26 12:26:11 +00:00
b046664872
Having the definition of static_call() in static_call_types.h makes no sense as long struct static_call_key isn't defined there, as the generic implementation of static_call() is referencing this structure. So move the definition of struct static_call_key to static_call_types.h. Signed-off-by: Juergen Gross <jgross@suse.com> Signed-off-by: Borislav Petkov <bp@suse.de> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/20210311142319.4723-3-jgross@suse.com
103 lines
2.7 KiB
C
103 lines
2.7 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _STATIC_CALL_TYPES_H
|
|
#define _STATIC_CALL_TYPES_H
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/stringify.h>
|
|
#include <linux/compiler.h>
|
|
|
|
#define STATIC_CALL_KEY_PREFIX __SCK__
|
|
#define STATIC_CALL_KEY_PREFIX_STR __stringify(STATIC_CALL_KEY_PREFIX)
|
|
#define STATIC_CALL_KEY_PREFIX_LEN (sizeof(STATIC_CALL_KEY_PREFIX_STR) - 1)
|
|
#define STATIC_CALL_KEY(name) __PASTE(STATIC_CALL_KEY_PREFIX, name)
|
|
#define STATIC_CALL_KEY_STR(name) __stringify(STATIC_CALL_KEY(name))
|
|
|
|
#define STATIC_CALL_TRAMP_PREFIX __SCT__
|
|
#define STATIC_CALL_TRAMP_PREFIX_STR __stringify(STATIC_CALL_TRAMP_PREFIX)
|
|
#define STATIC_CALL_TRAMP_PREFIX_LEN (sizeof(STATIC_CALL_TRAMP_PREFIX_STR) - 1)
|
|
#define STATIC_CALL_TRAMP(name) __PASTE(STATIC_CALL_TRAMP_PREFIX, name)
|
|
#define STATIC_CALL_TRAMP_STR(name) __stringify(STATIC_CALL_TRAMP(name))
|
|
|
|
/*
|
|
* Flags in the low bits of static_call_site::key.
|
|
*/
|
|
#define STATIC_CALL_SITE_TAIL 1UL /* tail call */
|
|
#define STATIC_CALL_SITE_INIT 2UL /* init section */
|
|
#define STATIC_CALL_SITE_FLAGS 3UL
|
|
|
|
/*
|
|
* The static call site table needs to be created by external tooling (objtool
|
|
* or a compiler plugin).
|
|
*/
|
|
struct static_call_site {
|
|
s32 addr;
|
|
s32 key;
|
|
};
|
|
|
|
#define DECLARE_STATIC_CALL(name, func) \
|
|
extern struct static_call_key STATIC_CALL_KEY(name); \
|
|
extern typeof(func) STATIC_CALL_TRAMP(name);
|
|
|
|
#ifdef CONFIG_HAVE_STATIC_CALL
|
|
|
|
#define __raw_static_call(name) (&STATIC_CALL_TRAMP(name))
|
|
|
|
#ifdef CONFIG_HAVE_STATIC_CALL_INLINE
|
|
|
|
/*
|
|
* __ADDRESSABLE() is used to ensure the key symbol doesn't get stripped from
|
|
* the symbol table so that objtool can reference it when it generates the
|
|
* .static_call_sites section.
|
|
*/
|
|
#define __STATIC_CALL_ADDRESSABLE(name) \
|
|
__ADDRESSABLE(STATIC_CALL_KEY(name))
|
|
|
|
#define __static_call(name) \
|
|
({ \
|
|
__STATIC_CALL_ADDRESSABLE(name); \
|
|
__raw_static_call(name); \
|
|
})
|
|
|
|
struct static_call_key {
|
|
void *func;
|
|
union {
|
|
/* bit 0: 0 = mods, 1 = sites */
|
|
unsigned long type;
|
|
struct static_call_mod *mods;
|
|
struct static_call_site *sites;
|
|
};
|
|
};
|
|
|
|
#else /* !CONFIG_HAVE_STATIC_CALL_INLINE */
|
|
|
|
#define __STATIC_CALL_ADDRESSABLE(name)
|
|
#define __static_call(name) __raw_static_call(name)
|
|
|
|
struct static_call_key {
|
|
void *func;
|
|
};
|
|
|
|
#endif /* CONFIG_HAVE_STATIC_CALL_INLINE */
|
|
|
|
#ifdef MODULE
|
|
#define __STATIC_CALL_MOD_ADDRESSABLE(name)
|
|
#define static_call_mod(name) __raw_static_call(name)
|
|
#else
|
|
#define __STATIC_CALL_MOD_ADDRESSABLE(name) __STATIC_CALL_ADDRESSABLE(name)
|
|
#define static_call_mod(name) __static_call(name)
|
|
#endif
|
|
|
|
#define static_call(name) __static_call(name)
|
|
|
|
#else
|
|
|
|
struct static_call_key {
|
|
void *func;
|
|
};
|
|
|
|
#define static_call(name) \
|
|
((typeof(STATIC_CALL_TRAMP(name))*)(STATIC_CALL_KEY(name).func))
|
|
|
|
#endif /* CONFIG_HAVE_STATIC_CALL */
|
|
|
|
#endif /* _STATIC_CALL_TYPES_H */
|