1/* SPDX-License-Identifier: GPL-2.0 */ 2 3#include <linux/stringify.h> 4#include <linux/linkage.h> 5#include <asm/dwarf2.h> 6#include <asm/cpufeatures.h> 7#include <asm/alternative-asm.h> 8#include <asm/export.h> 9#include <asm/nospec-branch.h> 10#include <asm/unwind_hints.h> 11#include <asm/frame.h> 12 13.macro THUNK reg 14 .section .text.__x86.indirect_thunk 15 16 .align 32 17SYM_FUNC_START(__x86_indirect_thunk_\reg) 18 JMP_NOSPEC \reg 19SYM_FUNC_END(__x86_indirect_thunk_\reg) 20 21SYM_FUNC_START_NOALIGN(__x86_retpoline_\reg) 22 ANNOTATE_INTRA_FUNCTION_CALL 23 call .Ldo_rop_\@ 24.Lspec_trap_\@: 25 UNWIND_HINT_EMPTY 26 pause 27 lfence 28 jmp .Lspec_trap_\@ 29.Ldo_rop_\@: 30 mov %\reg, (%_ASM_SP) 31 UNWIND_HINT_FUNC 32 ret 33SYM_FUNC_END(__x86_retpoline_\reg) 34 35.endm 36 37/* 38 * Despite being an assembler file we can't just use .irp here 39 * because __KSYM_DEPS__ only uses the C preprocessor and would 40 * only see one instance of "__x86_indirect_thunk_\reg" rather 41 * than one per register with the correct names. So we do it 42 * the simple and nasty way... 43 * 44 * Worse, you can only have a single EXPORT_SYMBOL per line, 45 * and CPP can't insert newlines, so we have to repeat everything 46 * at least twice. 47 */ 48 49#define __EXPORT_THUNK(sym) _ASM_NOKPROBE(sym); EXPORT_SYMBOL(sym) 50#define EXPORT_THUNK(reg) __EXPORT_THUNK(__x86_indirect_thunk_ ## reg) 51#define EXPORT_RETPOLINE(reg) __EXPORT_THUNK(__x86_retpoline_ ## reg) 52 53#undef GEN 54#define GEN(reg) THUNK reg 55#include <asm/GEN-for-each-reg.h> 56 57#undef GEN 58#define GEN(reg) EXPORT_THUNK(reg) 59#include <asm/GEN-for-each-reg.h> 60 61#undef GEN 62#define GEN(reg) EXPORT_RETPOLINE(reg) 63#include <asm/GEN-for-each-reg.h> 64