ab31640
From: Andrew Cooper <andrew.cooper3@citrix.com>
ab31640
Subject: x86/spec-ctrl: Rework SPEC_CTRL_ENTRY_FROM_INTR_IST
ab31640
ab31640
We are shortly going to add a conditional IBPB in this path.
ab31640
ab31640
Therefore, we cannot hold spec_ctrl_flags in %eax, and rely on only clobbering
ab31640
it after we're done with its contents.  %rbx is available for use, and the
ab31640
more normal register to hold preserved information in.
ab31640
ab31640
With %rax freed up, use it instead of %rdx for the RSB tmp register, and for
ab31640
the adjustment to spec_ctrl_flags.
ab31640
ab31640
This leaves no use of %rdx, except as 0 for the upper half of WRMSR.  In
ab31640
practice, %rdx is 0 from SAVE_ALL on all paths and isn't likely to change in
ab31640
the foreseeable future, so update the macro entry requirements to state this
ab31640
dependency.  This marginal optimisation can be revisited if circumstances
ab31640
change.
ab31640
ab31640
No practical change.
ab31640
ab31640
This is part of XSA-407.
ab31640
ab31640
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
ab31640
Reviewed-by: Jan Beulich <jbeulich@suse.com>
ab31640
ab31640
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
ab31640
index 2a86938f1f32..a1810bf4d311 100644
ab31640
--- a/xen/arch/x86/x86_64/entry.S
ab31640
+++ b/xen/arch/x86/x86_64/entry.S
ab31640
@@ -932,7 +932,7 @@ ENTRY(double_fault)
ab31640
 
ab31640
         GET_STACK_END(14)
ab31640
 
ab31640
-        SPEC_CTRL_ENTRY_FROM_INTR_IST /* Req: %rsp=regs, %r14=end, Clob: acd */
ab31640
+        SPEC_CTRL_ENTRY_FROM_INTR_IST /* Req: %rsp=regs, %r14=end, %rdx=0, Clob: abcd */
ab31640
         /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
ab31640
 
ab31640
         mov   STACK_CPUINFO_FIELD(xen_cr3)(%r14), %rbx
ab31640
@@ -968,7 +968,7 @@ handle_ist_exception:
ab31640
 
ab31640
         GET_STACK_END(14)
ab31640
 
ab31640
-        SPEC_CTRL_ENTRY_FROM_INTR_IST /* Req: %rsp=regs, %r14=end, Clob: acd */
ab31640
+        SPEC_CTRL_ENTRY_FROM_INTR_IST /* Req: %rsp=regs, %r14=end, %rdx=0, Clob: abcd */
ab31640
         /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
ab31640
 
ab31640
         mov   STACK_CPUINFO_FIELD(xen_cr3)(%r14), %rcx
ab31640
diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h
ab31640
index 0ff1b118f882..15e24cde00d1 100644
ab31640
--- a/xen/include/asm-x86/spec_ctrl_asm.h
ab31640
+++ b/xen/include/asm-x86/spec_ctrl_asm.h
ab31640
@@ -251,34 +251,33 @@
ab31640
  */
ab31640
 .macro SPEC_CTRL_ENTRY_FROM_INTR_IST
ab31640
 /*
ab31640
- * Requires %rsp=regs, %r14=stack_end
ab31640
- * Clobbers %rax, %rcx, %rdx
ab31640
+ * Requires %rsp=regs, %r14=stack_end, %rdx=0
ab31640
+ * Clobbers %rax, %rbx, %rcx, %rdx
ab31640
  *
ab31640
  * This is logical merge of DO_OVERWRITE_RSB and DO_SPEC_CTRL_ENTRY
ab31640
  * maybexen=1, but with conditionals rather than alternatives.
ab31640
  */
ab31640
-    movzbl STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14), %eax
ab31640
+    movzbl STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14), %ebx
ab31640
 
ab31640
-    test $SCF_ist_rsb, %al
ab31640
+    test $SCF_ist_rsb, %bl
ab31640
     jz .L\@_skip_rsb
ab31640
 
ab31640
-    DO_OVERWRITE_RSB tmp=rdx /* Clobbers %rcx/%rdx */
ab31640
+    DO_OVERWRITE_RSB         /* Clobbers %rax/%rcx */
ab31640
 
ab31640
 .L\@_skip_rsb:
ab31640
 
ab31640
-    test $SCF_ist_sc_msr, %al
ab31640
+    test $SCF_ist_sc_msr, %bl
ab31640
     jz .L\@_skip_msr_spec_ctrl
ab31640
 
ab31640
-    xor %edx, %edx
ab31640
+    xor %eax, %eax
ab31640
     testb $3, UREGS_cs(%rsp)
ab31640
-    setnz %dl
ab31640
-    not %edx
ab31640
-    and %dl, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14)
ab31640
+    setnz %al
ab31640
+    not %eax
ab31640
+    and %al, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14)
ab31640
 
ab31640
     /* Load Xen's intended value. */
ab31640
     mov $MSR_SPEC_CTRL, %ecx
ab31640
     movzbl STACK_CPUINFO_FIELD(xen_spec_ctrl)(%r14), %eax
ab31640
-    xor %edx, %edx
ab31640
     wrmsr
ab31640
 
ab31640
     /* Opencoded UNLIKELY_START() with no condition. */