提交 2daaa3b3 编写于 作者: P Peter Zijlstra 提交者: openeuler-sync-bot

x86/nospec: Unwreck the RSB stuffing

stable inclusion
from stable-v5.10.141
commit adee8f3082b01e5dab620d651e3ec75f57c0c855
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I685FC

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=adee8f3082b01e5dab620d651e3ec75f57c0c855

--------------------------------

commit 4e3aa923 upstream.

Commit 2b129932 ("x86/speculation: Add RSB VM Exit protections")
made a right mess of the RSB stuffing, rewrite the whole thing to not
suck.

Thanks to Andrew for the enlightening comment about Post-Barrier RSB
things so we can make this code less magical.

Cc: stable@vger.kernel.org
Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YvuNdDWoUZSBjYcm@worktop.programming.kicks-ass.net
[bwh: Backported to 5.10: adjust context]
Signed-off-by: NBen Hutchings <benh@debian.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NJialin Zhang <zhangjialin11@huawei.com>
Reviewed-by: NZheng Zengkai <zhengzengkai@huawei.com>
(cherry picked from commit 4b944c0f)
上级 3b8e63fa
...@@ -35,35 +35,46 @@ ...@@ -35,35 +35,46 @@
#define RSB_CLEAR_LOOPS 32 /* To forcibly overwrite all entries */ #define RSB_CLEAR_LOOPS 32 /* To forcibly overwrite all entries */
/* /*
* Common helper for __FILL_RETURN_BUFFER and __FILL_ONE_RETURN.
*/
#define __FILL_RETURN_SLOT \
ANNOTATE_INTRA_FUNCTION_CALL; \
call 772f; \
int3; \
772:
/*
* Stuff the entire RSB.
*
* Google experimented with loop-unrolling and this turned out to be * Google experimented with loop-unrolling and this turned out to be
* the optimal version — two calls, each with their own speculation * the optimal version — two calls, each with their own speculation
* trap should their return address end up getting used, in a loop. * trap should their return address end up getting used, in a loop.
*/ */
#define __FILL_RETURN_BUFFER(reg, nr, sp) \ #define __FILL_RETURN_BUFFER(reg, nr) \
mov $(nr/2), reg; \ mov $(nr/2), reg; \
771: \ 771: \
ANNOTATE_INTRA_FUNCTION_CALL; \ __FILL_RETURN_SLOT \
call 772f; \ __FILL_RETURN_SLOT \
773: /* speculation trap */ \ add $(BITS_PER_LONG/8) * 2, %_ASM_SP; \
UNWIND_HINT_EMPTY; \
pause; \
lfence; \
jmp 773b; \
772: \
ANNOTATE_INTRA_FUNCTION_CALL; \
call 774f; \
775: /* speculation trap */ \
UNWIND_HINT_EMPTY; \
pause; \
lfence; \
jmp 775b; \
774: \
add $(BITS_PER_LONG/8) * 2, sp; \
dec reg; \ dec reg; \
jnz 771b; \ jnz 771b; \
/* barrier for jnz misprediction */ \ /* barrier for jnz misprediction */ \
lfence; lfence;
/*
* Stuff a single RSB slot.
*
* To mitigate Post-Barrier RSB speculation, one CALL instruction must be
* forced to retire before letting a RET instruction execute.
*
* On PBRSB-vulnerable CPUs, it is not safe for a RET to be executed
* before this point.
*/
#define __FILL_ONE_RETURN \
__FILL_RETURN_SLOT \
add $(BITS_PER_LONG/8), %_ASM_SP; \
lfence;
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
/* /*
...@@ -120,28 +131,15 @@ ...@@ -120,28 +131,15 @@
#endif #endif
.endm .endm
.macro ISSUE_UNBALANCED_RET_GUARD
ANNOTATE_INTRA_FUNCTION_CALL
call .Lunbalanced_ret_guard_\@
int3
.Lunbalanced_ret_guard_\@:
add $(BITS_PER_LONG/8), %_ASM_SP
lfence
.endm
/* /*
* A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP
* monstrosity above, manually. * monstrosity above, manually.
*/ */
.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2 .macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2=ALT_NOT(X86_FEATURE_ALWAYS)
.ifb \ftr2 ALTERNATIVE_2 "jmp .Lskip_rsb_\@", \
ALTERNATIVE "jmp .Lskip_rsb_\@", "", \ftr __stringify(__FILL_RETURN_BUFFER(\reg,\nr)), \ftr, \
.else __stringify(__FILL_ONE_RETURN), \ftr2
ALTERNATIVE_2 "jmp .Lskip_rsb_\@", "", \ftr, "jmp .Lunbalanced_\@", \ftr2
.endif
__FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP)
.Lunbalanced_\@:
ISSUE_UNBALANCED_RET_GUARD
.Lskip_rsb_\@: .Lskip_rsb_\@:
.endm .endm
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册