afce7b2
From 2e2c3efcfc9f183674a8de6ed954ffbe7188b70d Mon Sep 17 00:00:00 2001
afce7b2
Message-ID: <2e2c3efcfc9f183674a8de6ed954ffbe7188b70d.1695733540.git.m.a.young@durham.ac.uk>
afce7b2
In-Reply-To: <d2d2dcae879c6cc05227c9620f0a772f35fe6886.1695733540.git.m.a.young@durham.ac.uk>
afce7b2
References: <d2d2dcae879c6cc05227c9620f0a772f35fe6886.1695733540.git.m.a.young@durham.ac.uk>
afce7b2
From: Andrew Cooper <andrew.cooper3@citrix.com>
afce7b2
Date: Wed, 13 Sep 2023 13:53:33 +0100
afce7b2
Subject: [XEN PATCH 08/10] x86/spec-ctrl: Issue VERW during IST exit to Xen
afce7b2
afce7b2
There is a corner case where e.g. an NMI hitting an exit-to-guest path after
afce7b2
SPEC_CTRL_EXIT_TO_* would have run the entire NMI handler *after* the VERW
afce7b2
flush to scrub potentially sensitive data from uarch buffers.
afce7b2
afce7b2
In order to compensate, issue VERW when exiting to Xen from an IST entry.
afce7b2
afce7b2
SPEC_CTRL_EXIT_TO_XEN already has two reads of spec_ctrl_flags off the stack,
afce7b2
and we're about to add a third.  Load the field into %ebx, and list the
afce7b2
register as clobbered.
afce7b2
afce7b2
%r12 has been arranged to be the ist_exit signal, so add this as an input
afce7b2
dependency and use it to identify when to issue a VERW.
afce7b2
afce7b2
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
afce7b2
Reviewed-by: Jan Beulich <jbeulich@suse.com>
afce7b2
(cherry picked from commit 3ee6066bcd737756b0990d417d94eddc0b0d2585)
afce7b2
---
afce7b2
 xen/arch/x86/include/asm/spec_ctrl_asm.h | 20 +++++++++++++++-----
afce7b2
 xen/arch/x86/x86_64/entry.S              |  2 +-
afce7b2
 2 files changed, 16 insertions(+), 6 deletions(-)
afce7b2
afce7b2
diff --git a/xen/arch/x86/include/asm/spec_ctrl_asm.h b/xen/arch/x86/include/asm/spec_ctrl_asm.h
afce7b2
index 66c706496f..28a75796e6 100644
afce7b2
--- a/xen/arch/x86/include/asm/spec_ctrl_asm.h
afce7b2
+++ b/xen/arch/x86/include/asm/spec_ctrl_asm.h
afce7b2
@@ -357,10 +357,12 @@ UNLIKELY_DISPATCH_LABEL(\@_serialise):
afce7b2
  */
afce7b2
 .macro SPEC_CTRL_EXIT_TO_XEN
afce7b2
 /*
afce7b2
- * Requires %r14=stack_end
afce7b2
- * Clobbers %rax, %rcx, %rdx
afce7b2
+ * Requires %r12=ist_exit, %r14=stack_end
afce7b2
+ * Clobbers %rax, %rbx, %rcx, %rdx
afce7b2
  */
afce7b2
-    testb $SCF_ist_sc_msr, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14)
afce7b2
+    movzbl STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14), %ebx
afce7b2
+
afce7b2
+    testb $SCF_ist_sc_msr, %bl
afce7b2
     jz .L\@_skip_sc_msr
afce7b2
 
afce7b2
     /*
afce7b2
@@ -371,7 +373,7 @@ UNLIKELY_DISPATCH_LABEL(\@_serialise):
afce7b2
      */
afce7b2
     xor %edx, %edx
afce7b2
 
afce7b2
-    testb $SCF_use_shadow, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14)
afce7b2
+    testb $SCF_use_shadow, %bl
afce7b2
     jz .L\@_skip_sc_msr
afce7b2
 
afce7b2
     mov STACK_CPUINFO_FIELD(shadow_spec_ctrl)(%r14), %eax
afce7b2
@@ -380,8 +382,16 @@ UNLIKELY_DISPATCH_LABEL(\@_serialise):
afce7b2
 
afce7b2
 .L\@_skip_sc_msr:
afce7b2
 
afce7b2
-    /* TODO VERW */
afce7b2
+    test %r12, %r12
afce7b2
+    jz .L\@_skip_ist_exit
afce7b2
+
afce7b2
+    /* Logically DO_SPEC_CTRL_COND_VERW but without the %rsp=cpuinfo dependency */
afce7b2
+    testb $SCF_verw, %bl
afce7b2
+    jz .L\@_skip_verw
afce7b2
+    verw STACK_CPUINFO_FIELD(verw_sel)(%r14)
afce7b2
+.L\@_skip_verw:
afce7b2
 
afce7b2
+.L\@_skip_ist_exit:
afce7b2
 .endm
afce7b2
 
afce7b2
 #endif /* __ASSEMBLY__ */
afce7b2
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
afce7b2
index 4cebc4fbe3..c12e011b4d 100644
afce7b2
--- a/xen/arch/x86/x86_64/entry.S
afce7b2
+++ b/xen/arch/x86/x86_64/entry.S
afce7b2
@@ -680,7 +680,7 @@ UNLIKELY_START(ne, exit_cr3)
afce7b2
 UNLIKELY_END(exit_cr3)
afce7b2
 
afce7b2
         /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */
afce7b2
-        SPEC_CTRL_EXIT_TO_XEN     /* Req: %r14=end, Clob: acd */
afce7b2
+        SPEC_CTRL_EXIT_TO_XEN     /* Req: %r12=ist_exit %r14=end, Clob: abcd */
afce7b2
 
afce7b2
         RESTORE_ALL adj=8
afce7b2
         iretq
afce7b2
-- 
afce7b2
2.41.0
afce7b2