Right now an indirect jump might use a relative jump to a retpoline
thunk in order to mitigate the Spectre vulnerability.

In case the code using the indirect jump is remapped to another
virtual address this won't work any longer, so add support for
indirect jumps using a local thunk instead.

Signed-off-by: Juergen Gross <jgr...@suse.com>
---
V3:
- new patch
---
 xen/arch/x86/indirect-thunk.S            | 23 +----------------------
 xen/include/asm-x86/asm_defns.h          | 25 +++++++++++++++++++++++++
 xen/include/asm-x86/indirect_thunk_asm.h |  8 ++++++--
 3 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/xen/arch/x86/indirect-thunk.S b/xen/arch/x86/indirect-thunk.S
index e03fc14c73..b4d3e4cec4 100644
--- a/xen/arch/x86/indirect-thunk.S
+++ b/xen/arch/x86/indirect-thunk.S
@@ -11,25 +11,6 @@
 
 #include <asm/asm_defns.h>
 
-.macro IND_THUNK_RETPOLINE reg:req
-        call 2f
-1:
-        lfence
-        jmp 1b
-2:
-        mov %\reg, (%rsp)
-        ret
-.endm
-
-.macro IND_THUNK_LFENCE reg:req
-        lfence
-        jmp *%\reg
-.endm
-
-.macro IND_THUNK_JMP reg:req
-        jmp *%\reg
-.endm
-
 /*
  * Build the __x86_indirect_thunk_* symbols.  Execution lands on an
  * alternative patch point which implements one of the above THUNK_*'s
@@ -38,9 +19,7 @@
         .section .text.__x86_indirect_thunk_\reg, "ax", @progbits
 
 ENTRY(__x86_indirect_thunk_\reg)
-        ALTERNATIVE_2 __stringify(IND_THUNK_RETPOLINE \reg),              \
-        __stringify(IND_THUNK_LFENCE \reg), X86_FEATURE_IND_THUNK_LFENCE, \
-        __stringify(IND_THUNK_JMP \reg),    X86_FEATURE_IND_THUNK_JMP
+        GEN_INDIRECT_THUNK_BODY \reg
 .endm
 
 /* Instantiate GEN_INDIRECT_THUNK for each register except %rsp. */
diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h
index 2a79e8a7f4..7d26391be8 100644
--- a/xen/include/asm-x86/asm_defns.h
+++ b/xen/include/asm-x86/asm_defns.h
@@ -334,6 +334,31 @@ static always_inline void stac(void)
         subq  $-(UREGS_error_code-UREGS_r15+\adj), %rsp
 .endm
 
+.macro IND_THUNK_RETPOLINE reg:req
+        call 2f
+1:
+        lfence
+        jmp 1b
+2:
+        mov %\reg, (%rsp)
+        ret
+.endm
+
+.macro IND_THUNK_LFENCE reg:req
+        lfence
+        jmp *%\reg
+.endm
+
+.macro IND_THUNK_JMP reg:req
+        jmp *%\reg
+.endm
+
+.macro GEN_INDIRECT_THUNK_BODY reg:req
+        ALTERNATIVE_2 __stringify(IND_THUNK_RETPOLINE \reg),              \
+        __stringify(IND_THUNK_LFENCE \reg), X86_FEATURE_IND_THUNK_LFENCE, \
+        __stringify(IND_THUNK_JMP \reg),    X86_FEATURE_IND_THUNK_JMP
+.endm
+
 #endif
 
 #ifdef CONFIG_PERF_COUNTERS
diff --git a/xen/include/asm-x86/indirect_thunk_asm.h 
b/xen/include/asm-x86/indirect_thunk_asm.h
index 96bcc25497..3abb32caee 100644
--- a/xen/include/asm-x86/indirect_thunk_asm.h
+++ b/xen/include/asm-x86/indirect_thunk_asm.h
@@ -3,7 +3,7 @@
  * usual #ifdef'ary to turn into comments.
  */
 
-.macro INDIRECT_BRANCH insn:req arg:req
+.macro INDIRECT_BRANCH insn:req arg:req label=__x86_indirect_thunk_r
 /*
  * Create an indirect branch.  insn is one of call/jmp, arg is a single
  * register.
@@ -16,7 +16,7 @@
         $done = 0
         .irp reg, ax, cx, dx, bx, bp, si, di, 8, 9, 10, 11, 12, 13, 14, 15
         .ifeqs "\arg", "%r\reg"
-            \insn __x86_indirect_thunk_r\reg
+            \insn \label\reg
             $done = 1
            .exitm
         .endif
@@ -39,3 +39,7 @@
 .macro INDIRECT_JMP arg:req
     INDIRECT_BRANCH jmp \arg
 .endm
+
+.macro INDIRECT_LOCAL_JMP arg:req
+    INDIRECT_BRANCH jmp \arg local__x86_indirect_thunk_r
+.endm
-- 
2.13.6


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Reply via email to