Skip to content

Commit bd57853

Browse files
pa1guptagregkh
authored andcommitted
x86/its: Align RETs in BHB clear sequence to avoid thunking
commit f0cd709 upstream. The software mitigation for BHI is to execute BHB clear sequence at syscall entry, and possibly after a cBPF program. ITS mitigation thunks RETs in the lower half of the cacheline. This causes the RETs in the BHB clear sequence to be thunked as well, adding unnecessary branches to the BHB clear sequence. Since the sequence is in hot path, align the RET instructions in the sequence to avoid thunking. This is how disassembly clear_bhb_loop() looks like after this change: 0x44 <+4>: mov $0x5,%ecx 0x49 <+9>: call 0xffffffff81001d9b <clear_bhb_loop+91> 0x4e <+14>: jmp 0xffffffff81001de5 <clear_bhb_loop+165> 0x53 <+19>: int3 ... 0x9b <+91>: call 0xffffffff81001dce <clear_bhb_loop+142> 0xa0 <+96>: ret 0xa1 <+97>: int3 ... 0xce <+142>: mov $0x5,%eax 0xd3 <+147>: jmp 0xffffffff81001dd6 <clear_bhb_loop+150> 0xd5 <+149>: nop 0xd6 <+150>: sub $0x1,%eax 0xd9 <+153>: jne 0xffffffff81001dd3 <clear_bhb_loop+147> 0xdb <+155>: sub $0x1,%ecx 0xde <+158>: jne 0xffffffff81001d9b <clear_bhb_loop+91> 0xe0 <+160>: ret 0xe1 <+161>: int3 0xe2 <+162>: int3 0xe3 <+163>: int3 0xe4 <+164>: int3 0xe5 <+165>: lfence 0xe8 <+168>: pop %rbp 0xe9 <+169>: ret Suggested-by: Andrew Cooper <[email protected]> Signed-off-by: Pawan Gupta <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Reviewed-by: Alexandre Chartre <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 9f132c0 commit bd57853

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

arch/x86/entry/entry_64.S

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,7 +1524,9 @@ SYM_CODE_END(rewind_stack_and_make_dead)
15241524
* ORC to unwind properly.
15251525
*
15261526
* The alignment is for performance and not for safety, and may be safely
1527-
* refactored in the future if needed.
1527+
* refactored in the future if needed. The .skips are for safety, to ensure
1528+
* that all RETs are in the second half of a cacheline to mitigate Indirect
1529+
* Target Selection, rather than taking the slowpath via its_return_thunk.
15281530
*/
15291531
SYM_FUNC_START(clear_bhb_loop)
15301532
push %rbp
@@ -1534,18 +1536,30 @@ SYM_FUNC_START(clear_bhb_loop)
15341536
call 1f
15351537
jmp 5f
15361538
.align 64, 0xcc
1539+
/*
1540+
* Shift instructions so that the RET is in the upper half of the
1541+
* cacheline and don't take the slowpath to its_return_thunk.
1542+
*/
1543+
.skip 32 - (.Lret1 - 1f), 0xcc
15371544
ANNOTATE_INTRA_FUNCTION_CALL
15381545
1: call 2f
1539-
RET
1546+
.Lret1: RET
15401547
.align 64, 0xcc
1548+
/*
1549+
* As above shift instructions for RET at .Lret2 as well.
1550+
*
1551+
* This should be ideally be: .skip 32 - (.Lret2 - 2f), 0xcc
1552+
* but some Clang versions (e.g. 18) don't like this.
1553+
*/
1554+
.skip 32 - 18, 0xcc
15411555
2: movl $5, %eax
15421556
3: jmp 4f
15431557
nop
15441558
4: sub $1, %eax
15451559
jnz 3b
15461560
sub $1, %ecx
15471561
jnz 1b
1548-
RET
1562+
.Lret2: RET
15491563
5: lfence
15501564
pop %rbp
15511565
RET

0 commit comments

Comments
 (0)