176b04384SDavid Woodhouse/* SPDX-License-Identifier: GPL-2.0 */ 276b04384SDavid Woodhouse 376b04384SDavid Woodhouse#include <linux/stringify.h> 476b04384SDavid Woodhouse#include <linux/linkage.h> 576b04384SDavid Woodhouse#include <asm/dwarf2.h> 676b04384SDavid Woodhouse#include <asm/cpufeatures.h> 7*5e21a3ecSJuergen Gross#include <asm/alternative.h> 876b04384SDavid Woodhouse#include <asm/export.h> 976b04384SDavid Woodhouse#include <asm/nospec-branch.h> 10cc1ac9c7SPeter Zijlstra#include <asm/unwind_hints.h> 11cc1ac9c7SPeter Zijlstra#include <asm/frame.h> 1276b04384SDavid Woodhouse 1376b04384SDavid Woodhouse.macro THUNK reg 14736e80a4SMasami Hiramatsu .section .text.__x86.indirect_thunk 1576b04384SDavid Woodhouse 16cc1ac9c7SPeter Zijlstra .align 32 176dcc5627SJiri SlabySYM_FUNC_START(__x86_indirect_thunk_\reg) 18cc1ac9c7SPeter Zijlstra JMP_NOSPEC \reg 196dcc5627SJiri SlabySYM_FUNC_END(__x86_indirect_thunk_\reg) 20cc1ac9c7SPeter Zijlstra 21cc1ac9c7SPeter ZijlstraSYM_FUNC_START_NOALIGN(__x86_retpoline_\reg) 22cc1ac9c7SPeter Zijlstra ANNOTATE_INTRA_FUNCTION_CALL 23cc1ac9c7SPeter Zijlstra call .Ldo_rop_\@ 24cc1ac9c7SPeter Zijlstra.Lspec_trap_\@: 25cc1ac9c7SPeter Zijlstra UNWIND_HINT_EMPTY 26cc1ac9c7SPeter Zijlstra pause 27cc1ac9c7SPeter Zijlstra lfence 28cc1ac9c7SPeter Zijlstra jmp .Lspec_trap_\@ 29cc1ac9c7SPeter Zijlstra.Ldo_rop_\@: 30cc1ac9c7SPeter Zijlstra mov %\reg, (%_ASM_SP) 31b735bd3eSJosh Poimboeuf UNWIND_HINT_FUNC 32cc1ac9c7SPeter Zijlstra ret 33cc1ac9c7SPeter ZijlstraSYM_FUNC_END(__x86_retpoline_\reg) 34cc1ac9c7SPeter Zijlstra 3576b04384SDavid Woodhouse.endm 3676b04384SDavid Woodhouse 3776b04384SDavid Woodhouse/* 3876b04384SDavid Woodhouse * Despite being an assembler file we can't just use .irp here 3976b04384SDavid Woodhouse * because __KSYM_DEPS__ only uses the C preprocessor and would 4076b04384SDavid Woodhouse * only see one instance of "__x86_indirect_thunk_\reg" rather 4176b04384SDavid Woodhouse * than one per register with the correct names. So we do it 4276b04384SDavid Woodhouse * the simple and nasty way... 43ca3f0d80SPeter Zijlstra * 44ca3f0d80SPeter Zijlstra * Worse, you can only have a single EXPORT_SYMBOL per line, 45ca3f0d80SPeter Zijlstra * and CPP can't insert newlines, so we have to repeat everything 46ca3f0d80SPeter Zijlstra * at least twice. 4776b04384SDavid Woodhouse */ 48ca3f0d80SPeter Zijlstra 49c1804a23SMasami Hiramatsu#define __EXPORT_THUNK(sym) _ASM_NOKPROBE(sym); EXPORT_SYMBOL(sym) 50c1804a23SMasami Hiramatsu#define EXPORT_THUNK(reg) __EXPORT_THUNK(__x86_indirect_thunk_ ## reg) 51cc1ac9c7SPeter Zijlstra#define EXPORT_RETPOLINE(reg) __EXPORT_THUNK(__x86_retpoline_ ## reg) 5276b04384SDavid Woodhouse 53ca3f0d80SPeter Zijlstra#undef GEN 54ca3f0d80SPeter Zijlstra#define GEN(reg) THUNK reg 55ca3f0d80SPeter Zijlstra#include <asm/GEN-for-each-reg.h> 56ca3f0d80SPeter Zijlstra 57ca3f0d80SPeter Zijlstra#undef GEN 58ca3f0d80SPeter Zijlstra#define GEN(reg) EXPORT_THUNK(reg) 59ca3f0d80SPeter Zijlstra#include <asm/GEN-for-each-reg.h> 60ca3f0d80SPeter Zijlstra 61cc1ac9c7SPeter Zijlstra#undef GEN 62cc1ac9c7SPeter Zijlstra#define GEN(reg) EXPORT_RETPOLINE(reg) 63cc1ac9c7SPeter Zijlstra#include <asm/GEN-for-each-reg.h> 64