162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _ASM_X86_LINKAGE_H
362306a36Sopenharmony_ci#define _ASM_X86_LINKAGE_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/stringify.h>
662306a36Sopenharmony_ci#include <asm/ibt.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#undef notrace
962306a36Sopenharmony_ci#define notrace __attribute__((no_instrument_function))
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifdef CONFIG_64BIT
1262306a36Sopenharmony_ci/*
1362306a36Sopenharmony_ci * The generic version tends to create spurious ENDBR instructions under
1462306a36Sopenharmony_ci * certain conditions.
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_ci#define _THIS_IP_ ({ unsigned long __here; asm ("lea 0(%%rip), %0" : "=r" (__here)); __here; })
1762306a36Sopenharmony_ci#endif
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#ifdef CONFIG_X86_32
2062306a36Sopenharmony_ci#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
2162306a36Sopenharmony_ci#endif /* CONFIG_X86_32 */
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define __ALIGN		.balign CONFIG_FUNCTION_ALIGNMENT, 0x90;
2462306a36Sopenharmony_ci#define __ALIGN_STR	__stringify(__ALIGN)
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#if defined(CONFIG_CALL_PADDING) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
2762306a36Sopenharmony_ci#define FUNCTION_PADDING	.skip CONFIG_FUNCTION_ALIGNMENT, 0x90;
2862306a36Sopenharmony_ci#else
2962306a36Sopenharmony_ci#define FUNCTION_PADDING
3062306a36Sopenharmony_ci#endif
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci#if (CONFIG_FUNCTION_ALIGNMENT > 8) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
3362306a36Sopenharmony_ci# define __FUNC_ALIGN		__ALIGN; FUNCTION_PADDING
3462306a36Sopenharmony_ci#else
3562306a36Sopenharmony_ci# define __FUNC_ALIGN		__ALIGN
3662306a36Sopenharmony_ci#endif
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define ASM_FUNC_ALIGN		__stringify(__FUNC_ALIGN)
3962306a36Sopenharmony_ci#define SYM_F_ALIGN		__FUNC_ALIGN
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#ifdef __ASSEMBLY__
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#if defined(CONFIG_RETHUNK) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
4462306a36Sopenharmony_ci#define RET	jmp __x86_return_thunk
4562306a36Sopenharmony_ci#else /* CONFIG_RETPOLINE */
4662306a36Sopenharmony_ci#ifdef CONFIG_SLS
4762306a36Sopenharmony_ci#define RET	ret; int3
4862306a36Sopenharmony_ci#else
4962306a36Sopenharmony_ci#define RET	ret
5062306a36Sopenharmony_ci#endif
5162306a36Sopenharmony_ci#endif /* CONFIG_RETPOLINE */
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#else /* __ASSEMBLY__ */
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci#if defined(CONFIG_RETHUNK) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
5662306a36Sopenharmony_ci#define ASM_RET	"jmp __x86_return_thunk\n\t"
5762306a36Sopenharmony_ci#else /* CONFIG_RETPOLINE */
5862306a36Sopenharmony_ci#ifdef CONFIG_SLS
5962306a36Sopenharmony_ci#define ASM_RET	"ret; int3\n\t"
6062306a36Sopenharmony_ci#else
6162306a36Sopenharmony_ci#define ASM_RET	"ret\n\t"
6262306a36Sopenharmony_ci#endif
6362306a36Sopenharmony_ci#endif /* CONFIG_RETPOLINE */
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci#endif /* __ASSEMBLY__ */
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci/*
6862306a36Sopenharmony_ci * Depending on -fpatchable-function-entry=N,N usage (CONFIG_CALL_PADDING) the
6962306a36Sopenharmony_ci * CFI symbol layout changes.
7062306a36Sopenharmony_ci *
7162306a36Sopenharmony_ci * Without CALL_THUNKS:
7262306a36Sopenharmony_ci *
7362306a36Sopenharmony_ci * 	.align	FUNCTION_ALIGNMENT
7462306a36Sopenharmony_ci * __cfi_##name:
7562306a36Sopenharmony_ci * 	.skip	FUNCTION_PADDING, 0x90
7662306a36Sopenharmony_ci * 	.byte   0xb8
7762306a36Sopenharmony_ci * 	.long	__kcfi_typeid_##name
7862306a36Sopenharmony_ci * name:
7962306a36Sopenharmony_ci *
8062306a36Sopenharmony_ci * With CALL_THUNKS:
8162306a36Sopenharmony_ci *
8262306a36Sopenharmony_ci * 	.align FUNCTION_ALIGNMENT
8362306a36Sopenharmony_ci * __cfi_##name:
8462306a36Sopenharmony_ci * 	.byte	0xb8
8562306a36Sopenharmony_ci * 	.long	__kcfi_typeid_##name
8662306a36Sopenharmony_ci * 	.skip	FUNCTION_PADDING, 0x90
8762306a36Sopenharmony_ci * name:
8862306a36Sopenharmony_ci *
8962306a36Sopenharmony_ci * In both cases the whole thing is FUNCTION_ALIGNMENT aligned and sized.
9062306a36Sopenharmony_ci */
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci#ifdef CONFIG_CALL_PADDING
9362306a36Sopenharmony_ci#define CFI_PRE_PADDING
9462306a36Sopenharmony_ci#define CFI_POST_PADDING	.skip	CONFIG_FUNCTION_PADDING_BYTES, 0x90;
9562306a36Sopenharmony_ci#else
9662306a36Sopenharmony_ci#define CFI_PRE_PADDING		.skip	CONFIG_FUNCTION_PADDING_BYTES, 0x90;
9762306a36Sopenharmony_ci#define CFI_POST_PADDING
9862306a36Sopenharmony_ci#endif
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci#define __CFI_TYPE(name)					\
10162306a36Sopenharmony_ci	SYM_START(__cfi_##name, SYM_L_LOCAL, SYM_A_NONE)	\
10262306a36Sopenharmony_ci	CFI_PRE_PADDING						\
10362306a36Sopenharmony_ci	.byte 0xb8 ASM_NL					\
10462306a36Sopenharmony_ci	.long __kcfi_typeid_##name ASM_NL			\
10562306a36Sopenharmony_ci	CFI_POST_PADDING					\
10662306a36Sopenharmony_ci	SYM_FUNC_END(__cfi_##name)
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci/* UML needs to be able to override memcpy() and friends for KASAN. */
10962306a36Sopenharmony_ci#ifdef CONFIG_UML
11062306a36Sopenharmony_ci# define SYM_FUNC_ALIAS_MEMFUNC	SYM_FUNC_ALIAS_WEAK
11162306a36Sopenharmony_ci#else
11262306a36Sopenharmony_ci# define SYM_FUNC_ALIAS_MEMFUNC	SYM_FUNC_ALIAS
11362306a36Sopenharmony_ci#endif
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci/* SYM_TYPED_FUNC_START -- use for indirectly called globals, w/ CFI type */
11662306a36Sopenharmony_ci#define SYM_TYPED_FUNC_START(name)				\
11762306a36Sopenharmony_ci	SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_F_ALIGN)	\
11862306a36Sopenharmony_ci	ENDBR
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/* SYM_FUNC_START -- use for global functions */
12162306a36Sopenharmony_ci#define SYM_FUNC_START(name)				\
12262306a36Sopenharmony_ci	SYM_START(name, SYM_L_GLOBAL, SYM_F_ALIGN)	\
12362306a36Sopenharmony_ci	ENDBR
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci/* SYM_FUNC_START_NOALIGN -- use for global functions, w/o alignment */
12662306a36Sopenharmony_ci#define SYM_FUNC_START_NOALIGN(name)			\
12762306a36Sopenharmony_ci	SYM_START(name, SYM_L_GLOBAL, SYM_A_NONE)	\
12862306a36Sopenharmony_ci	ENDBR
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci/* SYM_FUNC_START_LOCAL -- use for local functions */
13162306a36Sopenharmony_ci#define SYM_FUNC_START_LOCAL(name)			\
13262306a36Sopenharmony_ci	SYM_START(name, SYM_L_LOCAL, SYM_F_ALIGN)	\
13362306a36Sopenharmony_ci	ENDBR
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci/* SYM_FUNC_START_LOCAL_NOALIGN -- use for local functions, w/o alignment */
13662306a36Sopenharmony_ci#define SYM_FUNC_START_LOCAL_NOALIGN(name)		\
13762306a36Sopenharmony_ci	SYM_START(name, SYM_L_LOCAL, SYM_A_NONE)	\
13862306a36Sopenharmony_ci	ENDBR
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci/* SYM_FUNC_START_WEAK -- use for weak functions */
14162306a36Sopenharmony_ci#define SYM_FUNC_START_WEAK(name)			\
14262306a36Sopenharmony_ci	SYM_START(name, SYM_L_WEAK, SYM_F_ALIGN)	\
14362306a36Sopenharmony_ci	ENDBR
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci/* SYM_FUNC_START_WEAK_NOALIGN -- use for weak functions, w/o alignment */
14662306a36Sopenharmony_ci#define SYM_FUNC_START_WEAK_NOALIGN(name)		\
14762306a36Sopenharmony_ci	SYM_START(name, SYM_L_WEAK, SYM_A_NONE)		\
14862306a36Sopenharmony_ci	ENDBR
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci#endif /* _ASM_X86_LINKAGE_H */
15162306a36Sopenharmony_ci
152