diff options
Diffstat (limited to 'arch/arm64/include')
-rw-r--r-- | arch/arm64/include/asm/asm-prototypes.h | 41 | ||||
-rw-r--r-- | arch/arm64/include/asm/assembler.h | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/nospec-branch.h | 59 |
3 files changed, 101 insertions, 0 deletions
diff --git a/arch/arm64/include/asm/asm-prototypes.h b/arch/arm64/include/asm/asm-prototypes.h new file mode 100644 index 000000000000..930391c5cef7 --- /dev/null +++ b/arch/arm64/include/asm/asm-prototypes.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include <asm-generic/asm-prototypes.h> + +#ifdef CONFIG_RETPOLINE +#define INDIRECT_THUNK(reg) \ +extern asmlinkage void __aarch64_indirect_thunk_ ## reg(void); + +INDIRECT_THUNK(x0); +INDIRECT_THUNK(x1); +INDIRECT_THUNK(x2); +INDIRECT_THUNK(x3); +INDIRECT_THUNK(x4); +INDIRECT_THUNK(x5); +INDIRECT_THUNK(x6); +INDIRECT_THUNK(x7); +INDIRECT_THUNK(x8); +INDIRECT_THUNK(x9); +INDIRECT_THUNK(x10); +INDIRECT_THUNK(x11); +INDIRECT_THUNK(x12); +INDIRECT_THUNK(x13); +INDIRECT_THUNK(x14); +INDIRECT_THUNK(x15); +INDIRECT_THUNK(x16); +INDIRECT_THUNK(x17); +INDIRECT_THUNK(x18); +INDIRECT_THUNK(x19); +INDIRECT_THUNK(x20); +INDIRECT_THUNK(x21); +INDIRECT_THUNK(x22); +INDIRECT_THUNK(x23); +INDIRECT_THUNK(x24); +INDIRECT_THUNK(x25); +INDIRECT_THUNK(x26); +INDIRECT_THUNK(x27); +INDIRECT_THUNK(x28); +INDIRECT_THUNK(x29); +INDIRECT_THUNK(x30); + +#endif /* CONFIG_RETPOLINE */ + diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index b05565dd50b6..863a03b96902 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -30,6 +30,7 @@ #include <asm/pgtable-hwdef.h> #include <asm/ptrace.h> #include <asm/thread_info.h> +#include <asm/nospec-branch.h> .macro save_and_disable_daif, flags mrs \flags, daif diff --git a/arch/arm64/include/asm/nospec-branch.h b/arch/arm64/include/asm/nospec-branch.h new file mode 100644 index 000000000000..cc261d5f1afd --- /dev/null +++ b/arch/arm64/include/asm/nospec-branch.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _ASM_ARM64_NOSPEC_BRANCH_H_ +#define _ASM_ARM64_NOSPEC_BRANCH_H_ + +#ifdef __ASSEMBLY__ + +.macro retpoline + str x30, [sp, #-16]! + bl 101f +100: //speculation trap + wfe + b 100b +101: //do ROP + adrp x30, 102f + add x30, x30, :lo12:102f + ret +102: //non-spec code + ldr x30, [sp], #16 +.endm + +.macro br_nospec reg +#ifdef CONFIG_RETPOLINE + b __aarch64_indirect_thunk_\reg +#else + br \reg +#endif +.endm + +.macro blr_nospec reg +#ifdef CONFIG_RETPOLINE + bl __aarch64_indirect_thunk_\reg +#else + blr \reg +#endif +.endm + +/* + * In case of "blr lr" we need to inline the retpoline + * as we cannot do a bl to the indirect_thunk, because + * it would destroy the contents of our link register. + */ +.macro blr_nospec_lr +#ifdef CONFIG_RETPOLINE + retpoline + blr lr +#else + blr lr +#endif +.endm + +#else /* __ASSEMBLY__ */ + +extern char __indirect_thunk_start[]; +extern char __indirect_thunk_end[]; + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_ARM64_NOSPEC_BRANCH_H_ */ |