x86/retpoline: Add initial retpoline support
Enable the use of -mindirect-branch=thunk-extern in newer GCC, and provide
the corresponding thunks. Provide assembler macros for invoking the thunks
in the same way that GCC does, from native and inline assembler.
This adds X86_FEATURE_RETPOLINE and sets it by default on all CPUs. In
some circumstances, IBRS microcode features may be used instead, and the
retpoline can be disabled.
On AMD CPUs if lfence is serialising, the retpoline can be dramatically
simplified to a simple "lfence; jmp *\reg". A future patch, after it has
been verified that lfence really is serialising in all circumstances, can
enable this by setting the X86_FEATURE_RETPOLINE_AMD feature bit in addition
to X86_FEATURE_RETPOLINE.
Do not align the retpoline in the altinstr section, because there is no
guarantee that it stays aligned when it's copied over the oldinstr during
alternative patching.
[ Andi Kleen: Rename the macros, add CONFIG_RETPOLINE option, export thunks]
[ tglx: Put actual function CALL/JMP in front of the macros, convert to
symbolic labels ]
[ dwmw2: Convert back to numeric labels, merge objtool fixes ]
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: gnomes@lxorguk.ukuu.org.uk
Cc: Rik van Riel <riel@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: thomas.lendacky@amd.com
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kees Cook <keescook@google.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
Cc: Paul Turner <pjt@google.com>
Link: https://lkml.kernel.org/r/1515707194-20531-4-git-send-email-dwmw@amazon.co.uk
2018-01-11 21:46:25 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
|
2023-08-06 23:59:56 +09:00
|
|
|
#include <linux/export.h>
|
x86/retpoline: Add initial retpoline support
Enable the use of -mindirect-branch=thunk-extern in newer GCC, and provide
the corresponding thunks. Provide assembler macros for invoking the thunks
in the same way that GCC does, from native and inline assembler.
This adds X86_FEATURE_RETPOLINE and sets it by default on all CPUs. In
some circumstances, IBRS microcode features may be used instead, and the
retpoline can be disabled.
On AMD CPUs if lfence is serialising, the retpoline can be dramatically
simplified to a simple "lfence; jmp *\reg". A future patch, after it has
been verified that lfence really is serialising in all circumstances, can
enable this by setting the X86_FEATURE_RETPOLINE_AMD feature bit in addition
to X86_FEATURE_RETPOLINE.
Do not align the retpoline in the altinstr section, because there is no
guarantee that it stays aligned when it's copied over the oldinstr during
alternative patching.
[ Andi Kleen: Rename the macros, add CONFIG_RETPOLINE option, export thunks]
[ tglx: Put actual function CALL/JMP in front of the macros, convert to
symbolic labels ]
[ dwmw2: Convert back to numeric labels, merge objtool fixes ]
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: gnomes@lxorguk.ukuu.org.uk
Cc: Rik van Riel <riel@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: thomas.lendacky@amd.com
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kees Cook <keescook@google.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
Cc: Paul Turner <pjt@google.com>
Link: https://lkml.kernel.org/r/1515707194-20531-4-git-send-email-dwmw@amazon.co.uk
2018-01-11 21:46:25 +00:00
|
|
|
#include <linux/stringify.h>
|
|
|
|
#include <linux/linkage.h>
|
|
|
|
#include <asm/dwarf2.h>
|
|
|
|
#include <asm/cpufeatures.h>
|
2021-03-11 15:23:06 +01:00
|
|
|
#include <asm/alternative.h>
|
2022-09-15 13:11:27 +02:00
|
|
|
#include <asm/asm-offsets.h>
|
x86/retpoline: Add initial retpoline support
Enable the use of -mindirect-branch=thunk-extern in newer GCC, and provide
the corresponding thunks. Provide assembler macros for invoking the thunks
in the same way that GCC does, from native and inline assembler.
This adds X86_FEATURE_RETPOLINE and sets it by default on all CPUs. In
some circumstances, IBRS microcode features may be used instead, and the
retpoline can be disabled.
On AMD CPUs if lfence is serialising, the retpoline can be dramatically
simplified to a simple "lfence; jmp *\reg". A future patch, after it has
been verified that lfence really is serialising in all circumstances, can
enable this by setting the X86_FEATURE_RETPOLINE_AMD feature bit in addition
to X86_FEATURE_RETPOLINE.
Do not align the retpoline in the altinstr section, because there is no
guarantee that it stays aligned when it's copied over the oldinstr during
alternative patching.
[ Andi Kleen: Rename the macros, add CONFIG_RETPOLINE option, export thunks]
[ tglx: Put actual function CALL/JMP in front of the macros, convert to
symbolic labels ]
[ dwmw2: Convert back to numeric labels, merge objtool fixes ]
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: gnomes@lxorguk.ukuu.org.uk
Cc: Rik van Riel <riel@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: thomas.lendacky@amd.com
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kees Cook <keescook@google.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
Cc: Paul Turner <pjt@google.com>
Link: https://lkml.kernel.org/r/1515707194-20531-4-git-send-email-dwmw@amazon.co.uk
2018-01-11 21:46:25 +00:00
|
|
|
#include <asm/nospec-branch.h>
|
2020-04-16 14:34:26 +02:00
|
|
|
#include <asm/unwind_hints.h>
|
2022-09-15 13:11:27 +02:00
|
|
|
#include <asm/percpu.h>
|
2020-04-16 14:34:26 +02:00
|
|
|
#include <asm/frame.h>
|
2023-06-28 11:02:39 +02:00
|
|
|
#include <asm/nops.h>
|
x86/retpoline: Add initial retpoline support
Enable the use of -mindirect-branch=thunk-extern in newer GCC, and provide
the corresponding thunks. Provide assembler macros for invoking the thunks
in the same way that GCC does, from native and inline assembler.
This adds X86_FEATURE_RETPOLINE and sets it by default on all CPUs. In
some circumstances, IBRS microcode features may be used instead, and the
retpoline can be disabled.
On AMD CPUs if lfence is serialising, the retpoline can be dramatically
simplified to a simple "lfence; jmp *\reg". A future patch, after it has
been verified that lfence really is serialising in all circumstances, can
enable this by setting the X86_FEATURE_RETPOLINE_AMD feature bit in addition
to X86_FEATURE_RETPOLINE.
Do not align the retpoline in the altinstr section, because there is no
guarantee that it stays aligned when it's copied over the oldinstr during
alternative patching.
[ Andi Kleen: Rename the macros, add CONFIG_RETPOLINE option, export thunks]
[ tglx: Put actual function CALL/JMP in front of the macros, convert to
symbolic labels ]
[ dwmw2: Convert back to numeric labels, merge objtool fixes ]
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: gnomes@lxorguk.ukuu.org.uk
Cc: Rik van Riel <riel@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: thomas.lendacky@amd.com
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kees Cook <keescook@google.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
Cc: Paul Turner <pjt@google.com>
Link: https://lkml.kernel.org/r/1515707194-20531-4-git-send-email-dwmw@amazon.co.uk
2018-01-11 21:46:25 +00:00
|
|
|
|
2023-07-11 11:19:51 +02:00
|
|
|
.section .text..__x86.indirect_thunk
|
2021-03-26 16:12:15 +01:00
|
|
|
|
2022-09-15 13:11:28 +02:00
|
|
|
|
|
|
|
.macro POLINE reg
|
2020-04-16 14:34:26 +02:00
|
|
|
ANNOTATE_INTRA_FUNCTION_CALL
|
x86/retpoline: Simplify retpolines
Due to:
c9c324dc22aa ("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) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lkml.kernel.org/r/20210326151259.506071949@infradead.org
2021-03-26 16:12:02 +01:00
|
|
|
call .Ldo_rop_\@
|
2022-09-15 13:11:28 +02:00
|
|
|
int3
|
2020-04-16 14:34:26 +02:00
|
|
|
.Ldo_rop_\@:
|
x86/retpoline: Simplify retpolines
Due to:
c9c324dc22aa ("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) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lkml.kernel.org/r/20210326151259.506071949@infradead.org
2021-03-26 16:12:02 +01:00
|
|
|
mov %\reg, (%_ASM_SP)
|
2021-01-21 15:29:24 -06:00
|
|
|
UNWIND_HINT_FUNC
|
2022-09-15 13:11:28 +02:00
|
|
|
.endm
|
|
|
|
|
|
|
|
.macro RETPOLINE reg
|
|
|
|
POLINE \reg
|
2021-12-04 14:43:40 +01:00
|
|
|
RET
|
x86/retpoline: Simplify retpolines
Due to:
c9c324dc22aa ("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) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lkml.kernel.org/r/20210326151259.506071949@infradead.org
2021-03-26 16:12:02 +01:00
|
|
|
.endm
|
|
|
|
|
|
|
|
.macro THUNK reg
|
|
|
|
|
2021-10-26 14:01:41 +02:00
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
|
|
SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL)
|
2023-03-01 07:13:12 -08:00
|
|
|
UNWIND_HINT_UNDEFINED
|
2022-04-18 09:50:23 -07:00
|
|
|
ANNOTATE_NOENDBR
|
x86/retpoline: Simplify retpolines
Due to:
c9c324dc22aa ("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) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lkml.kernel.org/r/20210326151259.506071949@infradead.org
2021-03-26 16:12:02 +01:00
|
|
|
|
2022-06-14 23:15:35 +02:00
|
|
|
ALTERNATIVE_2 __stringify(RETPOLINE \reg), \
|
|
|
|
__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg; int3), X86_FEATURE_RETPOLINE_LFENCE, \
|
|
|
|
__stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), ALT_NOT(X86_FEATURE_RETPOLINE)
|
x86/retpoline: Simplify retpolines
Due to:
c9c324dc22aa ("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) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lkml.kernel.org/r/20210326151259.506071949@infradead.org
2021-03-26 16:12:02 +01:00
|
|
|
|
x86/retpoline: Add initial retpoline support
Enable the use of -mindirect-branch=thunk-extern in newer GCC, and provide
the corresponding thunks. Provide assembler macros for invoking the thunks
in the same way that GCC does, from native and inline assembler.
This adds X86_FEATURE_RETPOLINE and sets it by default on all CPUs. In
some circumstances, IBRS microcode features may be used instead, and the
retpoline can be disabled.
On AMD CPUs if lfence is serialising, the retpoline can be dramatically
simplified to a simple "lfence; jmp *\reg". A future patch, after it has
been verified that lfence really is serialising in all circumstances, can
enable this by setting the X86_FEATURE_RETPOLINE_AMD feature bit in addition
to X86_FEATURE_RETPOLINE.
Do not align the retpoline in the altinstr section, because there is no
guarantee that it stays aligned when it's copied over the oldinstr during
alternative patching.
[ Andi Kleen: Rename the macros, add CONFIG_RETPOLINE option, export thunks]
[ tglx: Put actual function CALL/JMP in front of the macros, convert to
symbolic labels ]
[ dwmw2: Convert back to numeric labels, merge objtool fixes ]
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: gnomes@lxorguk.ukuu.org.uk
Cc: Rik van Riel <riel@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: thomas.lendacky@amd.com
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kees Cook <keescook@google.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
Cc: Paul Turner <pjt@google.com>
Link: https://lkml.kernel.org/r/1515707194-20531-4-git-send-email-dwmw@amazon.co.uk
2018-01-11 21:46:25 +00:00
|
|
|
.endm
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Despite being an assembler file we can't just use .irp here
|
|
|
|
* because __KSYM_DEPS__ only uses the C preprocessor and would
|
|
|
|
* only see one instance of "__x86_indirect_thunk_\reg" rather
|
|
|
|
* than one per register with the correct names. So we do it
|
|
|
|
* the simple and nasty way...
|
2020-04-22 17:03:22 +02:00
|
|
|
*
|
|
|
|
* Worse, you can only have a single EXPORT_SYMBOL per line,
|
|
|
|
* and CPP can't insert newlines, so we have to repeat everything
|
|
|
|
* at least twice.
|
x86/retpoline: Add initial retpoline support
Enable the use of -mindirect-branch=thunk-extern in newer GCC, and provide
the corresponding thunks. Provide assembler macros for invoking the thunks
in the same way that GCC does, from native and inline assembler.
This adds X86_FEATURE_RETPOLINE and sets it by default on all CPUs. In
some circumstances, IBRS microcode features may be used instead, and the
retpoline can be disabled.
On AMD CPUs if lfence is serialising, the retpoline can be dramatically
simplified to a simple "lfence; jmp *\reg". A future patch, after it has
been verified that lfence really is serialising in all circumstances, can
enable this by setting the X86_FEATURE_RETPOLINE_AMD feature bit in addition
to X86_FEATURE_RETPOLINE.
Do not align the retpoline in the altinstr section, because there is no
guarantee that it stays aligned when it's copied over the oldinstr during
alternative patching.
[ Andi Kleen: Rename the macros, add CONFIG_RETPOLINE option, export thunks]
[ tglx: Put actual function CALL/JMP in front of the macros, convert to
symbolic labels ]
[ dwmw2: Convert back to numeric labels, merge objtool fixes ]
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: gnomes@lxorguk.ukuu.org.uk
Cc: Rik van Riel <riel@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: thomas.lendacky@amd.com
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kees Cook <keescook@google.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
Cc: Paul Turner <pjt@google.com>
Link: https://lkml.kernel.org/r/1515707194-20531-4-git-send-email-dwmw@amazon.co.uk
2018-01-11 21:46:25 +00:00
|
|
|
*/
|
2020-04-22 17:03:22 +02:00
|
|
|
|
|
|
|
#define __EXPORT_THUNK(sym) _ASM_NOKPROBE(sym); EXPORT_SYMBOL(sym)
|
|
|
|
|
2021-10-26 14:01:41 +02:00
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
|
|
SYM_CODE_START(__x86_indirect_thunk_array)
|
|
|
|
|
2020-04-22 17:03:22 +02:00
|
|
|
#define GEN(reg) THUNK reg
|
|
|
|
#include <asm/GEN-for-each-reg.h>
|
|
|
|
#undef GEN
|
2021-10-26 14:01:39 +02:00
|
|
|
|
2021-10-26 14:01:41 +02:00
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
|
|
SYM_CODE_END(__x86_indirect_thunk_array)
|
|
|
|
|
2022-09-15 13:11:28 +02:00
|
|
|
#define GEN(reg) __EXPORT_THUNK(__x86_indirect_thunk_ ## reg)
|
|
|
|
#include <asm/GEN-for-each-reg.h>
|
|
|
|
#undef GEN
|
|
|
|
|
2023-11-21 08:07:30 -08:00
|
|
|
#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
|
2022-09-15 13:11:28 +02:00
|
|
|
.macro CALL_THUNK reg
|
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
|
|
|
|
|
|
SYM_INNER_LABEL(__x86_indirect_call_thunk_\reg, SYM_L_GLOBAL)
|
2023-03-01 07:13:12 -08:00
|
|
|
UNWIND_HINT_UNDEFINED
|
2022-09-15 13:11:28 +02:00
|
|
|
ANNOTATE_NOENDBR
|
|
|
|
|
|
|
|
CALL_DEPTH_ACCOUNT
|
|
|
|
POLINE \reg
|
|
|
|
ANNOTATE_UNRET_SAFE
|
|
|
|
ret
|
|
|
|
int3
|
|
|
|
.endm
|
|
|
|
|
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
|
|
SYM_CODE_START(__x86_indirect_call_thunk_array)
|
|
|
|
|
|
|
|
#define GEN(reg) CALL_THUNK reg
|
|
|
|
#include <asm/GEN-for-each-reg.h>
|
|
|
|
#undef GEN
|
|
|
|
|
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
|
|
SYM_CODE_END(__x86_indirect_call_thunk_array)
|
|
|
|
|
|
|
|
#define GEN(reg) __EXPORT_THUNK(__x86_indirect_call_thunk_ ## reg)
|
2020-04-22 17:03:22 +02:00
|
|
|
#include <asm/GEN-for-each-reg.h>
|
2021-10-26 14:01:39 +02:00
|
|
|
#undef GEN
|
2022-06-14 23:15:36 +02:00
|
|
|
|
2022-09-15 13:11:28 +02:00
|
|
|
.macro JUMP_THUNK reg
|
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
|
|
|
|
|
|
SYM_INNER_LABEL(__x86_indirect_jump_thunk_\reg, SYM_L_GLOBAL)
|
2023-03-01 07:13:12 -08:00
|
|
|
UNWIND_HINT_UNDEFINED
|
2022-09-15 13:11:28 +02:00
|
|
|
ANNOTATE_NOENDBR
|
|
|
|
POLINE \reg
|
|
|
|
ANNOTATE_UNRET_SAFE
|
|
|
|
ret
|
|
|
|
int3
|
|
|
|
.endm
|
|
|
|
|
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
|
|
SYM_CODE_START(__x86_indirect_jump_thunk_array)
|
|
|
|
|
|
|
|
#define GEN(reg) JUMP_THUNK reg
|
|
|
|
#include <asm/GEN-for-each-reg.h>
|
|
|
|
#undef GEN
|
|
|
|
|
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
|
|
SYM_CODE_END(__x86_indirect_jump_thunk_array)
|
|
|
|
|
|
|
|
#define GEN(reg) __EXPORT_THUNK(__x86_indirect_jump_thunk_ ## reg)
|
|
|
|
#include <asm/GEN-for-each-reg.h>
|
|
|
|
#undef GEN
|
|
|
|
#endif
|
2023-09-04 22:05:00 -07:00
|
|
|
|
2023-11-21 08:07:37 -08:00
|
|
|
#ifdef CONFIG_MITIGATION_RETHUNK
|
2022-06-27 22:21:17 +00:00
|
|
|
|
2023-10-20 13:17:14 +02:00
|
|
|
/*
|
|
|
|
* Be careful here: that label cannot really be removed because in
|
|
|
|
* some configurations and toolchains, the JMP __x86_return_thunk the
|
|
|
|
* compiler issues is either a short one or the compiler doesn't use
|
|
|
|
* relocations for same-section JMPs and that breaks the returns
|
|
|
|
* detection logic in apply_returns() and in objtool.
|
|
|
|
*/
|
2023-09-04 22:05:00 -07:00
|
|
|
.section .text..__x86.return_thunk
|
|
|
|
|
2023-11-21 08:07:36 -08:00
|
|
|
#ifdef CONFIG_MITIGATION_SRSO
|
2023-09-04 22:05:00 -07:00
|
|
|
|
2023-06-28 11:02:39 +02:00
|
|
|
/*
|
2023-08-14 13:44:33 +02:00
|
|
|
* srso_alias_untrain_ret() and srso_alias_safe_ret() are placed at
|
2023-06-28 11:02:39 +02:00
|
|
|
* special addresses:
|
|
|
|
*
|
2023-08-14 13:44:33 +02:00
|
|
|
* - srso_alias_untrain_ret() is 2M aligned
|
|
|
|
* - srso_alias_safe_ret() is also in the same 2M page but bits 2, 8, 14
|
2023-06-28 11:02:39 +02:00
|
|
|
* and 20 in its virtual address are set (while those bits in the
|
2023-08-14 13:44:33 +02:00
|
|
|
* srso_alias_untrain_ret() function are cleared).
|
2023-06-28 11:02:39 +02:00
|
|
|
*
|
|
|
|
* This guarantees that those two addresses will alias in the branch
|
|
|
|
* target buffer of Zen3/4 generations, leading to any potential
|
|
|
|
* poisoned entries at that BTB slot to get evicted.
|
|
|
|
*
|
2023-08-14 13:44:33 +02:00
|
|
|
* As a result, srso_alias_safe_ret() becomes a safe return.
|
2023-06-28 11:02:39 +02:00
|
|
|
*/
|
2023-09-04 22:05:00 -07:00
|
|
|
.pushsection .text..__x86.rethunk_untrain
|
2023-09-04 22:05:01 -07:00
|
|
|
SYM_CODE_START_NOALIGN(srso_alias_untrain_ret)
|
2023-08-14 13:44:31 +02:00
|
|
|
UNWIND_HINT_FUNC
|
2023-07-28 23:03:22 +02:00
|
|
|
ANNOTATE_NOENDBR
|
2023-06-28 11:02:39 +02:00
|
|
|
ASM_NOP2
|
|
|
|
lfence
|
2023-08-14 13:44:31 +02:00
|
|
|
jmp srso_alias_return_thunk
|
2023-08-14 13:44:33 +02:00
|
|
|
SYM_FUNC_END(srso_alias_untrain_ret)
|
2024-03-28 13:59:05 +01:00
|
|
|
__EXPORT_THUNK(srso_alias_untrain_ret)
|
2023-09-04 22:05:00 -07:00
|
|
|
.popsection
|
2023-06-28 11:02:39 +02:00
|
|
|
|
2023-09-04 22:05:00 -07:00
|
|
|
.pushsection .text..__x86.rethunk_safe
|
2023-09-04 22:05:01 -07:00
|
|
|
SYM_CODE_START_NOALIGN(srso_alias_safe_ret)
|
x86/retpoline: Don't clobber RFLAGS during srso_safe_ret()
Use LEA instead of ADD when adjusting %rsp in srso_safe_ret{,_alias}()
so as to avoid clobbering flags. Drop one of the INT3 instructions to
account for the LEA consuming one more byte than the ADD.
KVM's emulator makes indirect calls into a jump table of sorts, where
the destination of each call is a small blob of code that performs fast
emulation by executing the target instruction with fixed operands.
E.g. to emulate ADC, fastop() invokes adcb_al_dl():
adcb_al_dl:
<+0>: adc %dl,%al
<+2>: jmp <__x86_return_thunk>
A major motivation for doing fast emulation is to leverage the CPU to
handle consumption and manipulation of arithmetic flags, i.e. RFLAGS is
both an input and output to the target of the call. fastop() collects
the RFLAGS result by pushing RFLAGS onto the stack and popping them back
into a variable (held in %rdi in this case):
asm("push %[flags]; popf; " CALL_NOSPEC " ; pushf; pop %[flags]\n"
<+71>: mov 0xc0(%r8),%rdx
<+78>: mov 0x100(%r8),%rcx
<+85>: push %rdi
<+86>: popf
<+87>: call *%rsi
<+89>: nop
<+90>: nop
<+91>: nop
<+92>: pushf
<+93>: pop %rdi
and then propagating the arithmetic flags into the vCPU's emulator state:
ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK);
<+64>: and $0xfffffffffffff72a,%r9
<+94>: and $0x8d5,%edi
<+109>: or %rdi,%r9
<+122>: mov %r9,0x10(%r8)
The failures can be most easily reproduced by running the "emulator"
test in KVM-Unit-Tests.
If you're feeling a bit of deja vu, see commit b63f20a778c8
("x86/retpoline: Don't clobber RFLAGS during CALL_NOSPEC on i386").
In addition, this breaks booting of clang-compiled guest on
a gcc-compiled host where the host contains the %rsp-modifying SRSO
mitigations.
[ bp: Massage commit message, extend, remove addresses. ]
Fixes: fb3bd914b3ec ("x86/srso: Add a Speculative RAS Overflow mitigation")
Closes: https://lore.kernel.org/all/de474347-122d-54cd-eabf-9dcc95ab9eae@amd.com
Reported-by: Srikanth Aithal <sraithal@amd.com>
Reported-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/20230810013334.GA5354@dev-arch.thelio-3990X/
Link: https://lore.kernel.org/r/20230811155255.250835-1-seanjc@google.com
2023-08-11 08:52:55 -07:00
|
|
|
lea 8(%_ASM_SP), %_ASM_SP
|
2023-06-28 11:02:39 +02:00
|
|
|
UNWIND_HINT_FUNC
|
|
|
|
ANNOTATE_UNRET_SAFE
|
|
|
|
ret
|
|
|
|
int3
|
2023-08-14 13:44:33 +02:00
|
|
|
SYM_FUNC_END(srso_alias_safe_ret)
|
2023-06-28 11:02:39 +02:00
|
|
|
|
2023-09-04 22:04:55 -07:00
|
|
|
SYM_CODE_START_NOALIGN(srso_alias_return_thunk)
|
2023-08-14 13:44:31 +02:00
|
|
|
UNWIND_HINT_FUNC
|
|
|
|
ANNOTATE_NOENDBR
|
2023-08-14 13:44:33 +02:00
|
|
|
call srso_alias_safe_ret
|
2023-08-14 13:44:31 +02:00
|
|
|
ud2
|
|
|
|
SYM_CODE_END(srso_alias_return_thunk)
|
2023-09-04 22:05:00 -07:00
|
|
|
.popsection
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SRSO untraining sequence for Zen1/2, similar to retbleed_untrain_ret()
|
|
|
|
* above. On kernel entry, srso_untrain_ret() is executed which is a
|
|
|
|
*
|
|
|
|
* movabs $0xccccc30824648d48,%rax
|
|
|
|
*
|
|
|
|
* and when the return thunk executes the inner label srso_safe_ret()
|
|
|
|
* later, it is a stack manipulation and a RET which is mispredicted and
|
|
|
|
* thus a "safe" one to use.
|
|
|
|
*/
|
|
|
|
.align 64
|
|
|
|
.skip 64 - (srso_safe_ret - srso_untrain_ret), 0xcc
|
2023-09-04 22:05:01 -07:00
|
|
|
SYM_CODE_START_LOCAL_NOALIGN(srso_untrain_ret)
|
2023-09-04 22:05:00 -07:00
|
|
|
ANNOTATE_NOENDBR
|
|
|
|
.byte 0x48, 0xb8
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This forces the function return instruction to speculate into a trap
|
|
|
|
* (UD2 in srso_return_thunk() below). This RET will then mispredict
|
|
|
|
* and execution will continue at the return site read from the top of
|
|
|
|
* the stack.
|
|
|
|
*/
|
|
|
|
SYM_INNER_LABEL(srso_safe_ret, SYM_L_GLOBAL)
|
|
|
|
lea 8(%_ASM_SP), %_ASM_SP
|
|
|
|
ret
|
|
|
|
int3
|
|
|
|
int3
|
|
|
|
/* end of movabs */
|
|
|
|
lfence
|
|
|
|
call srso_safe_ret
|
|
|
|
ud2
|
|
|
|
SYM_CODE_END(srso_safe_ret)
|
|
|
|
SYM_FUNC_END(srso_untrain_ret)
|
|
|
|
|
|
|
|
SYM_CODE_START(srso_return_thunk)
|
|
|
|
UNWIND_HINT_FUNC
|
|
|
|
ANNOTATE_NOENDBR
|
|
|
|
call srso_safe_ret
|
|
|
|
ud2
|
|
|
|
SYM_CODE_END(srso_return_thunk)
|
|
|
|
|
|
|
|
#define JMP_SRSO_UNTRAIN_RET "jmp srso_untrain_ret"
|
2023-11-21 08:07:36 -08:00
|
|
|
#else /* !CONFIG_MITIGATION_SRSO */
|
2024-03-28 13:59:05 +01:00
|
|
|
/* Dummy for the alternative in CALL_UNTRAIN_RET. */
|
|
|
|
SYM_CODE_START(srso_alias_untrain_ret)
|
2024-04-02 16:05:49 +02:00
|
|
|
ANNOTATE_UNRET_SAFE
|
2024-04-05 16:46:37 +02:00
|
|
|
ANNOTATE_NOENDBR
|
2024-04-02 16:05:49 +02:00
|
|
|
ret
|
|
|
|
int3
|
2024-03-28 13:59:05 +01:00
|
|
|
SYM_FUNC_END(srso_alias_untrain_ret)
|
2024-04-02 16:05:49 +02:00
|
|
|
__EXPORT_THUNK(srso_alias_untrain_ret)
|
2023-09-04 22:05:00 -07:00
|
|
|
#define JMP_SRSO_UNTRAIN_RET "ud2"
|
2023-11-21 08:07:36 -08:00
|
|
|
#endif /* CONFIG_MITIGATION_SRSO */
|
2023-09-04 22:05:00 -07:00
|
|
|
|
2023-11-21 08:07:34 -08:00
|
|
|
#ifdef CONFIG_MITIGATION_UNRET_ENTRY
|
2023-08-14 13:44:31 +02:00
|
|
|
|
2023-08-14 21:29:50 +02:00
|
|
|
/*
|
|
|
|
* Some generic notes on the untraining sequences:
|
|
|
|
*
|
|
|
|
* They are interchangeable when it comes to flushing potentially wrong
|
|
|
|
* RET predictions from the BTB.
|
|
|
|
*
|
|
|
|
* The SRSO Zen1/2 (MOVABS) untraining sequence is longer than the
|
|
|
|
* Retbleed sequence because the return sequence done there
|
|
|
|
* (srso_safe_ret()) is longer and the return sequence must fully nest
|
|
|
|
* (end before) the untraining sequence. Therefore, the untraining
|
|
|
|
* sequence must fully overlap the return sequence.
|
|
|
|
*
|
|
|
|
* Regarding alignment - the instructions which need to be untrained,
|
|
|
|
* must all start at a cacheline boundary for Zen1/2 generations. That
|
|
|
|
* is, instruction sequences starting at srso_safe_ret() and
|
|
|
|
* the respective instruction sequences at retbleed_return_thunk()
|
|
|
|
* must start at a cacheline boundary.
|
|
|
|
*/
|
|
|
|
|
2022-06-14 23:15:48 +02:00
|
|
|
/*
|
|
|
|
* Safety details here pertain to the AMD Zen{1,2} microarchitecture:
|
2023-08-14 13:44:32 +02:00
|
|
|
* 1) The RET at retbleed_return_thunk must be on a 64 byte boundary, for
|
2022-06-14 23:15:48 +02:00
|
|
|
* alignment within the BTB.
|
2023-08-14 13:44:32 +02:00
|
|
|
* 2) The instruction at retbleed_untrain_ret must contain, and not
|
2022-06-14 23:15:48 +02:00
|
|
|
* end with, the 0xc3 byte of the RET.
|
|
|
|
* 3) STIBP must be enabled, or SMT disabled, to prevent the sibling thread
|
|
|
|
* from re-poisioning the BTB prediction.
|
|
|
|
*/
|
|
|
|
.align 64
|
2023-08-14 13:44:32 +02:00
|
|
|
.skip 64 - (retbleed_return_thunk - retbleed_untrain_ret), 0xcc
|
2023-09-04 22:05:01 -07:00
|
|
|
SYM_CODE_START_LOCAL_NOALIGN(retbleed_untrain_ret)
|
2023-05-12 23:12:26 +02:00
|
|
|
ANNOTATE_NOENDBR
|
2022-06-14 23:15:48 +02:00
|
|
|
/*
|
2023-08-14 13:44:32 +02:00
|
|
|
* As executed from retbleed_untrain_ret, this is:
|
2022-06-14 23:15:48 +02:00
|
|
|
*
|
|
|
|
* TEST $0xcc, %bl
|
|
|
|
* LFENCE
|
2023-08-14 13:44:32 +02:00
|
|
|
* JMP retbleed_return_thunk
|
2022-06-14 23:15:48 +02:00
|
|
|
*
|
|
|
|
* Executing the TEST instruction has a side effect of evicting any BTB
|
|
|
|
* prediction (potentially attacker controlled) attached to the RET, as
|
2023-08-14 13:44:32 +02:00
|
|
|
* retbleed_return_thunk + 1 isn't an instruction boundary at the moment.
|
2022-06-14 23:15:48 +02:00
|
|
|
*/
|
|
|
|
.byte 0xf6
|
|
|
|
|
|
|
|
/*
|
2023-08-14 13:44:32 +02:00
|
|
|
* As executed from retbleed_return_thunk, this is a plain RET.
|
2022-06-14 23:15:48 +02:00
|
|
|
*
|
|
|
|
* As part of the TEST above, RET is the ModRM byte, and INT3 the imm8.
|
|
|
|
*
|
|
|
|
* We subsequently jump backwards and architecturally execute the RET.
|
|
|
|
* This creates a correct BTB prediction (type=ret), but in the
|
|
|
|
* meantime we suffer Straight Line Speculation (because the type was
|
|
|
|
* no branch) which is halted by the INT3.
|
|
|
|
*
|
|
|
|
* With SMT enabled and STIBP active, a sibling thread cannot poison
|
|
|
|
* RET's prediction to a type of its choice, but can evict the
|
|
|
|
* prediction due to competitive sharing. If the prediction is
|
2023-08-14 13:44:32 +02:00
|
|
|
* evicted, retbleed_return_thunk will suffer Straight Line Speculation
|
2022-06-14 23:15:48 +02:00
|
|
|
* which will be contained safely by the INT3.
|
|
|
|
*/
|
2023-08-14 13:44:32 +02:00
|
|
|
SYM_INNER_LABEL(retbleed_return_thunk, SYM_L_GLOBAL)
|
2022-06-14 23:15:36 +02:00
|
|
|
ret
|
|
|
|
int3
|
2023-08-14 13:44:32 +02:00
|
|
|
SYM_CODE_END(retbleed_return_thunk)
|
2022-06-14 23:15:36 +02:00
|
|
|
|
2022-06-14 23:15:48 +02:00
|
|
|
/*
|
|
|
|
* Ensure the TEST decoding / BTB invalidation is complete.
|
|
|
|
*/
|
|
|
|
lfence
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Jump back and execute the RET in the middle of the TEST instruction.
|
|
|
|
* INT3 is for SLS protection.
|
|
|
|
*/
|
2023-08-14 13:44:32 +02:00
|
|
|
jmp retbleed_return_thunk
|
2022-06-14 23:15:48 +02:00
|
|
|
int3
|
2023-08-14 13:44:32 +02:00
|
|
|
SYM_FUNC_END(retbleed_untrain_ret)
|
2022-06-14 23:15:48 +02:00
|
|
|
|
2023-09-04 22:05:00 -07:00
|
|
|
#define JMP_RETBLEED_UNTRAIN_RET "jmp retbleed_untrain_ret"
|
2023-11-21 08:07:34 -08:00
|
|
|
#else /* !CONFIG_MITIGATION_UNRET_ENTRY */
|
2023-09-04 22:05:00 -07:00
|
|
|
#define JMP_RETBLEED_UNTRAIN_RET "ud2"
|
2023-11-21 08:07:34 -08:00
|
|
|
#endif /* CONFIG_MITIGATION_UNRET_ENTRY */
|
2023-06-28 11:02:39 +02:00
|
|
|
|
2023-11-21 08:07:36 -08:00
|
|
|
#if defined(CONFIG_MITIGATION_UNRET_ENTRY) || defined(CONFIG_MITIGATION_SRSO)
|
2023-08-14 13:44:31 +02:00
|
|
|
|
2023-08-14 13:44:34 +02:00
|
|
|
SYM_FUNC_START(entry_untrain_ret)
|
2025-02-07 13:15:33 +01:00
|
|
|
ANNOTATE_NOENDBR
|
2024-03-28 13:59:05 +01:00
|
|
|
ALTERNATIVE JMP_RETBLEED_UNTRAIN_RET, JMP_SRSO_UNTRAIN_RET, X86_FEATURE_SRSO
|
2023-08-14 13:44:34 +02:00
|
|
|
SYM_FUNC_END(entry_untrain_ret)
|
|
|
|
__EXPORT_THUNK(entry_untrain_ret)
|
|
|
|
|
2023-11-21 08:07:36 -08:00
|
|
|
#endif /* CONFIG_MITIGATION_UNRET_ENTRY || CONFIG_MITIGATION_SRSO */
|
2022-09-15 13:11:27 +02:00
|
|
|
|
2023-11-21 08:07:30 -08:00
|
|
|
#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
|
2022-09-15 13:11:27 +02:00
|
|
|
|
|
|
|
.align 64
|
2023-09-04 22:05:04 -07:00
|
|
|
SYM_FUNC_START(call_depth_return_thunk)
|
2022-09-15 13:11:27 +02:00
|
|
|
ANNOTATE_NOENDBR
|
2022-09-15 13:11:30 +02:00
|
|
|
/*
|
|
|
|
* Keep the hotpath in a 16byte I-fetch for the non-debug
|
|
|
|
* case.
|
|
|
|
*/
|
|
|
|
CALL_THUNKS_DEBUG_INC_RETS
|
2025-03-03 11:52:40 -05:00
|
|
|
shlq $5, PER_CPU_VAR(__x86_call_depth)
|
2022-09-15 13:11:27 +02:00
|
|
|
jz 1f
|
|
|
|
ANNOTATE_UNRET_SAFE
|
|
|
|
ret
|
|
|
|
int3
|
|
|
|
1:
|
2022-09-15 13:11:30 +02:00
|
|
|
CALL_THUNKS_DEBUG_INC_STUFFS
|
2022-09-15 13:11:27 +02:00
|
|
|
.rept 16
|
|
|
|
ANNOTATE_INTRA_FUNCTION_CALL
|
|
|
|
call 2f
|
|
|
|
int3
|
|
|
|
2:
|
|
|
|
.endr
|
|
|
|
add $(8*16), %rsp
|
|
|
|
|
|
|
|
CREDIT_CALL_DEPTH
|
|
|
|
|
|
|
|
ANNOTATE_UNRET_SAFE
|
|
|
|
ret
|
|
|
|
int3
|
2023-09-04 22:05:04 -07:00
|
|
|
SYM_FUNC_END(call_depth_return_thunk)
|
2022-09-15 13:11:27 +02:00
|
|
|
|
2023-11-21 08:07:30 -08:00
|
|
|
#endif /* CONFIG_MITIGATION_CALL_DEPTH_TRACKING */
|
2023-09-04 22:05:00 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This function name is magical and is used by -mfunction-return=thunk-extern
|
|
|
|
* for the compiler to generate JMPs to it.
|
|
|
|
*
|
|
|
|
* This code is only used during kernel boot or module init. All
|
|
|
|
* 'JMP __x86_return_thunk' sites are changed to something else by
|
|
|
|
* apply_returns().
|
2023-10-20 13:17:14 +02:00
|
|
|
*
|
2024-01-03 19:36:26 +01:00
|
|
|
* The ALTERNATIVE below adds a really loud warning to catch the case
|
|
|
|
* where the insufficient default return thunk ends up getting used for
|
|
|
|
* whatever reason like miscompilation or failure of
|
|
|
|
* objtool/alternatives/etc to patch all the return sites.
|
2023-09-04 22:05:00 -07:00
|
|
|
*/
|
|
|
|
SYM_CODE_START(__x86_return_thunk)
|
|
|
|
UNWIND_HINT_FUNC
|
|
|
|
ANNOTATE_NOENDBR
|
2024-04-15 18:15:43 +02:00
|
|
|
#if defined(CONFIG_MITIGATION_UNRET_ENTRY) || \
|
|
|
|
defined(CONFIG_MITIGATION_SRSO) || \
|
|
|
|
defined(CONFIG_MITIGATION_CALL_DEPTH_TRACKING)
|
2024-01-03 19:36:26 +01:00
|
|
|
ALTERNATIVE __stringify(ANNOTATE_UNRET_SAFE; ret), \
|
|
|
|
"jmp warn_thunk_thunk", X86_FEATURE_ALWAYS
|
2024-04-15 18:15:43 +02:00
|
|
|
#else
|
|
|
|
ANNOTATE_UNRET_SAFE
|
|
|
|
ret
|
|
|
|
#endif
|
2023-09-04 22:05:00 -07:00
|
|
|
int3
|
|
|
|
SYM_CODE_END(__x86_return_thunk)
|
|
|
|
EXPORT_SYMBOL(__x86_return_thunk)
|
|
|
|
|
2023-11-21 08:07:37 -08:00
|
|
|
#endif /* CONFIG_MITIGATION_RETHUNK */
|