1/*
2 * Implement __x86_indirect_thunk_* symbols for use with compatbile compilers
3 * and the -mindirect-branch=thunk-extern -mindirect-branch-register options.
4 *
5 * Copyright (c) 2017-2018 Citrix Systems Ltd.
6 *
7 * This source code is licensed under the GNU General Public License,
8 * Version 2.  See the file COPYING for more details.
9 */
10        .file __FILE__
11
12#include <asm/asm_defns.h>
13
14.macro IND_THUNK_RETPOLINE reg:req
15        call 2f
161:
17        lfence
18        jmp 1b
192:
20        mov %\reg, (%rsp)
21        ret
22.endm
23
24.macro IND_THUNK_LFENCE reg:req
25        lfence
26        jmp *%\reg
27        int3 /* Halt straight-line speculation */
28.endm
29
30.macro IND_THUNK_JMP reg:req
31        jmp *%\reg
32        int3 /* Halt straight-line speculation */
33.endm
34
35/*
36 * Build the __x86_indirect_thunk_* symbols.  Execution lands on an
37 * alternative patch point which implements one of the above THUNK_*'s
38 */
39.macro GEN_INDIRECT_THUNK reg:req
40        .section .text.__x86_indirect_thunk_\reg, "ax", @progbits
41
42ENTRY(__x86_indirect_thunk_\reg)
43        ALTERNATIVE_2 __stringify(IND_THUNK_RETPOLINE \reg),              \
44        __stringify(IND_THUNK_LFENCE \reg), X86_FEATURE_IND_THUNK_LFENCE, \
45        __stringify(IND_THUNK_JMP \reg),    X86_FEATURE_IND_THUNK_JMP
46
47        .size __x86_indirect_thunk_\reg, . - __x86_indirect_thunk_\reg
48        .type __x86_indirect_thunk_\reg, @function
49.endm
50
51/* Instantiate GEN_INDIRECT_THUNK for each register except %rsp. */
52.irp reg, ax, cx, dx, bx, bp, si, di, 8, 9, 10, 11, 12, 13, 14, 15
53        GEN_INDIRECT_THUNK reg=r\reg
54.endr
55