Skip to content

Commit 4535e1a

Browse files
bp3tk0vtorvalds
authored andcommitted
x86/bugs: Fix the SRSO mitigation on Zen3/4
The original version of the mitigation would patch in the calls to the untraining routines directly. That is, the alternative() in UNTRAIN_RET will patch in the CALL to srso_alias_untrain_ret() directly. However, even if commit e7c25c4 ("x86/cpu: Cleanup the untrain mess") meant well in trying to clean up the situation, due to micro- architectural reasons, the untraining routine srso_alias_untrain_ret() must be the target of a CALL instruction and not of a JMP instruction as it is done now. Reshuffle the alternative macros to accomplish that. Fixes: e7c25c4 ("x86/cpu: Cleanup the untrain mess") Signed-off-by: Borislav Petkov (AMD) <[email protected]> Reviewed-by: Ingo Molnar <[email protected]> Cc: [email protected] Signed-off-by: Linus Torvalds <[email protected]>
1 parent 091619b commit 4535e1a

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <asm/asm.h>
1515
#include <asm/fred.h>
1616
#include <asm/gsseg.h>
17+
#include <asm/nospec-branch.h>
1718

1819
#ifndef CONFIG_X86_CMPXCHG64
1920
extern void cmpxchg8b_emu(void);

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

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,20 @@
262262
.Lskip_rsb_\@:
263263
.endm
264264

265+
/*
266+
* The CALL to srso_alias_untrain_ret() must be patched in directly at
267+
* the spot where untraining must be done, ie., srso_alias_untrain_ret()
268+
* must be the target of a CALL instruction instead of indirectly
269+
* jumping to a wrapper which then calls it. Therefore, this macro is
270+
* called outside of __UNTRAIN_RET below, for the time being, before the
271+
* kernel can support nested alternatives with arbitrary nesting.
272+
*/
273+
.macro CALL_UNTRAIN_RET
265274
#if defined(CONFIG_MITIGATION_UNRET_ENTRY) || defined(CONFIG_MITIGATION_SRSO)
266-
#define CALL_UNTRAIN_RET "call entry_untrain_ret"
267-
#else
268-
#define CALL_UNTRAIN_RET ""
275+
ALTERNATIVE_2 "", "call entry_untrain_ret", X86_FEATURE_UNRET, \
276+
"call srso_alias_untrain_ret", X86_FEATURE_SRSO_ALIAS
269277
#endif
278+
.endm
270279

271280
/*
272281
* Mitigate RETBleed for AMD/Hygon Zen uarch. Requires KERNEL CR3 because the
@@ -282,8 +291,8 @@
282291
.macro __UNTRAIN_RET ibpb_feature, call_depth_insns
283292
#if defined(CONFIG_MITIGATION_RETHUNK) || defined(CONFIG_MITIGATION_IBPB_ENTRY)
284293
VALIDATE_UNRET_END
285-
ALTERNATIVE_3 "", \
286-
CALL_UNTRAIN_RET, X86_FEATURE_UNRET, \
294+
CALL_UNTRAIN_RET
295+
ALTERNATIVE_2 "", \
287296
"call entry_ibpb", \ibpb_feature, \
288297
__stringify(\call_depth_insns), X86_FEATURE_CALL_DEPTH
289298
#endif
@@ -342,6 +351,8 @@ extern void retbleed_return_thunk(void);
342351
static inline void retbleed_return_thunk(void) {}
343352
#endif
344353

354+
extern void srso_alias_untrain_ret(void);
355+
345356
#ifdef CONFIG_MITIGATION_SRSO
346357
extern void srso_return_thunk(void);
347358
extern void srso_alias_return_thunk(void);

arch/x86/lib/retpoline.S

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ SYM_CODE_START_NOALIGN(srso_alias_untrain_ret)
163163
lfence
164164
jmp srso_alias_return_thunk
165165
SYM_FUNC_END(srso_alias_untrain_ret)
166+
__EXPORT_THUNK(srso_alias_untrain_ret)
166167
.popsection
167168

168169
.pushsection .text..__x86.rethunk_safe
@@ -224,10 +225,12 @@ SYM_CODE_START(srso_return_thunk)
224225
SYM_CODE_END(srso_return_thunk)
225226

226227
#define JMP_SRSO_UNTRAIN_RET "jmp srso_untrain_ret"
227-
#define JMP_SRSO_ALIAS_UNTRAIN_RET "jmp srso_alias_untrain_ret"
228228
#else /* !CONFIG_MITIGATION_SRSO */
229+
/* Dummy for the alternative in CALL_UNTRAIN_RET. */
230+
SYM_CODE_START(srso_alias_untrain_ret)
231+
RET
232+
SYM_FUNC_END(srso_alias_untrain_ret)
229233
#define JMP_SRSO_UNTRAIN_RET "ud2"
230-
#define JMP_SRSO_ALIAS_UNTRAIN_RET "ud2"
231234
#endif /* CONFIG_MITIGATION_SRSO */
232235

233236
#ifdef CONFIG_MITIGATION_UNRET_ENTRY
@@ -319,9 +322,7 @@ SYM_FUNC_END(retbleed_untrain_ret)
319322
#if defined(CONFIG_MITIGATION_UNRET_ENTRY) || defined(CONFIG_MITIGATION_SRSO)
320323

321324
SYM_FUNC_START(entry_untrain_ret)
322-
ALTERNATIVE_2 JMP_RETBLEED_UNTRAIN_RET, \
323-
JMP_SRSO_UNTRAIN_RET, X86_FEATURE_SRSO, \
324-
JMP_SRSO_ALIAS_UNTRAIN_RET, X86_FEATURE_SRSO_ALIAS
325+
ALTERNATIVE JMP_RETBLEED_UNTRAIN_RET, JMP_SRSO_UNTRAIN_RET, X86_FEATURE_SRSO
325326
SYM_FUNC_END(entry_untrain_ret)
326327
__EXPORT_THUNK(entry_untrain_ret)
327328

0 commit comments

Comments
 (0)