Skip to content

Commit 1192518

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
x86/retpoline: Simplify retpolines
Due to: c9c324d ("objtool: Support stack layout changes in alternatives") it is now possible to simplify the retpolines. Currently our retpolines consist of 2 symbols: - __x86_indirect_thunk_\reg: the compiler target - __x86_retpoline_\reg: the actual retpoline. Both are consecutive in code and aligned such that for any one register they both live in the same cacheline: 0000000000000000 <__x86_indirect_thunk_rax>: 0: ff e0 jmpq *%rax 2: 90 nop 3: 90 nop 4: 90 nop 0000000000000005 <__x86_retpoline_rax>: 5: e8 07 00 00 00 callq 11 <__x86_retpoline_rax+0xc> a: f3 90 pause c: 0f ae e8 lfence f: eb f9 jmp a <__x86_retpoline_rax+0x5> 11: 48 89 04 24 mov %rax,(%rsp) 15: c3 retq 16: 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:0x0(%rax,%rax,1) The thunk is an alternative_2, where one option is a JMP to the retpoline. This was done so that objtool didn't need to deal with alternatives with stack ops. But that problem has been solved, so now it is possible to fold the entire retpoline into the alternative to simplify and consolidate unused bytes: 0000000000000000 <__x86_indirect_thunk_rax>: 0: ff e0 jmpq *%rax 2: 90 nop 3: 90 nop 4: 90 nop 5: 90 nop 6: 90 nop 7: 90 nop 8: 90 nop 9: 90 nop a: 90 nop b: 90 nop c: 90 nop d: 90 nop e: 90 nop f: 90 nop 10: 90 nop 11: 66 66 2e 0f 1f 84 00 00 00 00 00 data16 nopw %cs:0x0(%rax,%rax,1) 1c: 0f 1f 40 00 nopl 0x0(%rax) Notice that since the longest alternative sequence is now: 0: e8 07 00 00 00 callq c <.altinstr_replacement+0xc> 5: f3 90 pause 7: 0f ae e8 lfence a: eb f9 jmp 5 <.altinstr_replacement+0x5> c: 48 89 04 24 mov %rax,(%rsp) 10: c3 retq 17 bytes, we have 15 bytes NOP at the end of our 32 byte slot. (IOW, if we can shrink the retpoline by 1 byte we can pack it more densely). [ bp: Massage commit message. ] Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 23c1ad5 commit 1192518

File tree

4 files changed

+21
-29
lines changed

4 files changed

+21
-29
lines changed

arch/x86/include/asm/asm-prototypes.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,8 @@ extern void cmpxchg8b_emu(void);
2222
#define DECL_INDIRECT_THUNK(reg) \
2323
extern asmlinkage void __x86_indirect_thunk_ ## reg (void);
2424

25-
#define DECL_RETPOLINE(reg) \
26-
extern asmlinkage void __x86_retpoline_ ## reg (void);
27-
2825
#undef GEN
2926
#define GEN(reg) DECL_INDIRECT_THUNK(reg)
3027
#include <asm/GEN-for-each-reg.h>
3128

32-
#undef GEN
33-
#define GEN(reg) DECL_RETPOLINE(reg)
34-
#include <asm/GEN-for-each-reg.h>
35-
3629
#endif /* CONFIG_RETPOLINE */

arch/x86/include/asm/nospec-branch.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
.macro JMP_NOSPEC reg:req
8181
#ifdef CONFIG_RETPOLINE
8282
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
83-
__stringify(jmp __x86_retpoline_\reg), X86_FEATURE_RETPOLINE, \
83+
__stringify(jmp __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \
8484
__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_AMD
8585
#else
8686
jmp *%\reg
@@ -90,7 +90,7 @@
9090
.macro CALL_NOSPEC reg:req
9191
#ifdef CONFIG_RETPOLINE
9292
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *%\reg), \
93-
__stringify(call __x86_retpoline_\reg), X86_FEATURE_RETPOLINE, \
93+
__stringify(call __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \
9494
__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_AMD
9595
#else
9696
call *%\reg
@@ -128,7 +128,7 @@
128128
ALTERNATIVE_2( \
129129
ANNOTATE_RETPOLINE_SAFE \
130130
"call *%[thunk_target]\n", \
131-
"call __x86_retpoline_%V[thunk_target]\n", \
131+
"call __x86_indirect_thunk_%V[thunk_target]\n", \
132132
X86_FEATURE_RETPOLINE, \
133133
"lfence;\n" \
134134
ANNOTATE_RETPOLINE_SAFE \

arch/x86/lib/retpoline.S

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,31 @@
1010
#include <asm/unwind_hints.h>
1111
#include <asm/frame.h>
1212

13-
.macro THUNK reg
14-
.section .text.__x86.indirect_thunk
15-
16-
.align 32
17-
SYM_FUNC_START(__x86_indirect_thunk_\reg)
18-
JMP_NOSPEC \reg
19-
SYM_FUNC_END(__x86_indirect_thunk_\reg)
20-
21-
SYM_FUNC_START_NOALIGN(__x86_retpoline_\reg)
13+
.macro RETPOLINE reg
2214
ANNOTATE_INTRA_FUNCTION_CALL
23-
call .Ldo_rop_\@
15+
call .Ldo_rop_\@
2416
.Lspec_trap_\@:
2517
UNWIND_HINT_EMPTY
2618
pause
2719
lfence
28-
jmp .Lspec_trap_\@
20+
jmp .Lspec_trap_\@
2921
.Ldo_rop_\@:
30-
mov %\reg, (%_ASM_SP)
22+
mov %\reg, (%_ASM_SP)
3123
UNWIND_HINT_FUNC
3224
ret
33-
SYM_FUNC_END(__x86_retpoline_\reg)
25+
.endm
26+
27+
.macro THUNK reg
28+
.section .text.__x86.indirect_thunk
29+
30+
.align 32
31+
SYM_FUNC_START(__x86_indirect_thunk_\reg)
32+
33+
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
34+
__stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \
35+
__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_AMD
36+
37+
SYM_FUNC_END(__x86_indirect_thunk_\reg)
3438

3539
.endm
3640

@@ -48,7 +52,6 @@ SYM_FUNC_END(__x86_retpoline_\reg)
4852

4953
#define __EXPORT_THUNK(sym) _ASM_NOKPROBE(sym); EXPORT_SYMBOL(sym)
5054
#define EXPORT_THUNK(reg) __EXPORT_THUNK(__x86_indirect_thunk_ ## reg)
51-
#define EXPORT_RETPOLINE(reg) __EXPORT_THUNK(__x86_retpoline_ ## reg)
5255

5356
#undef GEN
5457
#define GEN(reg) THUNK reg
@@ -58,6 +61,3 @@ SYM_FUNC_END(__x86_retpoline_\reg)
5861
#define GEN(reg) EXPORT_THUNK(reg)
5962
#include <asm/GEN-for-each-reg.h>
6063

61-
#undef GEN
62-
#define GEN(reg) EXPORT_RETPOLINE(reg)
63-
#include <asm/GEN-for-each-reg.h>

tools/objtool/check.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -872,8 +872,7 @@ static int add_jump_destinations(struct objtool_file *file)
872872
} else if (reloc->sym->type == STT_SECTION) {
873873
dest_sec = reloc->sym->sec;
874874
dest_off = arch_dest_reloc_offset(reloc->addend);
875-
} else if (!strncmp(reloc->sym->name, "__x86_indirect_thunk_", 21) ||
876-
!strncmp(reloc->sym->name, "__x86_retpoline_", 16)) {
875+
} else if (!strncmp(reloc->sym->name, "__x86_indirect_thunk_", 21)) {
877876
/*
878877
* Retpoline jumps are really dynamic jumps in
879878
* disguise, so convert them accordingly.

0 commit comments

Comments
 (0)