All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection
@ 2018-01-04  0:15 Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 01/26] x86/alt: Break out alternative-asm into a separate header file Andrew Cooper
                   ` (25 more replies)
  0 siblings, 26 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Due to the foreshortening of the embargo, I've posted what is currently
available.  I have yet to complete all the feedback from v6 review, but what
is here should be functionally correct, if a little rough around the edges.

*Important:*

In addition to this software series, you will need the following:

  1) A compiler which understands -mindirect-branch=thunk-external and
     -mindirect-branch-register.  A GCC patch series implementing this
     should be available imminently.

  2) New microcode from Intel and AMD.  These provide new MSRs for Xen to use,
     and virtualise for guest kernels to use.

There are some limitations, even with the work presented here.

  1) vCPU-to-vCPU SP2 attacks can only be mitigated at the hypervisor level
     with IBPB support, which for internal pipeline reasons, we do not expect
     to be made available on older processors.  For now, I will leave these
     details to the hardware vendors.

  2) Hardware lacking SMEP is in a worse position than hardware with SMEP.  If
     you have SMEP (Intel IvyBridge and later, Some AMD Fam16h and all Fam17h
     and later), make absolutely sure it is enabled in the BIOS and working.

  3) On hardware lacking SMEP support, it is still an open question how to
     protect against RSB-to-SMM speculation.  Native operating systems can fix
     this by prohibiting userspace from mmap()'ing addresses which alias the
     SMM range, but Xen has no feasible way of enforcing this restriction on
     PV guests, even if we could tolerate the ABI breakage.  (However, see the
     forthcoming SP3 mitigation series for alternatives for un trusted PV
     guests).


Please see the commit messages and comments for more details about mitigation
details and available options/impacts.  Its more complicated than I care to
reproduce here (and risk introducing a contradition).

~Andrew

Andrew Cooper (26):
  x86/alt: Break out alternative-asm into a separate header file
  x86/alt: Introduce ALTERNATIVE{,_2} macros
  x86/hvm: Rename update_guest_vendor() callback to cpuid_policy_changed()
  x86: Introduce a common cpuid_policy_updated()
  x86/entry: Remove support for partial cpu_user_regs frames
  x86/entry: Rearrange RESTORE_ALL to restore register in stack order
  x86/hvm: Use SAVE_ALL to construct the cpu_user_regs frame after VMExit
  x86/entry: Erase guest GPR state on entry to Xen
  x86: Support compiling with indirect branch thunks
  common/wait: Clarifications to wait infrastructure
  x86: Support indirect thunks from assembly code
  x86/boot: Report details of speculative mitigations
  x86/amd: Try to set lfence as being Dispatch Serialising
  x86: Introduce alternative indirect thunks
  x86/feature: Definitions for Indirect Branch Controls
  x86/cmdline: Introduce a command line option to disable IBRS/IBPB, STIBP and IBPB
  x86/msr: Emulation of MSR_{SPEC_CTRL,PRED_CMD} for guests
  x86/migrate: Move MSR_SPEC_CTRL on migrate
  x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL,PRED_CMD}
  x86: Protect unaware domains from meddling hyperthreads
  x86/entry: Use MSR_SPEC_CTRL at each entry/exit point
  x86/boot: Calculate the most appropriate BTI mitigation to use
  x86/entry: Clobber the Return Stack Buffer on entry to Xen
  x86/ctxt: Issue a speculation barrier between vcpu contexts
  x86/cpuid: Offer Indirect Branch Controls to guests
  x86/idle: Clear SPEC_CTRL while idle

 docs/misc/xen-command-line.markdown         |  37 ++++
 tools/libxc/xc_cpuid_x86.c                  |   4 +-
 tools/libxl/libxl_cpuid.c                   |   3 +
 tools/misc/xen-cpuid.c                      |  12 +-
 tools/tests/x86_emulator/x86-emulate.c      |   1 -
 xen/arch/x86/Makefile                       |   2 +
 xen/arch/x86/Rules.mk                       |   7 +
 xen/arch/x86/acpi/cpu_idle.c                |  21 ++
 xen/arch/x86/boot/trampoline.S              |  24 +-
 xen/arch/x86/cpu/amd.c                      |  35 ++-
 xen/arch/x86/cpu/mwait-idle.c               |   7 +
 xen/arch/x86/cpuid.c                        |  43 ++++
 xen/arch/x86/domain.c                       |  42 ++++
 xen/arch/x86/domctl.c                       |  38 +++-
 xen/arch/x86/extable.c                      |   4 +-
 xen/arch/x86/hvm/hvm.c                      |   4 +-
 xen/arch/x86/hvm/svm/entry.S                |  28 +--
 xen/arch/x86/hvm/svm/svm.c                  |   9 +-
 xen/arch/x86/hvm/vmx/entry.S                |  28 ++-
 xen/arch/x86/hvm/vmx/vmx.c                  |  23 +-
 xen/arch/x86/indirect_thunk.S               |  39 ++++
 xen/arch/x86/msr.c                          |  49 +++++
 xen/arch/x86/pv/domain.c                    |   1 -
 xen/arch/x86/pv/emul-priv-op.c              |  43 +++-
 xen/arch/x86/setup.c                        |   4 +
 xen/arch/x86/smpboot.c                      |   2 +
 xen/arch/x86/spec_ctrl.c                    | 328 ++++++++++++++++++++++++++++
 xen/arch/x86/x86_64/asm-offsets.c           |   6 +
 xen/arch/x86/x86_64/compat/entry.S          |  19 +-
 xen/arch/x86/x86_64/entry.S                 |  51 ++++-
 xen/arch/x86/x86_64/traps.c                 |  13 +-
 xen/arch/x86/x86_emulate.c                  |   1 -
 xen/arch/x86/x86_emulate/x86_emulate.c      |  12 +-
 xen/arch/x86/xen.lds.S                      |   1 +
 xen/common/kernel.c                         |  23 ++
 xen/common/wait.c                           |  38 +++-
 xen/include/asm-x86/alternative-asm.h       |  77 +++++++
 xen/include/asm-x86/alternative.h           |  13 +-
 xen/include/asm-x86/asm_defns.h             | 158 ++++----------
 xen/include/asm-x86/cpufeature.h            |   6 +
 xen/include/asm-x86/cpufeatures.h           |  10 +
 xen/include/asm-x86/current.h               |   6 +
 xen/include/asm-x86/domain.h                |   2 +
 xen/include/asm-x86/hvm/hvm.h               |   6 +-
 xen/include/asm-x86/indirect_thunk_asm.h    |  41 ++++
 xen/include/asm-x86/msr-index.h             |  12 +
 xen/include/asm-x86/msr.h                   |  15 ++
 xen/include/asm-x86/nops.h                  |  10 +-
 xen/include/asm-x86/spec_ctrl.h             |  78 +++++++
 xen/include/asm-x86/spec_ctrl_asm.h         | 276 +++++++++++++++++++++++
 xen/include/public/arch-x86/cpufeatureset.h |   3 +
 xen/include/xen/lib.h                       |   7 +
 xen/tools/gen-cpuid.py                      |   5 +
 53 files changed, 1497 insertions(+), 230 deletions(-)
 create mode 100644 xen/arch/x86/indirect_thunk.S
 create mode 100644 xen/arch/x86/spec_ctrl.c
 create mode 100644 xen/include/asm-x86/alternative-asm.h
 create mode 100644 xen/include/asm-x86/indirect_thunk_asm.h
 create mode 100644 xen/include/asm-x86/spec_ctrl.h
 create mode 100644 xen/include/asm-x86/spec_ctrl_asm.h

-- 
2.1.4


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [PATCH v6.5 01/26] x86/alt: Break out alternative-asm into a separate header file
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 02/26] x86/alt: Introduce ALTERNATIVE{, _2} macros Andrew Cooper
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/include/asm-x86/alternative-asm.h | 31 +++++++++++++++++++++++++++++++
 xen/include/asm-x86/alternative.h     | 13 +++----------
 2 files changed, 34 insertions(+), 10 deletions(-)
 create mode 100644 xen/include/asm-x86/alternative-asm.h

diff --git a/xen/include/asm-x86/alternative-asm.h b/xen/include/asm-x86/alternative-asm.h
new file mode 100644
index 0000000..bf0332e
--- /dev/null
+++ b/xen/include/asm-x86/alternative-asm.h
@@ -0,0 +1,31 @@
+#ifndef _ASM_X86_ALTERNATIVE_ASM_H_
+#define _ASM_X86_ALTERNATIVE_ASM_H_
+
+#ifdef __ASSEMBLY__
+
+/*
+ * Issue one struct alt_instr descriptor entry (need to put it into
+ * the section .altinstructions, see below). This entry contains
+ * enough information for the alternatives patching code to patch an
+ * instruction. See apply_alternatives().
+ */
+.macro altinstruction_entry orig alt feature orig_len alt_len
+    .long \orig - .
+    .long \alt - .
+    .word \feature
+    .byte \orig_len
+    .byte \alt_len
+.endm
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_X86_ALTERNATIVE_ASM_H_ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-x86/alternative.h b/xen/include/asm-x86/alternative.h
index db4f08e..ba537d6 100644
--- a/xen/include/asm-x86/alternative.h
+++ b/xen/include/asm-x86/alternative.h
@@ -1,17 +1,10 @@
 #ifndef __X86_ALTERNATIVE_H__
 #define __X86_ALTERNATIVE_H__
 
+#include <asm/alternative-asm.h>
 #include <asm/nops.h>
 
-#ifdef __ASSEMBLY__
-.macro altinstruction_entry orig alt feature orig_len alt_len
-        .long \orig - .
-        .long \alt - .
-        .word \feature
-        .byte \orig_len
-        .byte \alt_len
-.endm
-#else
+#ifndef __ASSEMBLY__
 #include <xen/stringify.h>
 #include <xen/types.h>
 
@@ -145,6 +138,6 @@ extern void alternative_instructions(void);
 /* Use this macro(s) if you need more than one output parameter. */
 #define ASM_OUTPUT2(a...) a
 
-#endif  /*  __ASSEMBLY__  */
+#endif /*  !__ASSEMBLY__  */
 
 #endif /* __X86_ALTERNATIVE_H__ */
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 02/26] x86/alt: Introduce ALTERNATIVE{, _2} macros
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 01/26] x86/alt: Break out alternative-asm into a separate header file Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 03/26] x86/hvm: Rename update_guest_vendor() callback to cpuid_policy_changed() Andrew Cooper
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

To help creating alternative frames in assembly.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
v3:
 * Drop the now-unused ALTERNATIVE_2
 * Use .L\@ rather than opencoded numbers
v4:
 * Extra @progbits
 * Reinstate ALTERNATIVE_2
---
 xen/include/asm-x86/alternative-asm.h | 46 +++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/xen/include/asm-x86/alternative-asm.h b/xen/include/asm-x86/alternative-asm.h
index bf0332e..6640e85 100644
--- a/xen/include/asm-x86/alternative-asm.h
+++ b/xen/include/asm-x86/alternative-asm.h
@@ -17,6 +17,52 @@
     .byte \alt_len
 .endm
 
+.macro ALTERNATIVE oldinstr, newinstr, feature
+.Lold_start_\@:
+    \oldinstr
+.Lold_end_\@:
+
+    .pushsection .altinstructions, "a", @progbits
+    altinstruction_entry .Lold_start_\@, .Lnew_start_\@, \feature, \
+        (.Lold_end_\@ - .Lold_start_\@), (.Lnew_end_\@ - .Lnew_start_\@)
+
+    .section .discard, "a", @progbits
+    /* Assembler-time check that \newinstr isn't longer than \oldinstr. */
+    .byte 0xff + (.Lnew_end_\@ - .Lnew_start_\@) - (.Lold_end_\@ - .Lold_start_\@)
+
+    .section .altinstr_replacement, "ax", @progbits
+.Lnew_start_\@:
+    \newinstr
+.Lnew_end_\@:
+    .popsection
+.endm
+
+.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
+.Lold_start_\@:
+    \oldinstr
+.Lold_end_\@:
+
+    .pushsection .altinstructions, "a", @progbits
+    altinstruction_entry .Lold_start_\@, .Lnew1_start_\@, \feature1, \
+        (.Lold_end_\@ - .Lold_start_\@), (.Lnew1_end_\@ - .Lnew1_start_\@)
+    altinstruction_entry .Lold_start_\@, .Lnew2_start_\@, \feature2, \
+        (.Lold_end_\@ - .Lold_start_\@), (.Lnew2_end_\@ - .Lnew2_start_\@)
+
+    .section .discard, "a", @progbits
+    /* Assembler-time check that \newinstr{1,2} aren't longer than \oldinstr. */
+    .byte 0xff + (.Lnew1_end_\@ - .Lnew1_start_\@) - (.Lold_end_\@ - .Lold_start_\@)
+    .byte 0xff + (.Lnew2_end_\@ - .Lnew2_start_\@) - (.Lold_end_\@ - .Lold_start_\@)
+
+    .section .altinstr_replacement, "ax", @progbits
+.Lnew1_start_\@:
+    \newinstr1
+.Lnew1_end_\@:
+.Lnew2_start_\@:
+    \newinstr2
+.Lnew2_end_\@:
+    .popsection
+.endm
+
 #endif /* __ASSEMBLY__ */
 #endif /* _ASM_X86_ALTERNATIVE_ASM_H_ */
 
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 03/26] x86/hvm: Rename update_guest_vendor() callback to cpuid_policy_changed()
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 01/26] x86/alt: Break out alternative-asm into a separate header file Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 02/26] x86/alt: Introduce ALTERNATIVE{, _2} macros Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 04/26] x86: Introduce a common cpuid_policy_updated() Andrew Cooper
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

It will shortly be used for more than just changing the vendor.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
v3:
 * Drop forward declaration of vmx_update_guest_vendor()
---
 xen/arch/x86/domctl.c         | 17 ++++++++++-------
 xen/arch/x86/hvm/hvm.c        |  2 +-
 xen/arch/x86/hvm/svm/svm.c    |  4 ++--
 xen/arch/x86/hvm/vmx/vmx.c    |  5 ++---
 xen/include/asm-x86/hvm/hvm.h |  6 +++---
 5 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 36ab235..cc7f433 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -53,6 +53,7 @@ static int update_domain_cpuid_info(struct domain *d,
     struct cpuid_policy *p = d->arch.cpuid;
     const struct cpuid_leaf leaf = { ctl->eax, ctl->ebx, ctl->ecx, ctl->edx };
     int old_vendor = p->x86_vendor;
+    bool call_policy_changed = false; /* Avoid for_each_vcpu() unnecessarily */
 
     /*
      * Skip update for leaves we don't care about.  This avoids the overhead
@@ -128,13 +129,7 @@ static int update_domain_cpuid_info(struct domain *d,
     switch ( ctl->input[0] )
     {
     case 0:
-        if ( is_hvm_domain(d) && (p->x86_vendor != old_vendor) )
-        {
-            struct vcpu *v;
-
-            for_each_vcpu( d, v )
-                hvm_update_guest_vendor(v);
-        }
+        call_policy_changed = (p->x86_vendor != old_vendor);
         break;
 
     case 1:
@@ -299,6 +294,14 @@ static int update_domain_cpuid_info(struct domain *d,
         break;
     }
 
+    if ( is_hvm_domain(d) && call_policy_changed )
+    {
+        struct vcpu *v;
+
+        for_each_vcpu( d, v )
+            hvm_cpuid_policy_changed(v);
+    }
+
     return 0;
 }
 
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 28bc7e4..61df92c 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -1555,7 +1555,7 @@ int hvm_vcpu_initialise(struct vcpu *v)
         hvm_set_guest_tsc(v, 0);
     }
 
-    hvm_update_guest_vendor(v);
+    hvm_cpuid_policy_changed(v);
 
     return 0;
 
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 2e62b9b..c48fdfa 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -613,7 +613,7 @@ static void svm_update_guest_efer(struct vcpu *v)
     vmcb_set_efer(vmcb, new_efer);
 }
 
-static void svm_update_guest_vendor(struct vcpu *v)
+static void svm_cpuid_policy_changed(struct vcpu *v)
 {
     struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
     struct vmcb_struct *vmcb = arch_svm->vmcb;
@@ -2424,7 +2424,7 @@ static struct hvm_function_table __initdata svm_function_table = {
     .get_shadow_gs_base   = svm_get_shadow_gs_base,
     .update_guest_cr      = svm_update_guest_cr,
     .update_guest_efer    = svm_update_guest_efer,
-    .update_guest_vendor  = svm_update_guest_vendor,
+    .cpuid_policy_changed = svm_cpuid_policy_changed,
     .fpu_leave            = svm_fpu_leave,
     .set_guest_pat        = svm_set_guest_pat,
     .get_guest_pat        = svm_get_guest_pat,
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index e526e88..e036303 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -72,7 +72,6 @@ static void vmx_free_vlapic_mapping(struct domain *d);
 static void vmx_install_vlapic_mapping(struct vcpu *v);
 static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr);
 static void vmx_update_guest_efer(struct vcpu *v);
-static void vmx_update_guest_vendor(struct vcpu *v);
 static void vmx_wbinvd_intercept(void);
 static void vmx_fpu_dirty_intercept(void);
 static int vmx_msr_read_intercept(unsigned int msr, uint64_t *msr_content);
@@ -655,7 +654,7 @@ void vmx_update_exception_bitmap(struct vcpu *v)
         __vmwrite(EXCEPTION_BITMAP, bitmap);
 }
 
-static void vmx_update_guest_vendor(struct vcpu *v)
+static void vmx_cpuid_policy_changed(struct vcpu *v)
 {
     if ( opt_hvm_fep ||
          (v->domain->arch.cpuid->x86_vendor != boot_cpu_data.x86_vendor) )
@@ -2318,7 +2317,7 @@ static struct hvm_function_table __initdata vmx_function_table = {
     .update_host_cr3      = vmx_update_host_cr3,
     .update_guest_cr      = vmx_update_guest_cr,
     .update_guest_efer    = vmx_update_guest_efer,
-    .update_guest_vendor  = vmx_update_guest_vendor,
+    .cpuid_policy_changed = vmx_cpuid_policy_changed,
     .fpu_leave            = vmx_fpu_leave,
     .set_guest_pat        = vmx_set_guest_pat,
     .get_guest_pat        = vmx_get_guest_pat,
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index 6ecad33..7275c65 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -135,7 +135,7 @@ struct hvm_function_table {
     void (*update_guest_cr)(struct vcpu *v, unsigned int cr);
     void (*update_guest_efer)(struct vcpu *v);
 
-    void (*update_guest_vendor)(struct vcpu *v);
+    void (*cpuid_policy_changed)(struct vcpu *v);
 
     void (*fpu_leave)(struct vcpu *v);
 
@@ -334,9 +334,9 @@ static inline void hvm_update_guest_efer(struct vcpu *v)
     hvm_funcs.update_guest_efer(v);
 }
 
-static inline void hvm_update_guest_vendor(struct vcpu *v)
+static inline void hvm_cpuid_policy_changed(struct vcpu *v)
 {
-    hvm_funcs.update_guest_vendor(v);
+    hvm_funcs.cpuid_policy_changed(v);
 }
 
 /*
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 04/26] x86: Introduce a common cpuid_policy_updated()
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (2 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 03/26] x86/hvm: Rename update_guest_vendor() callback to cpuid_policy_changed() Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 05/26] x86/entry: Remove support for partial cpu_user_regs frames Andrew Cooper
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

No practical change at the moment, but future changes will need to react
irrespective of guest type.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/domain.c        | 12 ++++++++++++
 xen/arch/x86/domctl.c        |  4 ++--
 xen/arch/x86/hvm/hvm.c       |  2 --
 xen/include/asm-x86/domain.h |  2 ++
 4 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index b17468c..d383489 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -363,6 +363,8 @@ int vcpu_initialise(struct vcpu *v)
 
         if ( (rc = init_vcpu_msr_policy(v)) )
             goto fail;
+
+        cpuid_policy_updated(v);
     }
 
     return rc;
@@ -2019,6 +2021,16 @@ int domain_relinquish_resources(struct domain *d)
     return 0;
 }
 
+/*
+ * Called during vcpu construction, and each time the toolstack changes the
+ * CPUID configuration for the domain.
+ */
+void cpuid_policy_updated(struct vcpu *v)
+{
+    if ( is_hvm_vcpu(v) )
+        hvm_cpuid_policy_changed(v);
+}
+
 void arch_dump_domain_info(struct domain *d)
 {
     paging_dump_domain_info(d);
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index cc7f433..5973d9f 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -294,12 +294,12 @@ static int update_domain_cpuid_info(struct domain *d,
         break;
     }
 
-    if ( is_hvm_domain(d) && call_policy_changed )
+    if ( call_policy_changed )
     {
         struct vcpu *v;
 
         for_each_vcpu( d, v )
-            hvm_cpuid_policy_changed(v);
+            cpuid_policy_updated(v);
     }
 
     return 0;
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 61df92c..6a1c752 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -1555,8 +1555,6 @@ int hvm_vcpu_initialise(struct vcpu *v)
         hvm_set_guest_tsc(v, 0);
     }
 
-    hvm_cpuid_policy_changed(v);
-
     return 0;
 
  fail6:
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index f699119..4679d54 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -79,6 +79,8 @@ void toggle_guest_mode(struct vcpu *);
 /* x86/64: toggle guest page tables between kernel and user modes. */
 void toggle_guest_pt(struct vcpu *);
 
+void cpuid_policy_updated(struct vcpu *v);
+
 /*
  * Initialise a hypercall-transfer page. The given pointer must be mapped
  * in Xen virtual address space (accesses are not validated or checked).
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 05/26] x86/entry: Remove support for partial cpu_user_regs frames
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (3 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 04/26] x86: Introduce a common cpuid_policy_updated() Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  8:51   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 06/26] x86/entry: Rearrange RESTORE_ALL to restore register in stack order Andrew Cooper
                   ` (20 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Save all GPRs on entry to Xen.

The entry_int82() path is via a DPL1 gate, only usable by 32bit PV guests, so
can get away with only saving the 32bit registers.  All other entrypoints can
be reached from 32 or 64bit contexts.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
---
 tools/tests/x86_emulator/x86-emulate.c |   1 -
 xen/arch/x86/pv/domain.c               |   1 -
 xen/arch/x86/pv/emul-priv-op.c         |   2 -
 xen/arch/x86/x86_64/compat/entry.S     |   7 ++-
 xen/arch/x86/x86_64/entry.S            |  12 ++--
 xen/arch/x86/x86_64/traps.c            |  13 ++--
 xen/arch/x86/x86_emulate.c             |   1 -
 xen/arch/x86/x86_emulate/x86_emulate.c |   8 +--
 xen/common/wait.c                      |   1 -
 xen/include/asm-x86/asm_defns.h        | 105 +++------------------------------
 10 files changed, 26 insertions(+), 125 deletions(-)

diff --git a/tools/tests/x86_emulator/x86-emulate.c b/tools/tests/x86_emulator/x86-emulate.c
index 975ddc7..9056610 100644
--- a/tools/tests/x86_emulator/x86-emulate.c
+++ b/tools/tests/x86_emulator/x86-emulate.c
@@ -3,7 +3,6 @@
 #include <sys/mman.h>
 
 #define cpu_has_amd_erratum(nr) 0
-#define mark_regs_dirty(r) ((void)(r))
 #define cpu_has_mpx false
 #define read_bndcfgu() 0
 #define xstate_set_init(what)
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 2234128..74e9e66 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -20,7 +20,6 @@
 static void noreturn continue_nonidle_domain(struct vcpu *v)
 {
     check_wakeup_from_wait();
-    mark_regs_dirty(guest_cpu_user_regs());
     reset_stack_and_jump(ret_from_intr);
 }
 
diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
index 6115840..1041a4c 100644
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -337,7 +337,6 @@ static int read_io(unsigned int port, unsigned int bytes,
         io_emul_stub_t *io_emul =
             io_emul_stub_setup(poc, ctxt->opcode, port, bytes);
 
-        mark_regs_dirty(ctxt->regs);
         io_emul(ctxt->regs);
         return X86EMUL_DONE;
     }
@@ -436,7 +435,6 @@ static int write_io(unsigned int port, unsigned int bytes,
         io_emul_stub_t *io_emul =
             io_emul_stub_setup(poc, ctxt->opcode, port, bytes);
 
-        mark_regs_dirty(ctxt->regs);
         io_emul(ctxt->regs);
         if ( (bytes == 1) && pv_post_outb_hook )
             pv_post_outb_hook(port, val);
diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
index ba6e941..3fea54e 100644
--- a/xen/arch/x86/x86_64/compat/entry.S
+++ b/xen/arch/x86/x86_64/compat/entry.S
@@ -16,7 +16,8 @@
 ENTRY(entry_int82)
         ASM_CLAC
         pushq $0
-        SAVE_VOLATILE type=HYPERCALL_VECTOR compat=1
+        movl  $HYPERCALL_VECTOR, 4(%rsp)
+        SAVE_ALL compat=1 /* DPL1 gate, restricted to 32bit PV guests only. */
         CR4_PV32_RESTORE
 
         GET_CURRENT(bx)
@@ -60,7 +61,6 @@ compat_test_guest_events:
 /* %rbx: struct vcpu */
 compat_process_softirqs:
         sti
-        andl  $~TRAP_regs_partial,UREGS_entry_vector(%rsp)
         call  do_softirq
         jmp   compat_test_all_events
 
@@ -197,7 +197,8 @@ ENTRY(cstar_enter)
         pushq $FLAT_USER_CS32
         pushq %rcx
         pushq $0
-        SAVE_VOLATILE TRAP_syscall
+        movl  $TRAP_syscall, 4(%rsp)
+        SAVE_ALL
         GET_CURRENT(bx)
         movq  VCPU_domain(%rbx),%rcx
         cmpb  $0,DOMAIN_is_32bit_pv(%rcx)
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 6066ed8..1dd9ccf 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -98,7 +98,8 @@ ENTRY(lstar_enter)
         pushq $FLAT_KERNEL_CS64
         pushq %rcx
         pushq $0
-        SAVE_VOLATILE TRAP_syscall
+        movl  $TRAP_syscall, 4(%rsp)
+        SAVE_ALL
         GET_CURRENT(bx)
         testb $TF_kernel_mode,VCPU_thread_flags(%rbx)
         jz    switch_to_kernel
@@ -140,7 +141,6 @@ test_guest_events:
 /* %rbx: struct vcpu */
 process_softirqs:
         sti       
-        SAVE_PRESERVED
         call do_softirq
         jmp  test_all_events
 
@@ -190,7 +190,8 @@ GLOBAL(sysenter_eflags_saved)
         pushq $3 /* ring 3 null cs */
         pushq $0 /* null rip */
         pushq $0
-        SAVE_VOLATILE TRAP_syscall
+        movl  $TRAP_syscall, 4(%rsp)
+        SAVE_ALL
         GET_CURRENT(bx)
         cmpb  $0,VCPU_sysenter_disables_events(%rbx)
         movq  VCPU_sysenter_addr(%rbx),%rax
@@ -207,7 +208,6 @@ UNLIKELY_END(sysenter_nt_set)
         leal  (,%rcx,TBF_INTERRUPT),%ecx
 UNLIKELY_START(z, sysenter_gpf)
         movq  VCPU_trap_ctxt(%rbx),%rsi
-        SAVE_PRESERVED
         movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
         movl  %eax,TRAPBOUNCE_error_code(%rdx)
         movq  TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rsi),%rax
@@ -225,7 +225,8 @@ UNLIKELY_END(sysenter_gpf)
 ENTRY(int80_direct_trap)
         ASM_CLAC
         pushq $0
-        SAVE_VOLATILE 0x80
+        movl  $0x80, 4(%rsp)
+        SAVE_ALL
 
         cmpb  $0,untrusted_msi(%rip)
 UNLIKELY_START(ne, msi_check)
@@ -253,7 +254,6 @@ int80_slow_path:
          * IDT entry with DPL==0.
          */
         movl  $((0x80 << 3) | X86_XEC_IDT),UREGS_error_code(%rsp)
-        SAVE_PRESERVED
         movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
         /* A GPF wouldn't have incremented the instruction pointer. */
         subq  $2,UREGS_rip(%rsp)
diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index 2a326be..3652f5f 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -80,15 +80,10 @@ static void _show_registers(
            regs->rbp, regs->rsp, regs->r8);
     printk("r9:  %016lx   r10: %016lx   r11: %016lx\n",
            regs->r9,  regs->r10, regs->r11);
-    if ( !(regs->entry_vector & TRAP_regs_partial) )
-    {
-        printk("r12: %016lx   r13: %016lx   r14: %016lx\n",
-               regs->r12, regs->r13, regs->r14);
-        printk("r15: %016lx   cr0: %016lx   cr4: %016lx\n",
-               regs->r15, crs[0], crs[4]);
-    }
-    else
-        printk("cr0: %016lx   cr4: %016lx\n", crs[0], crs[4]);
+    printk("r12: %016lx   r13: %016lx   r14: %016lx\n",
+           regs->r12, regs->r13, regs->r14);
+    printk("r15: %016lx   cr0: %016lx   cr4: %016lx\n",
+           regs->r15, crs[0], crs[4]);
     printk("cr3: %016lx   cr2: %016lx\n", crs[3], crs[2]);
     printk("fsb: %016lx   gsb: %016lx   gss: %016lx\n",
            crs[5], crs[6], crs[7]);
diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c
index cc334ca..c7ba221 100644
--- a/xen/arch/x86/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate.c
@@ -11,7 +11,6 @@
 
 #include <xen/domain_page.h>
 #include <asm/x86_emulate.h>
-#include <asm/asm_defns.h> /* mark_regs_dirty() */
 #include <asm/processor.h> /* current_cpu_info */
 #include <asm/xstate.h>
 #include <asm/amd.h> /* cpu_has_amd_erratum() */
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
index 54a2756..820495f 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -1956,10 +1956,10 @@ decode_register(
     case  9: p = &regs->r9;  break;
     case 10: p = &regs->r10; break;
     case 11: p = &regs->r11; break;
-    case 12: mark_regs_dirty(regs); p = &regs->r12; break;
-    case 13: mark_regs_dirty(regs); p = &regs->r13; break;
-    case 14: mark_regs_dirty(regs); p = &regs->r14; break;
-    case 15: mark_regs_dirty(regs); p = &regs->r15; break;
+    case 12: p = &regs->r12; break;
+    case 13: p = &regs->r13; break;
+    case 14: p = &regs->r14; break;
+    case 15: p = &regs->r15; break;
 #endif
     default: BUG(); p = NULL; break;
     }
diff --git a/xen/common/wait.c b/xen/common/wait.c
index 9490a17..c5fc094 100644
--- a/xen/common/wait.c
+++ b/xen/common/wait.c
@@ -127,7 +127,6 @@ static void __prepare_to_wait(struct waitqueue_vcpu *wqv)
     unsigned long dummy;
     u32 entry_vector = cpu_info->guest_cpu_user_regs.entry_vector;
 
-    cpu_info->guest_cpu_user_regs.entry_vector &= ~TRAP_regs_partial;
     ASSERT(wqv->esp == 0);
 
     /* Save current VCPU affinity; force wakeup on *this* CPU only. */
diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h
index 388fc93..98192eb 100644
--- a/xen/include/asm-x86/asm_defns.h
+++ b/xen/include/asm-x86/asm_defns.h
@@ -17,15 +17,6 @@
 void ret_from_intr(void);
 #endif
 
-#ifdef CONFIG_FRAME_POINTER
-/* Indicate special exception stack frame by inverting the frame pointer. */
-#define SETUP_EXCEPTION_FRAME_POINTER(offs)     \
-        leaq  offs(%rsp),%rbp;                  \
-        notq  %rbp
-#else
-#define SETUP_EXCEPTION_FRAME_POINTER(offs)
-#endif
-
 #ifndef NDEBUG
 #define ASSERT_INTERRUPT_STATUS(x, msg)         \
         pushf;                                  \
@@ -42,31 +33,6 @@ void ret_from_intr(void);
 #define ASSERT_INTERRUPTS_DISABLED \
     ASSERT_INTERRUPT_STATUS(z, "INTERRUPTS DISABLED")
 
-/*
- * This flag is set in an exception frame when registers R12-R15 did not get
- * saved.
- */
-#define _TRAP_regs_partial 16
-#define TRAP_regs_partial  (1 << _TRAP_regs_partial)
-/*
- * This flag gets set in an exception frame when registers R12-R15 possibly
- * get modified from their originally saved values and hence need to be
- * restored even if the normal call flow would restore register values.
- *
- * The flag being set implies _TRAP_regs_partial to be unset. Restoring
- * R12-R15 thus is
- * - required when this flag is set,
- * - safe when _TRAP_regs_partial is unset.
- */
-#define _TRAP_regs_dirty   17
-#define TRAP_regs_dirty    (1 << _TRAP_regs_dirty)
-
-#define mark_regs_dirty(r) ({ \
-        struct cpu_user_regs *r__ = (r); \
-        ASSERT(!((r__)->entry_vector & TRAP_regs_partial)); \
-        r__->entry_vector |= TRAP_regs_dirty; \
-})
-
 #ifdef __ASSEMBLY__
 # define _ASM_EX(p) p-.
 #else
@@ -236,7 +202,7 @@ static always_inline void stac(void)
 #endif
 
 #ifdef __ASSEMBLY__
-.macro SAVE_ALL op
+.macro SAVE_ALL op, compat=0
 .ifeqs "\op", "CLAC"
         ASM_CLAC
 .else
@@ -255,40 +221,6 @@ static always_inline void stac(void)
         movq  %rdx,UREGS_rdx(%rsp)
         movq  %rcx,UREGS_rcx(%rsp)
         movq  %rax,UREGS_rax(%rsp)
-        movq  %r8,UREGS_r8(%rsp)
-        movq  %r9,UREGS_r9(%rsp)
-        movq  %r10,UREGS_r10(%rsp)
-        movq  %r11,UREGS_r11(%rsp)
-        movq  %rbx,UREGS_rbx(%rsp)
-        movq  %rbp,UREGS_rbp(%rsp)
-        SETUP_EXCEPTION_FRAME_POINTER(UREGS_rbp)
-        movq  %r12,UREGS_r12(%rsp)
-        movq  %r13,UREGS_r13(%rsp)
-        movq  %r14,UREGS_r14(%rsp)
-        movq  %r15,UREGS_r15(%rsp)
-.endm
-
-/*
- * Save all registers not preserved by C code or used in entry/exit code. Mark
- * the frame as partial.
- *
- * @type: exception type
- * @compat: R8-R15 don't need saving, and the frame nevertheless is complete
- */
-.macro SAVE_VOLATILE type compat=0
-.if \compat
-        movl  $\type,UREGS_entry_vector-UREGS_error_code(%rsp)
-.else
-        movl  $\type|TRAP_regs_partial,\
-              UREGS_entry_vector-UREGS_error_code(%rsp)
-.endif
-        addq  $-(UREGS_error_code-UREGS_r15),%rsp
-        cld
-        movq  %rdi,UREGS_rdi(%rsp)
-        movq  %rsi,UREGS_rsi(%rsp)
-        movq  %rdx,UREGS_rdx(%rsp)
-        movq  %rcx,UREGS_rcx(%rsp)
-        movq  %rax,UREGS_rax(%rsp)
 .if !\compat
         movq  %r8,UREGS_r8(%rsp)
         movq  %r9,UREGS_r9(%rsp)
@@ -297,20 +229,17 @@ static always_inline void stac(void)
 .endif
         movq  %rbx,UREGS_rbx(%rsp)
         movq  %rbp,UREGS_rbp(%rsp)
-        SETUP_EXCEPTION_FRAME_POINTER(UREGS_rbp)
-.endm
-
-/*
- * Complete a frame potentially only partially saved.
- */
-.macro SAVE_PRESERVED
-        btrl  $_TRAP_regs_partial,UREGS_entry_vector(%rsp)
-        jnc   987f
+#ifdef CONFIG_FRAME_POINTER
+/* Indicate special exception stack frame by inverting the frame pointer. */
+        leaq  UREGS_rbp(%rsp), %rbp
+        notq  %rbp
+#endif
+.if !\compat
         movq  %r12,UREGS_r12(%rsp)
         movq  %r13,UREGS_r13(%rsp)
         movq  %r14,UREGS_r14(%rsp)
         movq  %r15,UREGS_r15(%rsp)
-987:
+.endif
 .endm
 
 #define LOAD_ONE_REG(reg, compat) \
@@ -330,7 +259,6 @@ static always_inline void stac(void)
  */
 .macro RESTORE_ALL adj=0 compat=0
 .if !\compat
-        testl $TRAP_regs_dirty,UREGS_entry_vector(%rsp)
         movq  UREGS_r11(%rsp),%r11
         movq  UREGS_r10(%rsp),%r10
         movq  UREGS_r9(%rsp),%r9
@@ -347,33 +275,16 @@ static always_inline void stac(void)
         LOAD_ONE_REG(si, \compat)
         LOAD_ONE_REG(di, \compat)
 .if !\compat
-        jz    987f
         movq  UREGS_r15(%rsp),%r15
         movq  UREGS_r14(%rsp),%r14
         movq  UREGS_r13(%rsp),%r13
         movq  UREGS_r12(%rsp),%r12
-#ifndef NDEBUG
-        .subsection 1
-987:    testl $TRAP_regs_partial,UREGS_entry_vector(%rsp)
-        jnz   987f
-        cmpq  UREGS_r15(%rsp),%r15
-        jne   789f
-        cmpq  UREGS_r14(%rsp),%r14
-        jne   789f
-        cmpq  UREGS_r13(%rsp),%r13
-        jne   789f
-        cmpq  UREGS_r12(%rsp),%r12
-        je    987f
-789:    BUG   /* Corruption of partial register state. */
-        .subsection 0
-#endif
 .else
         xor %r15, %r15
         xor %r14, %r14
         xor %r13, %r13
         xor %r12, %r12
 .endif
-987:
         LOAD_ONE_REG(bp, \compat)
         LOAD_ONE_REG(bx, \compat)
         subq  $-(UREGS_error_code-UREGS_r15+\adj), %rsp
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 06/26] x86/entry: Rearrange RESTORE_ALL to restore register in stack order
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (4 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 05/26] x86/entry: Remove support for partial cpu_user_regs frames Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 07/26] x86/hvm: Use SAVE_ALL to construct the cpu_user_regs frame after VMExit Andrew Cooper
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Results in a more predictable (i.e. linear) memory access pattern.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
---
 xen/include/asm-x86/asm_defns.h | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h
index 98192eb..fa62c54 100644
--- a/xen/include/asm-x86/asm_defns.h
+++ b/xen/include/asm-x86/asm_defns.h
@@ -259,6 +259,19 @@ static always_inline void stac(void)
  */
 .macro RESTORE_ALL adj=0 compat=0
 .if !\compat
+        movq  UREGS_r15(%rsp), %r15
+        movq  UREGS_r14(%rsp), %r14
+        movq  UREGS_r13(%rsp), %r13
+        movq  UREGS_r12(%rsp), %r12
+.else
+        xor %r15, %r15
+        xor %r14, %r14
+        xor %r13, %r13
+        xor %r12, %r12
+.endif
+        LOAD_ONE_REG(bp, \compat)
+        LOAD_ONE_REG(bx, \compat)
+.if !\compat
         movq  UREGS_r11(%rsp),%r11
         movq  UREGS_r10(%rsp),%r10
         movq  UREGS_r9(%rsp),%r9
@@ -274,19 +287,6 @@ static always_inline void stac(void)
         LOAD_ONE_REG(dx, \compat)
         LOAD_ONE_REG(si, \compat)
         LOAD_ONE_REG(di, \compat)
-.if !\compat
-        movq  UREGS_r15(%rsp),%r15
-        movq  UREGS_r14(%rsp),%r14
-        movq  UREGS_r13(%rsp),%r13
-        movq  UREGS_r12(%rsp),%r12
-.else
-        xor %r15, %r15
-        xor %r14, %r14
-        xor %r13, %r13
-        xor %r12, %r12
-.endif
-        LOAD_ONE_REG(bp, \compat)
-        LOAD_ONE_REG(bx, \compat)
         subq  $-(UREGS_error_code-UREGS_r15+\adj), %rsp
 .endm
 
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 07/26] x86/hvm: Use SAVE_ALL to construct the cpu_user_regs frame after VMExit
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (5 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 06/26] x86/entry: Rearrange RESTORE_ALL to restore register in stack order Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 08/26] x86/entry: Erase guest GPR state on entry to Xen Andrew Cooper
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

No practical change.

One side effect in debug builds is that %rbp is inverted in the manner
expected by the stack unwinder to indicate a interrupt frame.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
---
 xen/arch/x86/hvm/svm/entry.S | 22 ++++------------------
 xen/arch/x86/hvm/vmx/entry.S | 17 ++---------------
 2 files changed, 6 insertions(+), 33 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/entry.S b/xen/arch/x86/hvm/svm/entry.S
index 4a72e38..df86da0 100644
--- a/xen/arch/x86/hvm/svm/entry.S
+++ b/xen/arch/x86/hvm/svm/entry.S
@@ -98,24 +98,10 @@ UNLIKELY_END(svm_trace)
 
         VMRUN
 
-        GET_CURRENT(ax)
-        push %rdi
-        push %rsi
-        push %rdx
-        push %rcx
-        mov  VCPU_svm_vmcb(%rax),%rcx
-        push %rax
-        push %r8
-        push %r9
-        push %r10
-        push %r11
-        push %rbx
-        mov  %rax,%rbx
-        push %rbp
-        push %r12
-        push %r13
-        push %r14
-        push %r15
+        SAVE_ALL
+
+        GET_CURRENT(bx)
+        mov  VCPU_svm_vmcb(%rbx),%rcx
 
         movb $0,VCPU_svm_vmcb_in_sync(%rbx)
         mov  VMCB_rax(%rcx),%rax
diff --git a/xen/arch/x86/hvm/vmx/entry.S b/xen/arch/x86/hvm/vmx/entry.S
index 47cd674..b2f98be 100644
--- a/xen/arch/x86/hvm/vmx/entry.S
+++ b/xen/arch/x86/hvm/vmx/entry.S
@@ -30,23 +30,10 @@
 #define VMLAUNCH     .byte 0x0f,0x01,0xc2
 
 ENTRY(vmx_asm_vmexit_handler)
-        push %rdi
-        push %rsi
-        push %rdx
-        push %rcx
-        push %rax
+        SAVE_ALL
+
         mov  %cr2,%rax
-        push %r8
-        push %r9
-        push %r10
-        push %r11
-        push %rbx
         GET_CURRENT(bx)
-        push %rbp
-        push %r12
-        push %r13
-        push %r14
-        push %r15
 
         movb $1,VCPU_vmx_launched(%rbx)
         mov  %rax,VCPU_hvm_guest_cr2(%rbx)
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 08/26] x86/entry: Erase guest GPR state on entry to Xen
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (6 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 07/26] x86/hvm: Use SAVE_ALL to construct the cpu_user_regs frame after VMExit Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-22 10:04   ` David Woodhouse
  2018-01-04  0:15 ` [PATCH v6.5 09/26] x86: Support compiling with indirect branch thunks Andrew Cooper
                   ` (17 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

This reduces the number of code gadgets which can be attacked with arbitrary
guest-controlled GPR values.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
---
 xen/include/asm-x86/asm_defns.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h
index fa62c54..7e8838e 100644
--- a/xen/include/asm-x86/asm_defns.h
+++ b/xen/include/asm-x86/asm_defns.h
@@ -217,22 +217,34 @@ static always_inline void stac(void)
         addq  $-(UREGS_error_code-UREGS_r15), %rsp
         cld
         movq  %rdi,UREGS_rdi(%rsp)
+        xor   %edi, %edi
         movq  %rsi,UREGS_rsi(%rsp)
+        xor   %esi, %esi
         movq  %rdx,UREGS_rdx(%rsp)
+        xor   %edx, %edx
         movq  %rcx,UREGS_rcx(%rsp)
+        xor   %ecx, %ecx
         movq  %rax,UREGS_rax(%rsp)
+        xor   %eax, %eax
 .if !\compat
         movq  %r8,UREGS_r8(%rsp)
         movq  %r9,UREGS_r9(%rsp)
         movq  %r10,UREGS_r10(%rsp)
         movq  %r11,UREGS_r11(%rsp)
 .endif
+        xor   %r8, %r8
+        xor   %r9, %r9
+        xor   %r10, %r10
+        xor   %r11, %r11
         movq  %rbx,UREGS_rbx(%rsp)
+        xor   %ebx, %ebx
         movq  %rbp,UREGS_rbp(%rsp)
 #ifdef CONFIG_FRAME_POINTER
 /* Indicate special exception stack frame by inverting the frame pointer. */
         leaq  UREGS_rbp(%rsp), %rbp
         notq  %rbp
+#else
+        xor   %ebp, %ebp
 #endif
 .if !\compat
         movq  %r12,UREGS_r12(%rsp)
@@ -240,6 +252,10 @@ static always_inline void stac(void)
         movq  %r14,UREGS_r14(%rsp)
         movq  %r15,UREGS_r15(%rsp)
 .endif
+        xor   %r12, %r12
+        xor   %r13, %r13
+        xor   %r14, %r14
+        xor   %r15, %r15
 .endm
 
 #define LOAD_ONE_REG(reg, compat) \
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 09/26] x86: Support compiling with indirect branch thunks
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (7 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 08/26] x86/entry: Erase guest GPR state on entry to Xen Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  9:02   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 10/26] common/wait: Clarifications to wait infrastructure Andrew Cooper
                   ` (16 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Use -mindirect-branch=thunk-extern/-mindirect-branch-register when available.
To begin with, use the retpoline thunk.  Later work will add alternative
thunks which can be selected at boot time.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v4:
 * New
---
 xen/arch/x86/Makefile         |  1 +
 xen/arch/x86/Rules.mk         |  7 +++++++
 xen/arch/x86/indirect_thunk.S | 28 ++++++++++++++++++++++++++++
 xen/arch/x86/xen.lds.S        |  1 +
 4 files changed, 37 insertions(+)
 create mode 100644 xen/arch/x86/indirect_thunk.S

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index d5d58a2..433233c 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -36,6 +36,7 @@ obj-y += io_apic.o
 obj-$(CONFIG_LIVEPATCH) += alternative.o livepatch.o
 obj-y += msi.o
 obj-y += msr.o
+obj-$(CONFIG_INDIRECT_THUNK) += indirect_thunk.o
 obj-y += ioport_emulate.o
 obj-y += irq.o
 obj-$(CONFIG_KEXEC) += machine_kexec.o
diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk
index 568657e..abcc4d4 100644
--- a/xen/arch/x86/Rules.mk
+++ b/xen/arch/x86/Rules.mk
@@ -30,3 +30,10 @@ CFLAGS += -fno-asynchronous-unwind-tables
 ifneq ($(call cc-option,$(CC),-fvisibility=hidden,n),n)
 CFLAGS += -DGCC_HAS_VISIBILITY_ATTRIBUTE
 endif
+
+# Compile with thunk-extern, indirect-branch-register if avaiable.
+ifneq ($(call cc-option,$(CC),-mindirect-branch-register,n),n)
+CFLAGS += -mindirect-branch=thunk-extern -mindirect-branch-register
+CFLAGS += -DCONFIG_INDIRECT_THUNK
+export CONFIG_INDIRECT_THUNK=y
+endif
diff --git a/xen/arch/x86/indirect_thunk.S b/xen/arch/x86/indirect_thunk.S
new file mode 100644
index 0000000..4fef1c8
--- /dev/null
+++ b/xen/arch/x86/indirect_thunk.S
@@ -0,0 +1,28 @@
+#include <asm/asm_defns.h>
+
+.macro IND_THUNK_RETPOLINE reg:req
+        call 2f
+1:
+        lfence
+        jmp 1b
+2:
+        mov \reg, (%rsp)
+        ret
+.endm
+
+/*
+ * Build the __x86.indirect_thunk.* symbols.  Execution lands on an
+ * alternative patch point which implements one of the above THUNK_*'s
+ */
+.macro GEN_INDIRECT_THUNK name:req reg:req
+        .section .text.__x86.indirect_thunk.\name, "ax", @progbits
+
+ENTRY(__x86.indirect_thunk.\name)
+        IND_THUNK_RETPOLINE \reg
+.endm
+
+/* Instantiate GEN_INDIRECT_THUNK for each register except %rsp. */
+.irp enc, rax, rbx, rcx, rdx, rsi, rdi, rbp, \
+          r8, r9, r10, r11, r12, r13, r14, r15
+        GEN_INDIRECT_THUNK name=\enc, reg=%\enc
+.endr
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index d5e8821..345946f 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -59,6 +59,7 @@ SECTIONS
   .text : {
         _stext = .;            /* Text and read-only data */
        *(.text)
+       *(.text.__x86.*)
        *(.text.cold)
        *(.text.unlikely)
        *(.fixup)
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 10/26] common/wait: Clarifications to wait infrastructure
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (8 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 09/26] x86: Support compiling with indirect branch thunks Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code Andrew Cooper
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

This logic is not as clear as it could be.  Add some comments to help.

Rearrange the asm block in __prepare_to_wait() to separate the GPR
saving/restoring from the internal logic.

While tweaking, add an unreachable() following the jmp in
check_wakeup_from_wait().

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
v6:
 * New
---
 xen/common/wait.c | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/xen/common/wait.c b/xen/common/wait.c
index c5fc094..3d3d9fe 100644
--- a/xen/common/wait.c
+++ b/xen/common/wait.c
@@ -138,14 +138,26 @@ static void __prepare_to_wait(struct waitqueue_vcpu *wqv)
         domain_crash_synchronous();
     }
 
+    /* Hand-rolled setjmp(). */
     asm volatile (
-        "push %%rax; push %%rbx; push %%rdx; "
-        "push %%rbp; push %%r8; push %%r9; push %%r10; push %%r11; "
-        "push %%r12; push %%r13; push %%r14; push %%r15; call 1f; "
-        "1: addq $2f-1b,(%%rsp); sub %%esp,%%ecx; cmp %3,%%ecx; ja 3f; "
-        "mov %%rsp,%%rsi; 2: rep movsb; mov %%rsp,%%rsi; 3: pop %%rax; "
-        "pop %%r15; pop %%r14; pop %%r13; pop %%r12; "
-        "pop %%r11; pop %%r10; pop %%r9; pop %%r8; "
+        "push %%rax; push %%rbx; push %%rdx; push %%rbp;"
+        "push %%r8;  push %%r9;  push %%r10; push %%r11;"
+        "push %%r12; push %%r13; push %%r14; push %%r15;"
+
+        "call 1f;"
+        "1: addq $2f-1b,(%%rsp);"
+        "sub %%esp,%%ecx;"
+        "cmp %3,%%ecx;"
+        "ja 3f;"
+        "mov %%rsp,%%rsi;"
+
+        /* check_wakeup_from_wait() longjmp()'s to this point. */
+        "2: rep movsb;"
+        "mov %%rsp,%%rsi;"
+        "3: pop %%rax;"
+
+        "pop %%r15; pop %%r14; pop %%r13; pop %%r12;"
+        "pop %%r11; pop %%r10; pop %%r9;  pop %%r8;"
         "pop %%rbp; pop %%rdx; pop %%rbx; pop %%rax"
         : "=&S" (wqv->esp), "=&c" (dummy), "=&D" (dummy)
         : "i" (PAGE_SIZE), "0" (0), "1" (cpu_info), "2" (wqv->stack)
@@ -189,11 +201,16 @@ void check_wakeup_from_wait(void)
         wait(); /* takes us back into the scheduler */
     }
 
+    /*
+     * Hand-rolled longjmp().  Returns to the pointer on the top of
+     * wqv->stack, and lands on a `rep movs` instruction.
+     */
     asm volatile (
         "mov %1,%%"__OP"sp; jmp *(%0)"
         : : "S" (wqv->stack), "D" (wqv->esp),
         "c" ((char *)get_cpu_info() - (char *)wqv->esp)
         : "memory" );
+    unreachable();
 }
 
 #else /* !CONFIG_X86 */
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (9 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 10/26] common/wait: Clarifications to wait infrastructure Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  9:23   ` Jan Beulich
  2018-01-11 13:03   ` David Woodhouse
  2018-01-04  0:15 ` [PATCH v6.5 12/26] x86/boot: Report details of speculative mitigations Andrew Cooper
                   ` (14 subsequent siblings)
  25 siblings, 2 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Introduce CALL_THUNK and JMP_THUNK which either degrade to a normal indirect
branch, or dispatch to the __x86.indirect_thunk.* symbols.

Update all the manual indirect branches in to use the new thunks.  The
indirect branches in the early boot and kexec path are left intact as we can't
use the compiled-in thunks at those points.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v4:
 * New
v6:
 * Thunk more assembly
 * Fix check_wakeup_from_wait() to not corrupt its stack
v7:
 * Protect the jmp from the trampoline into the high mappings on the AP boot
   path, and the hand-crafted indirect jump in the PV IO emulation stubs.
---
 xen/arch/x86/boot/trampoline.S           | 24 +++++++++++++++++--
 xen/arch/x86/extable.c                   |  4 ++--
 xen/arch/x86/pv/emul-priv-op.c           | 41 ++++++++++++++++++++++++--------
 xen/arch/x86/x86_64/entry.S              |  6 +++--
 xen/arch/x86/x86_emulate/x86_emulate.c   |  4 ++--
 xen/common/wait.c                        |  8 ++++---
 xen/include/asm-x86/asm_defns.h          |  8 +++++++
 xen/include/asm-x86/indirect_thunk_asm.h | 41 ++++++++++++++++++++++++++++++++
 8 files changed, 115 insertions(+), 21 deletions(-)
 create mode 100644 xen/include/asm-x86/indirect_thunk_asm.h

diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
index 4d640f3..abf40f3 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -153,8 +153,28 @@ trampoline_protmode_entry:
         .code64
 start64:
         /* Jump to high mappings. */
-        movabs  $__high_start,%rax
-        jmpq    *%rax
+        movabs  $__high_start, %rdi
+
+#ifdef CONFIG_INDIRECT_THUNK
+        /*
+         * If booting virtualised, or hot-onlining a CPU, sibling threads can
+         * attempt Branch Target Injection against this jmp.
+         *
+         * We've got no usable stack so can't use a RETPOLINE thunk, and are
+         * further than +- 2G from the high mappings so couldn't use JUMP_THUNK
+         * even if was a non-RETPOLINE thunk.  Futhermore, an LFENCE isn't
+         * necesserily safe to use at this point.
+         *
+         * As this isn't a hotpath, use a fully serialising event to reduce
+         * the speculation window as much as possible.  %ebx needs preserving
+         * for __high_start.
+         */
+        mov     %ebx, %esi
+        cpuid
+        mov     %esi, %ebx
+#endif
+
+        jmpq    *%rdi
 
 #include "wakeup.S"
 
diff --git a/xen/arch/x86/extable.c b/xen/arch/x86/extable.c
index 6fffe05..bf5822d 100644
--- a/xen/arch/x86/extable.c
+++ b/xen/arch/x86/extable.c
@@ -158,7 +158,7 @@ static int __init stub_selftest(void)
         memcpy(ptr, tests[i].opc, ARRAY_SIZE(tests[i].opc));
         unmap_domain_page(ptr);
 
-        asm volatile ( "call *%[stb]\n"
+        asm volatile ( "CALL_THUNK %[stb]\n"
                        ".Lret%=:\n\t"
                        ".pushsection .fixup,\"ax\"\n"
                        ".Lfix%=:\n\t"
@@ -167,7 +167,7 @@ static int __init stub_selftest(void)
                        ".popsection\n\t"
                        _ASM_EXTABLE(.Lret%=, .Lfix%=)
                        : [exn] "+m" (res)
-                       : [stb] "rm" (addr), "a" (tests[i].rax));
+                       : [stb] "r" (addr), "a" (tests[i].rax));
         ASSERT(res == tests[i].res.raw);
     }
 
diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
index 1041a4c..6da9b46 100644
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -73,37 +73,58 @@ void (*pv_post_outb_hook)(unsigned int port, u8 value);
 
 typedef void io_emul_stub_t(struct cpu_user_regs *);
 
+#ifdef CONFIG_INDIRECT_THUNK
+extern char ind_thunk_rcx[] asm ("__x86.indirect_thunk.rcx");
+#endif
+
 static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode,
                                           unsigned int port, unsigned int bytes)
 {
+    struct stubs *this_stubs = &this_cpu(stubs);
+    unsigned long stub_va = this_stubs->addr + STUB_BUF_SIZE / 2;
+
     if ( !ctxt->io_emul_stub )
-        ctxt->io_emul_stub = map_domain_page(_mfn(this_cpu(stubs.mfn))) +
-                                             (this_cpu(stubs.addr) &
-                                              ~PAGE_MASK) +
-                                             STUB_BUF_SIZE / 2;
+        ctxt->io_emul_stub =
+            map_domain_page(_mfn(this_stubs->mfn)) + (stub_va & ~PAGE_MASK);
 
     /* movq $host_to_guest_gpr_switch,%rcx */
     ctxt->io_emul_stub[0] = 0x48;
     ctxt->io_emul_stub[1] = 0xb9;
     *(void **)&ctxt->io_emul_stub[2] = (void *)host_to_guest_gpr_switch;
+
+#ifdef CONFIG_INDIRECT_THUNK
+    /* callq __x86.indirect_thunk.rcx */
+    ctxt->io_emul_stub[10] = 0xe8;
+    *(int32_t *)&ctxt->io_emul_stub[11] =
+        _p(ind_thunk_rcx) - _p(stub_va + 11 + 4);
+
+#else
     /* callq *%rcx */
     ctxt->io_emul_stub[10] = 0xff;
     ctxt->io_emul_stub[11] = 0xd1;
+
+    /*
+     * 3 bytes of P6_NOPS.
+     * TODO: untangle ideal_nops from init/livepatch Kconfig options.
+     */
+    memcpy(&ctxt->io_emul_stub[12], "\x0f\x1f\x00", 3);
+#endif
+
     /* data16 or nop */
-    ctxt->io_emul_stub[12] = (bytes != 2) ? 0x90 : 0x66;
+    ctxt->io_emul_stub[15] = (bytes != 2) ? 0x90 : 0x66;
     /* <io-access opcode> */
-    ctxt->io_emul_stub[13] = opcode;
+    ctxt->io_emul_stub[16] = opcode;
     /* imm8 or nop */
-    ctxt->io_emul_stub[14] = !(opcode & 8) ? port : 0x90;
+    ctxt->io_emul_stub[17] = !(opcode & 8) ? port : 0x90;
     /* ret (jumps to guest_to_host_gpr_switch) */
-    ctxt->io_emul_stub[15] = 0xc3;
-    BUILD_BUG_ON(STUB_BUF_SIZE / 2 < 16);
+    ctxt->io_emul_stub[18] = 0xc3;
+    BUILD_BUG_ON(STUB_BUF_SIZE / 2 < 19);
 
     if ( ioemul_handle_quirk )
         ioemul_handle_quirk(opcode, &ctxt->io_emul_stub[12], ctxt->ctxt.regs);
 
     /* Handy function-typed pointer to the stub. */
-    return (void *)(this_cpu(stubs.addr) + STUB_BUF_SIZE / 2);
+    return (void *)stub_va;
 }
 
 
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 1dd9ccf..b49d62b 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -474,7 +474,8 @@ handle_exception_saved:
         movzbl UREGS_entry_vector(%rsp),%eax
         leaq  exception_table(%rip),%rdx
         PERFC_INCR(exceptions, %rax, %rbx)
-        callq *(%rdx,%rax,8)
+        mov   (%rdx, %rax, 8), %rdx
+        CALL_THUNK %rdx
         testb $3,UREGS_cs(%rsp)
         jz    restore_all_xen
         leaq  VCPU_trap_bounce(%rbx),%rdx
@@ -615,7 +616,8 @@ handle_ist_exception:
 1:      movq  %rsp,%rdi
         movzbl UREGS_entry_vector(%rsp),%eax
         leaq  exception_table(%rip),%rdx
-        callq *(%rdx,%rax,8)
+        mov   (%rdx, %rax, 8), %rdx
+        CALL_THUNK %rdx
         cmpb  $TRAP_nmi,UREGS_entry_vector(%rsp)
         jne   ret_from_intr
 
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
index 820495f..3d56b81 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -867,7 +867,7 @@ static inline int mkec(uint8_t e, int32_t ec, ...)
 #ifdef __XEN__
 # define invoke_stub(pre, post, constraints...) do {                    \
     union stub_exception_token res_ = { .raw = ~0 };                    \
-    asm volatile ( pre "\n\tcall *%[stub]\n\t" post "\n"                \
+    asm volatile ( pre "\n\tCALL_THUNK %[stub]\n\t" post "\n"           \
                    ".Lret%=:\n\t"                                       \
                    ".pushsection .fixup,\"ax\"\n"                       \
                    ".Lfix%=:\n\t"                                       \
@@ -876,7 +876,7 @@ static inline int mkec(uint8_t e, int32_t ec, ...)
                    ".popsection\n\t"                                    \
                    _ASM_EXTABLE(.Lret%=, .Lfix%=)                       \
                    : [exn] "+g" (res_), constraints,                    \
-                     [stub] "rm" (stub.func),                           \
+                     [stub] "r" (stub.func),                            \
                      "m" (*(uint8_t(*)[MAX_INST_LEN + 1])stub.ptr) );   \
     if ( unlikely(~res_.raw) )                                          \
     {                                                                   \
diff --git a/xen/common/wait.c b/xen/common/wait.c
index 3d3d9fe..4b5a8bf 100644
--- a/xen/common/wait.c
+++ b/xen/common/wait.c
@@ -203,12 +203,14 @@ void check_wakeup_from_wait(void)
 
     /*
      * Hand-rolled longjmp().  Returns to the pointer on the top of
-     * wqv->stack, and lands on a `rep movs` instruction.
+     * wqv->stack, and lands on a `rep movs` instruction.  All other GPRs are
+     * restored from the stack, so are available for use here.
      */
     asm volatile (
-        "mov %1,%%"__OP"sp; jmp *(%0)"
+        "mov %1,%%"__OP"sp; JMP_THUNK %[ip]"
         : : "S" (wqv->stack), "D" (wqv->esp),
-        "c" ((char *)get_cpu_info() - (char *)wqv->esp)
+          "c" ((char *)get_cpu_info() - (char *)wqv->esp),
+          [ip] "r" (*(unsigned long *)wqv->stack)
         : "memory" );
     unreachable();
 }
diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h
index 7e8838e..40b0250 100644
--- a/xen/include/asm-x86/asm_defns.h
+++ b/xen/include/asm-x86/asm_defns.h
@@ -13,6 +13,14 @@
 #include <asm/cpufeature.h>
 #include <asm/alternative.h>
 
+#ifdef __ASSEMBLY__
+# include <asm/indirect_thunk_asm.h>
+#else
+asm ( "\t.equ CONFIG_INDIRECT_THUNK, "
+      __stringify(IS_ENABLED(CONFIG_INDIRECT_THUNK)) );
+asm ( "\t.include \"asm/indirect_thunk_asm.h\"" );
+#endif
+
 #ifndef __ASSEMBLY__
 void ret_from_intr(void);
 #endif
diff --git a/xen/include/asm-x86/indirect_thunk_asm.h b/xen/include/asm-x86/indirect_thunk_asm.h
new file mode 100644
index 0000000..554dd7e
--- /dev/null
+++ b/xen/include/asm-x86/indirect_thunk_asm.h
@@ -0,0 +1,41 @@
+/*
+ * Warning!  This file is included at an assembler level for .c files, causing
+ * usual #ifdef'ary to turn into comments.
+ */
+
+.macro IND_THUNK insn:req arg:req
+/*
+ * Create an indirect branch.  insn is one of call/jmp, arg is a single
+ * register.
+ *
+ * With no compiler support, this degrated into a plain indirect call/jmp.
+ * With compiler support, dispatch to the correct __x86.indirect_thunk.*
+ */
+    .if CONFIG_INDIRECT_THUNK == 1
+
+        $done = 0
+        .irp reg, rax, rbx, rcx, rdx, rsi, rdi, rbp, r8, r9, r10, r11, r12, r13, r14, r15
+        .ifeqs "\arg", "%\reg"
+            \insn __x86.indirect_thunk.\reg
+            $done = 1
+           .exitm
+        .endif
+        .endr
+
+        .if $done != 1
+        .error "Bad register arg \arg"
+        .endif
+
+    .else
+        \insn *\arg
+    .endif
+.endm
+
+/* Convenience wrappers. */
+.macro CALL_THUNK arg:req
+    IND_THUNK call, \arg
+.endm
+
+.macro JMP_THUNK arg:req
+    IND_THUNK jmp, \arg
+.endm
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 12/26] x86/boot: Report details of speculative mitigations
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (10 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  9:29   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 13/26] x86/amd: Try to set lfence as being Dispatch Serialising Andrew Cooper
                   ` (13 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Nothing very interesting at the moment, but the logic will grow as new
mitigations are added.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v3:
 * New
v4:
 * Drop the else-clause printk
 * Rebase over AMD additions
---
 xen/arch/x86/Makefile           |  1 +
 xen/arch/x86/setup.c            |  3 ++
 xen/arch/x86/spec_ctrl.c        | 75 +++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/spec_ctrl.h | 35 +++++++++++++++++++
 4 files changed, 114 insertions(+)
 create mode 100644 xen/arch/x86/spec_ctrl.c
 create mode 100644 xen/include/asm-x86/spec_ctrl.h

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 433233c..90ab93d 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -57,6 +57,7 @@ obj-y += setup.o
 obj-y += shutdown.o
 obj-y += smp.o
 obj-y += smpboot.o
+obj-y += spec_ctrl.o
 obj-y += srat.o
 obj-y += string.o
 obj-y += sysctl.o
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 2e10c6b..470427b 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -51,6 +51,7 @@
 #include <asm/alternative.h>
 #include <asm/mc146818rtc.h>
 #include <asm/cpuid.h>
+#include <asm/spec_ctrl.h>
 
 /* opt_nosmp: If true, secondary processors are ignored. */
 static bool __initdata opt_nosmp;
@@ -1502,6 +1503,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     if ( cpu_has_fsgsbase )
         set_in_cr4(X86_CR4_FSGSBASE);
 
+    init_speculation_mitigations();
+
     init_idle_domain();
 
     this_cpu(stubs.addr) = alloc_stub_page(smp_processor_id(),
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
new file mode 100644
index 0000000..ffee909
--- /dev/null
+++ b/xen/arch/x86/spec_ctrl.c
@@ -0,0 +1,75 @@
+/******************************************************************************
+ * arch/x86/spec_ctrl.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2017 Citrix Systems Ltd.
+ */
+#include <xen/init.h>
+#include <xen/lib.h>
+
+#include <asm/processor.h>
+#include <asm/spec_ctrl.h>
+
+enum ind_thunk {
+    THUNK_DEFAULT, /* Decide which thunk to use at boot time. */
+    THUNK_NONE,    /* Missing compiler support for thunks. */
+
+    THUNK_RETPOLINE,
+};
+
+static void __init print_details(enum ind_thunk thunk)
+{
+    printk(XENLOG_DEBUG "Speculative mitigation facilities:\n");
+
+    /* Compiled-in support which pertains to BTI mitigations. */
+    if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) )
+        printk(XENLOG_DEBUG "  Compiled-in support: INDIRECT_THUNK\n");
+
+    printk(XENLOG_INFO
+           "BTI mitigations: Thunk %s\n",
+           thunk == THUNK_NONE      ? "N/A" :
+           thunk == THUNK_RETPOLINE ? "RETPOLINE" : "?");
+}
+
+void __init init_speculation_mitigations(void)
+{
+    enum ind_thunk thunk = THUNK_DEFAULT;
+
+    /*
+     * Supplimentary minor adjustments.  Without compiler support, there are
+     * no thunks.
+     */
+    if ( !IS_ENABLED(CONFIG_INDIRECT_THUNK) )
+        thunk = THUNK_NONE;
+
+    /*
+     * If there are still no thunk preferences, the compiled default is
+     * actually retpoline, and it is better than nothing.
+     */
+    if ( thunk == THUNK_DEFAULT )
+        thunk = THUNK_RETPOLINE;
+
+    print_details(thunk);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
new file mode 100644
index 0000000..d0b44f6
--- /dev/null
+++ b/xen/include/asm-x86/spec_ctrl.h
@@ -0,0 +1,35 @@
+/******************************************************************************
+ * include/asm-x86/spec_ctrl.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2017 Citrix Systems Ltd.
+ */
+
+#ifndef __X86_SPEC_CTRL_H__
+#define __X86_SPEC_CTRL_H__
+
+void init_speculation_mitigations(void);
+
+#endif /* !__X86_SPEC_CTRL_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 13/26] x86/amd: Try to set lfence as being Dispatch Serialising
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (11 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 12/26] x86/boot: Report details of speculative mitigations Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  9:32   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 14/26] x86: Introduce alternative indirect thunks Andrew Cooper
                   ` (12 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

This property is required for the AMD's recommended mitigation for Branch
Target Injection, but Xen needs to cope with being unable to detect or modify
the MSR.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v4:
 * New
v5:
 * Use mnemonics.
---
 xen/arch/x86/cpu/amd.c            | 35 ++++++++++++++++++++++++++++++++++-
 xen/include/asm-x86/cpufeature.h  |  1 +
 xen/include/asm-x86/cpufeatures.h |  1 +
 xen/include/asm-x86/msr-index.h   |  1 +
 4 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index 5f36ac7..db78b50 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -558,8 +558,41 @@ static void init_amd(struct cpuinfo_x86 *c)
 			wrmsr_amd_safe(0xc001100d, l, h & ~1);
 	}
 
+	/*
+	 * Attempt to set lfence to be Dispatch Serialising.  This MSR almost
+	 * certainly isn't virtualised (and Xen at least will leak the real
+	 * value in but silently discard writes), as well as being per-core
+	 * rather than per-thread, so do a full safe read/write/readback cycle
+	 * in the worst case.
+	 */
+	if (c->x86 == 0x0f || c->x86 == 0x11)
+		/* Always dispatch serialising on this hardare. */
+		__set_bit(X86_FEATURE_LFENCE_DISPATCH, c->x86_capability);
+	else if (c->x86 == 0x10 || c->x86 >= 0x12) {
+		if (rdmsr_safe(MSR_AMD64_DE_CFG, value))
+			/* Unable to read.  Assume the safer default. */
+			__clear_bit(X86_FEATURE_LFENCE_DISPATCH,
+				    c->x86_capability);
+		else if (value & AMD64_DE_CFG_LFENCE_SERIALISE)
+			/* Already dispatch serialising. */
+			__set_bit(X86_FEATURE_LFENCE_DISPATCH,
+				  c->x86_capability);
+		else if (wrmsr_safe(MSR_AMD64_DE_CFG,
+				    value | AMD64_DE_CFG_LFENCE_SERIALISE) ||
+			 rdmsr_safe(MSR_AMD64_DE_CFG, value) ||
+			 !(value & AMD64_DE_CFG_LFENCE_SERIALISE))
+			/* Attempt to set failed.  Assume the safer default */
+			__clear_bit(X86_FEATURE_LFENCE_DISPATCH,
+				    c->x86_capability);
+		else
+			/* Successfully enabled! */
+			__set_bit(X86_FEATURE_LFENCE_DISPATCH,
+				  c->x86_capability);
+	}
+
 	/* MFENCE stops RDTSC speculation */
-	__set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability);
+	if (!cpu_has_lfence_dispatch)
+		__set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability);
 
 	switch(c->x86)
 	{
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index 84cc51d..adc333f 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -104,6 +104,7 @@
 #define cpu_has_arch_perfmon    boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
 #define cpu_has_cpuid_faulting  boot_cpu_has(X86_FEATURE_CPUID_FAULTING)
 #define cpu_has_aperfmperf      boot_cpu_has(X86_FEATURE_APERFMPERF)
+#define cpu_has_lfence_dispatch boot_cpu_has(X86_FEATURE_LFENCE_DISPATCH)
 
 enum _cache_type {
     CACHE_TYPE_NULL = 0,
diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h
index bc98227..58b37d6 100644
--- a/xen/include/asm-x86/cpufeatures.h
+++ b/xen/include/asm-x86/cpufeatures.h
@@ -22,3 +22,4 @@ XEN_CPUFEATURE(APERFMPERF,      (FSCAPINTS+0)*32+ 8) /* APERFMPERF */
 XEN_CPUFEATURE(MFENCE_RDTSC,    (FSCAPINTS+0)*32+ 9) /* MFENCE synchronizes RDTSC */
 XEN_CPUFEATURE(XEN_SMEP,        (FSCAPINTS+0)*32+10) /* SMEP gets used by Xen itself */
 XEN_CPUFEATURE(XEN_SMAP,        (FSCAPINTS+0)*32+11) /* SMAP gets used by Xen itself */
+XEN_CPUFEATURE(LFENCE_DISPATCH, (FSCAPINTS+0)*32+12) /* lfence set as Dispatch Serialising */
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index a834f3b..56f5359 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -207,6 +207,7 @@
 #define MSR_AMD64_IC_CFG		0xc0011021
 #define MSR_AMD64_DC_CFG		0xc0011022
 #define MSR_AMD64_DE_CFG		0xc0011029
+#define AMD64_DE_CFG_LFENCE_SERIALISE	(_AC(1, ULL) << 1)
 
 #define MSR_AMD64_DR0_ADDRESS_MASK	0xc0011027
 #define MSR_AMD64_DR1_ADDRESS_MASK	0xc0011019
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 14/26] x86: Introduce alternative indirect thunks
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (12 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 13/26] x86/amd: Try to set lfence as being Dispatch Serialising Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  9:40   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls Andrew Cooper
                   ` (11 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Depending on hardware and microcode availability, we will want to replace
IND_THUNK_REPOLINE with other implementations.

For AMD hardware, choose IND_THUNK_LFENCE in preference to retpoline if lfence
is known to be (or was successfully made) dispatch serialising.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v4:
 * New
v5:
 * Introduce a command line option
---
 docs/misc/xen-command-line.markdown | 14 +++++++
 xen/arch/x86/indirect_thunk.S       | 13 ++++++-
 xen/arch/x86/spec_ctrl.c            | 73 ++++++++++++++++++++++++++++++++++++-
 xen/include/asm-x86/cpufeatures.h   |  2 +
 4 files changed, 99 insertions(+), 3 deletions(-)

diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index 781110d..c9dbfbb 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -245,6 +245,20 @@ and not running softirqs. Reduce this if softirqs are not being run frequently
 enough. Setting this to a high value may cause boot failure, particularly if
 the NMI watchdog is also enabled.
 
+### bti (x86)
+> `= List of [ thunk=retpoline|lfence|plain ]`
+
+Branch Target Injection controls.  By default, Xen will pick the most
+appropriate BTI mitigations based on compiled in support, loaded microcode,
+and hardware details.
+
+**WARNING: Any use of this option inhibits all heristcs.  Use with extreme care.**
+
+If Xen was compiled with INDIRECT_THUNK support, `thunk=` can be used to
+select which of the thunks gets patched into the `__x86.indirect_thunk.%reg`
+locations.  The default thunk is `retpoline`, with the alternatives being
+`plain` (a `jmp *%reg` gadget), and `lfence` (an `lfence; jmp *%reg` gadget).
+
 ### xenheap\_megabytes (arm32)
 > `= <size>`
 
diff --git a/xen/arch/x86/indirect_thunk.S b/xen/arch/x86/indirect_thunk.S
index 4fef1c8..542974a 100644
--- a/xen/arch/x86/indirect_thunk.S
+++ b/xen/arch/x86/indirect_thunk.S
@@ -10,6 +10,15 @@
         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
@@ -18,7 +27,9 @@
         .section .text.__x86.indirect_thunk.\name, "ax", @progbits
 
 ENTRY(__x86.indirect_thunk.\name)
-        IND_THUNK_RETPOLINE \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
 .endm
 
 /* Instantiate GEN_INDIRECT_THUNK for each register except %rsp. */
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index ffee909..8301648 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -16,6 +16,7 @@
  *
  * Copyright (c) 2017 Citrix Systems Ltd.
  */
+#include <xen/errno.h>
 #include <xen/init.h>
 #include <xen/lib.h>
 
@@ -27,7 +28,42 @@ enum ind_thunk {
     THUNK_NONE,    /* Missing compiler support for thunks. */
 
     THUNK_RETPOLINE,
-};
+    THUNK_LFENCE,
+    THUNK_JMP,
+} opt_thunk __initdata = THUNK_DEFAULT;
+
+static int __init parse_bti(const char *s)
+{
+    const char *ss;
+    int rc = 0;
+
+    do {
+        ss = strchr(s, ',');
+        if ( !ss )
+            ss = strchr(s, '\0');
+
+        if ( !strncmp(s, "thunk=", 6) )
+        {
+            s += 6;
+
+            if ( !strncmp(s, "retpoline", ss - s) )
+                opt_thunk = THUNK_RETPOLINE;
+            else if ( !strncmp(s, "lfence", ss - s) )
+                opt_thunk = THUNK_LFENCE;
+            else if ( !strncmp(s, "jmp", ss - s) )
+                opt_thunk = THUNK_JMP;
+            else
+                rc = -EINVAL;
+        }
+        else
+            rc = -EINVAL;
+
+        s = ss + 1;
+    } while ( *ss );
+
+    return rc;
+}
+custom_param("bti", parse_bti);
 
 static void __init print_details(enum ind_thunk thunk)
 {
@@ -40,7 +76,9 @@ static void __init print_details(enum ind_thunk thunk)
     printk(XENLOG_INFO
            "BTI mitigations: Thunk %s\n",
            thunk == THUNK_NONE      ? "N/A" :
-           thunk == THUNK_RETPOLINE ? "RETPOLINE" : "?");
+           thunk == THUNK_RETPOLINE ? "RETPOLINE" :
+           thunk == THUNK_LFENCE    ? "LFENCE" :
+           thunk == THUNK_JMP       ? "JMP" : "?");
 }
 
 void __init init_speculation_mitigations(void)
@@ -48,6 +86,31 @@ void __init init_speculation_mitigations(void)
     enum ind_thunk thunk = THUNK_DEFAULT;
 
     /*
+     * Has the user specified any custom BTI mitigations?  If so, follow their
+     * instructions exactly and disable all heuristics.
+     */
+    if ( opt_thunk != THUNK_DEFAULT )
+    {
+        thunk = opt_thunk;
+    }
+    else
+    {
+        /*
+         * Evaluate the safest Branch Target Injection mitigations to use.
+         * First, begin with compiler-aided mitigations.
+         */
+        if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) )
+        {
+            /*
+             * AMD's recommended mitigation is to set lfence as being dispatch
+             * serialising, and to use IND_THUNK_LFENCE.
+             */
+            if ( cpu_has_lfence_dispatch )
+                thunk = THUNK_LFENCE;
+        }
+    }
+
+    /*
      * Supplimentary minor adjustments.  Without compiler support, there are
      * no thunks.
      */
@@ -61,6 +124,12 @@ void __init init_speculation_mitigations(void)
     if ( thunk == THUNK_DEFAULT )
         thunk = THUNK_RETPOLINE;
 
+    /* Apply the chosen settings. */
+    if ( thunk == THUNK_LFENCE )
+        setup_force_cpu_cap(X86_FEATURE_IND_THUNK_LFENCE);
+    else if ( thunk == THUNK_JMP )
+        setup_force_cpu_cap(X86_FEATURE_IND_THUNK_JMP);
+
     print_details(thunk);
 }
 
diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h
index 58b37d6..ba1771b 100644
--- a/xen/include/asm-x86/cpufeatures.h
+++ b/xen/include/asm-x86/cpufeatures.h
@@ -23,3 +23,5 @@ XEN_CPUFEATURE(MFENCE_RDTSC,    (FSCAPINTS+0)*32+ 9) /* MFENCE synchronizes RDTS
 XEN_CPUFEATURE(XEN_SMEP,        (FSCAPINTS+0)*32+10) /* SMEP gets used by Xen itself */
 XEN_CPUFEATURE(XEN_SMAP,        (FSCAPINTS+0)*32+11) /* SMAP gets used by Xen itself */
 XEN_CPUFEATURE(LFENCE_DISPATCH, (FSCAPINTS+0)*32+12) /* lfence set as Dispatch Serialising */
+XEN_CPUFEATURE(IND_THUNK_LFENCE,(FSCAPINTS+0)*32+13) /* Use IND_THUNK_LFENCE */
+XEN_CPUFEATURE(IND_THUNK_JMP,   (FSCAPINTS+0)*32+14) /* Use IND_THUNK_JMP */
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (13 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 14/26] x86: Introduce alternative indirect thunks Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  1:14   ` Doug Goldstein
                     ` (2 more replies)
  2018-01-04  0:15 ` [PATCH v6.5 16/26] x86/cmdline: Introduce a command line option to disable IBRS/IBPB, STIBP and IBPB Andrew Cooper
                   ` (10 subsequent siblings)
  25 siblings, 3 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Contemporary processors are gaining Indirect Branch Controls via microcode
updates.  Intel are introducing one bit to indicate IBRS and IBPB support, and
a second bit for STIBP.  AMD are introducing IPBP only, so enumerate it with a
separate bit.

Furthermore, depending on compiler and microcode availability, we may want to
run Xen with IBRS set, or clear.

To use these facilities, we synthesise separate IBRS and IBPB bits for
internal use.  A lot of infrastructure is required before these features are
safe to offer to guests.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v4:
 * Update for AMD, drop acks/reviews.
---
 tools/libxl/libxl_cpuid.c                   |  3 +++
 tools/misc/xen-cpuid.c                      | 12 ++++++++++--
 xen/arch/x86/spec_ctrl.c                    | 17 +++++++++++++++++
 xen/include/asm-x86/cpufeatures.h           |  3 +++
 xen/include/asm-x86/msr-index.h             | 11 +++++++++++
 xen/include/public/arch-x86/cpufeatureset.h |  3 +++
 xen/tools/gen-cpuid.py                      |  5 +++++
 7 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
index e692b61..81ba961 100644
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -202,6 +202,8 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str)
 
         {"avx512-4vnniw",0x00000007,  0, CPUID_REG_EDX,  2,  1},
         {"avx512-4fmaps",0x00000007,  0, CPUID_REG_EDX,  3,  1},
+        {"ibrsb",        0x00000007,  0, CPUID_REG_EDX, 26,  1},
+        {"stibp",        0x00000007,  0, CPUID_REG_EDX, 27,  1},
 
         {"lahfsahf",     0x80000001, NA, CPUID_REG_ECX,  0,  1},
         {"cmplegacy",    0x80000001, NA, CPUID_REG_ECX,  1,  1},
@@ -239,6 +241,7 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str)
 
         {"invtsc",       0x80000007, NA, CPUID_REG_EDX,  8,  1},
 
+        {"ibpb",         0x80000008, NA, CPUID_REG_EBX, 12,  1},
         {"nc",           0x80000008, NA, CPUID_REG_ECX,  0,  8},
         {"apicidsize",   0x80000008, NA, CPUID_REG_ECX, 12,  4},
 
diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c
index 0831f75..8c3dac0 100644
--- a/tools/misc/xen-cpuid.c
+++ b/tools/misc/xen-cpuid.c
@@ -149,7 +149,11 @@ static const char *str_e8b[32] =
 {
     [ 0] = "clzero",
 
-    [1 ... 31] = "REZ",
+    [1 ... 11] = "REZ",
+
+    [12] = "ibpb",
+
+    [13 ... 31] = "REZ",
 };
 
 static const char *str_7d0[32] =
@@ -158,7 +162,11 @@ static const char *str_7d0[32] =
 
     [ 2] = "avx512_4vnniw", [ 3] = "avx512_4fmaps",
 
-    [4 ... 31] = "REZ",
+    [4 ... 25] = "REZ",
+
+    [26] = "ibrsb",         [27] = "stibp",
+
+    [28 ... 31] = "REZ",
 };
 
 static struct {
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index 8301648..d9ace2d 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -67,8 +67,25 @@ custom_param("bti", parse_bti);
 
 static void __init print_details(enum ind_thunk thunk)
 {
+    unsigned int _7d0 = 0, e8b = 0, tmp;
+
+    /* Collect diagnostics about available mitigations. */
+    if ( boot_cpu_data.cpuid_level >= 7 )
+        cpuid_count(7, 0, &tmp, &tmp, &tmp, &_7d0);
+    if ( boot_cpu_data.extended_cpuid_level >= 0x80000008 )
+        cpuid(0x80000008, &tmp, &e8b, &tmp, &tmp);
+
     printk(XENLOG_DEBUG "Speculative mitigation facilities:\n");
 
+    /* Hardware features which pertain to speculative mitigations. */
+    if ( (_7d0 & (cpufeat_mask(X86_FEATURE_IBRSB) |
+                  cpufeat_mask(X86_FEATURE_STIBP))) ||
+         (e8b & cpufeat_mask(X86_FEATURE_IBPB)) )
+        printk(XENLOG_DEBUG "  Hardware features:%s%s%s\n",
+               (_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "",
+               (_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP"     : "",
+               (e8b  & cpufeat_mask(X86_FEATURE_IBPB))  ? " IBPB"      : "");
+
     /* Compiled-in support which pertains to BTI mitigations. */
     if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) )
         printk(XENLOG_DEBUG "  Compiled-in support: INDIRECT_THUNK\n");
diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h
index ba1771b..dd2388f 100644
--- a/xen/include/asm-x86/cpufeatures.h
+++ b/xen/include/asm-x86/cpufeatures.h
@@ -25,3 +25,6 @@ XEN_CPUFEATURE(XEN_SMAP,        (FSCAPINTS+0)*32+11) /* SMAP gets used by Xen it
 XEN_CPUFEATURE(LFENCE_DISPATCH, (FSCAPINTS+0)*32+12) /* lfence set as Dispatch Serialising */
 XEN_CPUFEATURE(IND_THUNK_LFENCE,(FSCAPINTS+0)*32+13) /* Use IND_THUNK_LFENCE */
 XEN_CPUFEATURE(IND_THUNK_JMP,   (FSCAPINTS+0)*32+14) /* Use IND_THUNK_JMP */
+XEN_CPUFEATURE(XEN_IBPB,        (FSCAPINTS+0)*32+15) /* IBRSB || IBPB */
+XEN_CPUFEATURE(XEN_IBRS_SET,    (FSCAPINTS+0)*32+16) /* IBRSB && IRBS set in Xen */
+XEN_CPUFEATURE(XEN_IBRS_CLEAR,  (FSCAPINTS+0)*32+17) /* IBRSB && IBRS clear in Xen */
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index 56f5359..3a73013 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -31,6 +31,17 @@
 #define EFER_LMSLE		(1<<_EFER_LMSLE)
 #define EFER_FFXSE		(1<<_EFER_FFXSE)
 
+/* Speculation Controls. */
+#define MSR_SPEC_CTRL			0x00000048
+#define _SPEC_CTRL_IBRS			0
+#define SPEC_CTRL_IBRS			(_AC(1, ULL) << _SPEC_CTRL_IBRS)
+#define _SPEC_CTRL_STIBP		1
+#define SPEC_CTRL_STIBP			(_AC(1, ULL) << _SPEC_CTRL_STIBP)
+
+#define MSR_PRED_CMD			0x00000049
+#define _PRED_CMD_IBPB			0
+#define PRED_CMD_IBPB			(_AC(1, ULL) << _PRED_CMD_IBPB)
+
 /* Intel MSRs. Some also available on other CPUs */
 #define MSR_IA32_PERFCTR0		0x000000c1
 #define MSR_IA32_A_PERFCTR0		0x000004c1
diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h
index be6da8e..e148755 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -237,10 +237,13 @@ XEN_CPUFEATURE(EFRO,          7*32+10) /*   APERF/MPERF Read Only interface */
 
 /* AMD-defined CPU features, CPUID level 0x80000008.ebx, word 8 */
 XEN_CPUFEATURE(CLZERO,        8*32+ 0) /*A  CLZERO instruction */
+XEN_CPUFEATURE(IBPB,          8*32+12) /*   IBPB support only (no IBRS, used by AMD) */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0.edx, word 9 */
 XEN_CPUFEATURE(AVX512_4VNNIW, 9*32+ 2) /*A  AVX512 Neural Network Instructions */
 XEN_CPUFEATURE(AVX512_4FMAPS, 9*32+ 3) /*A  AVX512 Multiply Accumulation Single Precision */
+XEN_CPUFEATURE(IBRSB,         9*32+26) /*   IBRS and IBPB support (used by Intel) */
+XEN_CPUFEATURE(STIBP,         9*32+27) /*   STIBP */
 
 #endif /* XEN_CPUFEATURE */
 
diff --git a/xen/tools/gen-cpuid.py b/xen/tools/gen-cpuid.py
index 9ec4486..613b909 100755
--- a/xen/tools/gen-cpuid.py
+++ b/xen/tools/gen-cpuid.py
@@ -256,6 +256,11 @@ def crunch_numbers(state):
         AVX512F: [AVX512DQ, AVX512IFMA, AVX512PF, AVX512ER, AVX512CD,
                   AVX512BW, AVX512VL, AVX512VBMI, AVX512_4VNNIW,
                   AVX512_4FMAPS, AVX512_VPOPCNTDQ],
+
+        # Single Thread Indirect Branch Predictors enumerates a new bit in the
+        # MSR enumerated by Indirect Branch Restricted Speculation/Indirect
+        # Branch Prediction Barrier enumeration.
+        IBRSB: [STIBP],
     }
 
     deep_features = tuple(sorted(deps.keys()))
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 16/26] x86/cmdline: Introduce a command line option to disable IBRS/IBPB, STIBP and IBPB
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (14 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  9:43   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 17/26] x86/msr: Emulation of MSR_{SPEC_CTRL, PRED_CMD} for guests Andrew Cooper
                   ` (9 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

Instead of gaining yet another top level boolean, introduce a more generic
cpuid= option.  Also introduce a helper function to parse a generic boolean
value.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>

v3:
 * New
v4:
 * Rename "xen-cpuid" to "cpuid"
 * Adjust comment in parse_boolean()
---
 docs/misc/xen-command-line.markdown | 12 ++++++++++++
 xen/arch/x86/cpuid.c                | 35 +++++++++++++++++++++++++++++++++++
 xen/common/kernel.c                 | 23 +++++++++++++++++++++++
 xen/include/xen/lib.h               |  7 +++++++
 4 files changed, 77 insertions(+)

diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index c9dbfbb..19e12ac 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -469,6 +469,18 @@ choice of `dom0-kernel` is deprecated and not supported by all Dom0 kernels.
   respectively.
 * `verbose` option can be included as a string or also as `verbose=<integer>`
 
+### cpuid (x86)
+> `= List of comma separated booleans`
+
+This option allows for fine tuning of the facilities Xen will use, after
+accounting for hardware capabilities as enumerated via CPUID.
+
+Currently accepted:
+
+The Speculation Control hardware features `ibrsb`, `stibp`, `ibpb` are used by
+default if avaiable.  They can be ignored, e.g. `no-ibrsb`, at which point Xen
+won't use them itself, and won't offer them to guests.
+
 ### cpuid\_mask\_cpu (AMD only)
 > `= fam_0f_rev_c | fam_0f_rev_d | fam_0f_rev_e | fam_0f_rev_f | fam_0f_rev_g | fam_10_rev_b | fam_10_rev_c | fam_11_rev_b`
 
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 5ee82d3..2ef71d2 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -18,6 +18,41 @@ static const uint32_t hvm_shadow_featuremask[] = INIT_HVM_SHADOW_FEATURES;
 static const uint32_t hvm_hap_featuremask[] = INIT_HVM_HAP_FEATURES;
 static const uint32_t deep_features[] = INIT_DEEP_FEATURES;
 
+static int __init parse_xen_cpuid(const char *s)
+{
+    const char *ss;
+    int val, rc = 0;
+
+    do {
+        ss = strchr(s, ',');
+        if ( !ss )
+            ss = strchr(s, '\0');
+
+        if ( (val = parse_boolean("ibpb", s, ss)) >= 0 )
+        {
+            if ( !val )
+                setup_clear_cpu_cap(X86_FEATURE_IBPB);
+        }
+        else if ( (val = parse_boolean("ibrsb", s, ss)) >= 0 )
+        {
+            if ( !val )
+                setup_clear_cpu_cap(X86_FEATURE_IBRSB);
+        }
+        else if ( (val = parse_boolean("stibp", s, ss)) >= 0 )
+        {
+            if ( !val )
+                setup_clear_cpu_cap(X86_FEATURE_STIBP);
+        }
+        else
+            rc = -EINVAL;
+
+        s = ss + 1;
+    } while ( *ss );
+
+    return rc;
+}
+custom_param("cpuid", parse_xen_cpuid);
+
 #define EMPTY_LEAF ((struct cpuid_leaf){})
 static void zero_leaves(struct cpuid_leaf *l,
                         unsigned int first, unsigned int last)
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index 8d137c5..19f9bad 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -244,6 +244,29 @@ int parse_bool(const char *s, const char *e)
     return -1;
 }
 
+int parse_boolean(const char *name, const char *s, const char *e)
+{
+    size_t slen, nlen;
+    int val = !!strncmp(s, "no-", 3);
+
+    if ( !val )
+        s += 3;
+
+    slen = e ? ({ ASSERT(e >= s); e - s; }) : strlen(s);
+    nlen = strlen(name);
+
+    /* Does s now start with name? */
+    if ( slen < nlen || strncmp(s, name, nlen) )
+        return -1;
+
+    switch ( s[nlen] )
+    {
+    case '\0': return val;
+    case '=':  return parse_bool(&s[nlen + 1], e);
+    default:   return -1;
+    }
+}
+
 unsigned int tainted;
 
 /**
diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h
index ed00ae1..1d97713 100644
--- a/xen/include/xen/lib.h
+++ b/xen/include/xen/lib.h
@@ -74,6 +74,13 @@ void cmdline_parse(const char *cmdline);
 int runtime_parse(const char *line);
 int parse_bool(const char *s, const char *e);
 
+/**
+ * Given a specific name, parses a string of the form:
+ *   [no-]$NAME[=...]
+ * returning 0 or 1 for a recognised boolean, or -1 for an error.
+ */
+int parse_boolean(const char *name, const char *s, const char *e);
+
 /*#define DEBUG_TRACE_DUMP*/
 #ifdef DEBUG_TRACE_DUMP
 extern void debugtrace_dump(void);
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 17/26] x86/msr: Emulation of MSR_{SPEC_CTRL, PRED_CMD} for guests
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (15 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 16/26] x86/cmdline: Introduce a command line option to disable IBRS/IBPB, STIBP and IBPB Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 18/26] x86/migrate: Move MSR_SPEC_CTRL on migrate Andrew Cooper
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
v3:
 * Brackets around && (.. & ..) operation
 * Extend host to uint32_t for the benefit of the asm code.
v4:
 * Extend MSR_PRED_CMD availability logic for AMD.
---
 xen/arch/x86/msr.c        | 35 +++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/msr.h | 12 ++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c
index 31983ed..02a7b49 100644
--- a/xen/arch/x86/msr.c
+++ b/xen/arch/x86/msr.c
@@ -119,11 +119,22 @@ int init_vcpu_msr_policy(struct vcpu *v)
 
 int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
 {
+    const struct cpuid_policy *cp = v->domain->arch.cpuid;
     const struct msr_domain_policy *dp = v->domain->arch.msr;
     const struct msr_vcpu_policy *vp = v->arch.msr;
 
     switch ( msr )
     {
+    case MSR_PRED_CMD:
+        /* Write-only */
+        goto gp_fault;
+
+    case MSR_SPEC_CTRL:
+        if ( !cp->feat.ibrsb )
+            goto gp_fault;
+        *val = vp->spec_ctrl.guest;
+        break;
+
     case MSR_INTEL_PLATFORM_INFO:
         if ( !dp->plaform_info.available )
             goto gp_fault;
@@ -152,14 +163,38 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
 {
     const struct vcpu *curr = current;
     struct domain *d = v->domain;
+    const struct cpuid_policy *cp = d->arch.cpuid;
     struct msr_domain_policy *dp = d->arch.msr;
     struct msr_vcpu_policy *vp = v->arch.msr;
 
     switch ( msr )
     {
     case MSR_INTEL_PLATFORM_INFO:
+        /* Read-only */
         goto gp_fault;
 
+    case MSR_SPEC_CTRL:
+        if ( !cp->feat.ibrsb )
+            goto gp_fault; /* MSR available? */
+        if ( val & ~(SPEC_CTRL_IBRS |
+                     (cp->feat.stibp ? SPEC_CTRL_STIBP : 0)) )
+            goto gp_fault; /* Rsvd bit set? */
+        vp->spec_ctrl.guest = val;
+        vp->spec_ctrl.host  = val;
+        break;
+
+    case MSR_PRED_CMD:
+        if ( !cp->feat.ibrsb && !cp->extd.ibpb )
+            goto gp_fault; /* MSR available? */
+
+        /*
+         * The only defined behaviour is when writing PRED_CMD_IBPB.  In
+         * practice, real hardware accepts any value without faulting.
+         */
+        if ( v == curr && (val & PRED_CMD_IBPB) )
+            wrmsrl(MSR_PRED_CMD, PRED_CMD_IBPB);
+        break;
+
     case MSR_INTEL_MISC_FEATURES_ENABLES:
     {
         uint64_t rsvd = ~0ull;
diff --git a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h
index 2fbed02..3d0012d 100644
--- a/xen/include/asm-x86/msr.h
+++ b/xen/include/asm-x86/msr.h
@@ -223,6 +223,18 @@ struct msr_domain_policy
 /* MSR policy object for per-vCPU MSRs */
 struct msr_vcpu_policy
 {
+    /* 0x00000048 - MSR_SPEC_CTRL */
+    struct {
+        /*
+         * Only the bottom two bits are defined, so no need to waste space
+         * with uint64_t at the moment.  We maintain the guests idea of the
+         * value it wrote, and a value to install into hardware (extended to
+         * uint32_t to simplify the asm) which might be different.
+         */
+        uint32_t host;
+        uint8_t guest;
+    } spec_ctrl;
+
     /* 0x00000140  MSR_INTEL_MISC_FEATURES_ENABLES */
     struct {
         bool available; /* This MSR is non-architectural */
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 18/26] x86/migrate: Move MSR_SPEC_CTRL on migrate
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (16 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 17/26] x86/msr: Emulation of MSR_{SPEC_CTRL, PRED_CMD} for guests Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD} Andrew Cooper
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/domctl.c  | 2 ++
 xen/arch/x86/hvm/hvm.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 5973d9f..72b4489 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -1290,6 +1290,7 @@ long arch_do_domctl(
         struct xen_domctl_vcpu_msr msr = {};
         struct vcpu *v;
         static const uint32_t msrs_to_send[] = {
+            MSR_SPEC_CTRL,
             MSR_INTEL_MISC_FEATURES_ENABLES,
         };
         uint32_t nr_msrs = ARRAY_SIZE(msrs_to_send);
@@ -1413,6 +1414,7 @@ long arch_do_domctl(
 
                 switch ( msr.index )
                 {
+                case MSR_SPEC_CTRL:
                 case MSR_INTEL_MISC_FEATURES_ENABLES:
                     if ( guest_wrmsr(v, msr.index, msr.value) != X86EMUL_OKAY )
                         break;
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 6a1c752..e4d22d5 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -1323,6 +1323,7 @@ static int hvm_load_cpu_xsave_states(struct domain *d, hvm_domain_context_t *h)
 
 #define HVM_CPU_MSR_SIZE(cnt) offsetof(struct hvm_msr, msr[cnt])
 static const uint32_t msrs_to_send[] = {
+    MSR_SPEC_CTRL,
     MSR_INTEL_MISC_FEATURES_ENABLES,
 };
 static unsigned int __read_mostly msr_count_max = ARRAY_SIZE(msrs_to_send);
@@ -1458,6 +1459,7 @@ static int hvm_load_cpu_msrs(struct domain *d, hvm_domain_context_t *h)
         {
             int rc;
 
+        case MSR_SPEC_CTRL:
         case MSR_INTEL_MISC_FEATURES_ENABLES:
             rc = guest_wrmsr(v, ctxt->msr[i].index, ctxt->msr[i].val);
 
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD}
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (17 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 18/26] x86/migrate: Move MSR_SPEC_CTRL on migrate Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  9:52   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 20/26] x86: Protect unaware domains from meddling hyperthreads Andrew Cooper
                   ` (6 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

For performance reasons, HVM guests should have direct access to these MSRs
when possible.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v4:
 * Redo almost from scratch to support AMD
v6:
 * Allow direct access to PRED_CMD for IBPB
---
 xen/arch/x86/domctl.c      | 19 +++++++++++++++++++
 xen/arch/x86/hvm/svm/svm.c |  5 +++++
 xen/arch/x86/hvm/vmx/vmx.c | 18 ++++++++++++++++++
 xen/arch/x86/msr.c         |  3 ++-
 xen/include/asm-x86/msr.h  |  5 ++++-
 5 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 72b4489..81fbeaa 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -53,6 +53,7 @@ static int update_domain_cpuid_info(struct domain *d,
     struct cpuid_policy *p = d->arch.cpuid;
     const struct cpuid_leaf leaf = { ctl->eax, ctl->ebx, ctl->ecx, ctl->edx };
     int old_vendor = p->x86_vendor;
+    unsigned int old_7d0 = p->feat.raw[0].d, old_e8b = p->extd.raw[8].b;
     bool call_policy_changed = false; /* Avoid for_each_vcpu() unnecessarily */
 
     /*
@@ -218,6 +219,14 @@ static int update_domain_cpuid_info(struct domain *d,
 
             d->arch.pv_domain.cpuidmasks->_7ab0 = mask;
         }
+
+        /*
+         * If the IBSRB/STIBP policy has changed, we need to recalculate the
+         * MSR interception bitmaps and STIBP protection default.
+         */
+        call_policy_changed = ((old_7d0 ^ p->feat.raw[0].d) &
+                               (cpufeat_mask(X86_FEATURE_IBRSB) |
+                                cpufeat_mask(X86_FEATURE_STIBP)));
         break;
 
     case 0xa:
@@ -292,6 +301,16 @@ static int update_domain_cpuid_info(struct domain *d,
             d->arch.pv_domain.cpuidmasks->e1cd = mask;
         }
         break;
+
+    case 0x80000008:
+        /*
+         * If the IBRB policy has changed, we need to recalculate the MSR
+         * interception bitmaps.
+         */
+        call_policy_changed = (is_hvm_domain(d) &&
+                               ((old_e8b ^ p->extd.raw[8].b) &
+                                (cpufeat_mask(X86_FEATURE_IBPB))));
+        break;
     }
 
     if ( call_policy_changed )
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index c48fdfa..ee47508 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -617,6 +617,7 @@ static void svm_cpuid_policy_changed(struct vcpu *v)
 {
     struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
     struct vmcb_struct *vmcb = arch_svm->vmcb;
+    const struct cpuid_policy *cp = v->domain->arch.cpuid;
     u32 bitmap = vmcb_get_exception_intercepts(vmcb);
 
     if ( opt_hvm_fep ||
@@ -626,6 +627,10 @@ static void svm_cpuid_policy_changed(struct vcpu *v)
         bitmap &= ~(1U << TRAP_invalid_op);
 
     vmcb_set_exception_intercepts(vmcb, bitmap);
+
+    /* Give access to MSR_PRED_CMD if the guest has been told about it. */
+    svm_intercept_msr(v, MSR_PRED_CMD,
+                      cp->extd.ibpb ? MSR_INTERCEPT_NONE : MSR_INTERCEPT_RW);
 }
 
 static void svm_sync_vmcb(struct vcpu *v)
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index e036303..8609de3 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -656,6 +656,8 @@ void vmx_update_exception_bitmap(struct vcpu *v)
 
 static void vmx_cpuid_policy_changed(struct vcpu *v)
 {
+    const struct cpuid_policy *cp = v->domain->arch.cpuid;
+
     if ( opt_hvm_fep ||
          (v->domain->arch.cpuid->x86_vendor != boot_cpu_data.x86_vendor) )
         v->arch.hvm_vmx.exception_bitmap |= (1U << TRAP_invalid_op);
@@ -665,6 +667,22 @@ static void vmx_cpuid_policy_changed(struct vcpu *v)
     vmx_vmcs_enter(v);
     vmx_update_exception_bitmap(v);
     vmx_vmcs_exit(v);
+
+    /*
+     * We can only pass though MSR_SPEC_CTRL if the guest knows about all bits
+     * in it.  Otherwise, Xen may be fixing up in the background.
+     */
+    v->arch.msr->spec_ctrl.direct_access = cp->feat.ibrsb && cp->feat.stibp;
+    if ( v->arch.msr->spec_ctrl.direct_access )
+        vmx_clear_msr_intercept(v, MSR_SPEC_CTRL, VMX_MSR_RW);
+    else
+        vmx_set_msr_intercept(v, MSR_SPEC_CTRL, VMX_MSR_RW);
+
+    /* MSR_PRED_CMD is safe to pass through if the guest knows about it. */
+    if ( cp->feat.ibrsb || cp->extd.ibpb )
+        vmx_clear_msr_intercept(v, MSR_PRED_CMD,  VMX_MSR_RW);
+    else
+        vmx_set_msr_intercept(v, MSR_PRED_CMD,  VMX_MSR_RW);
 }
 
 int vmx_guest_x86_mode(struct vcpu *v)
diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c
index 02a7b49..697cc6e 100644
--- a/xen/arch/x86/msr.c
+++ b/xen/arch/x86/msr.c
@@ -132,7 +132,8 @@ int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
     case MSR_SPEC_CTRL:
         if ( !cp->feat.ibrsb )
             goto gp_fault;
-        *val = vp->spec_ctrl.guest;
+        *val = (vp->spec_ctrl.direct_access
+                ? vp->spec_ctrl.host : vp->spec_ctrl.guest);
         break;
 
     case MSR_INTEL_PLATFORM_INFO:
diff --git a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h
index 3d0012d..007e966 100644
--- a/xen/include/asm-x86/msr.h
+++ b/xen/include/asm-x86/msr.h
@@ -229,10 +229,13 @@ struct msr_vcpu_policy
          * Only the bottom two bits are defined, so no need to waste space
          * with uint64_t at the moment.  We maintain the guests idea of the
          * value it wrote, and a value to install into hardware (extended to
-         * uint32_t to simplify the asm) which might be different.
+         * uint32_t to simplify the asm) which might be different.  HVM guests
+         * might be given direct access to the MSRs, at which point the
+         * 'guest' value becomes stale.
          */
         uint32_t host;
         uint8_t guest;
+        bool direct_access;
     } spec_ctrl;
 
     /* 0x00000140  MSR_INTEL_MISC_FEATURES_ENABLES */
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 20/26] x86: Protect unaware domains from meddling hyperthreads
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (18 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD} Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04  9:59   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 21/26] x86/entry: Use MSR_SPEC_CTRL at each entry/exit point Andrew Cooper
                   ` (5 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v3:
 * Spelling corrections
v4:
 * Rebase over AMD changes
v6:
 * Fix cpuid_policy_updated() to not corrupt vp->spec_ctrl.host on migrate, or
   on older versions of Xen where feature flags start as 0 rather than the
   domain maximum.
---
 xen/arch/x86/domain.c            | 19 +++++++++++++++++++
 xen/arch/x86/msr.c               | 15 ++++++++++++++-
 xen/include/asm-x86/cpufeature.h |  3 +++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index d383489..698346e 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -2027,6 +2027,25 @@ int domain_relinquish_resources(struct domain *d)
  */
 void cpuid_policy_updated(struct vcpu *v)
 {
+    const struct cpuid_policy *cp = v->domain->arch.cpuid;
+    struct msr_vcpu_policy *vp = v->arch.msr;
+
+    /*
+     * For guests which know about IBRS but are not told about STIBP running
+     * on hardware supporting hyperthreading, the guest doesn't know to
+     * protect itself fully.  (Such a guest won't be permitted direct access
+     * to the MSR.)  Have Xen fill in the gaps, so an unaware guest can't be
+     * interfered with by a meddling guest on an adjacent hyperthread.
+     */
+    if ( cp->feat.ibrsb )
+    {
+        if ( !cp->feat.stibp && cpu_has_stibp &&
+             !(vp->spec_ctrl.guest & (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP)) )
+            vp->spec_ctrl.host = SPEC_CTRL_STIBP;
+        else
+            vp->spec_ctrl.host = vp->spec_ctrl.guest;
+    }
+
     if ( is_hvm_vcpu(v) )
         hvm_cpuid_policy_changed(v);
 }
diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c
index 697cc6e..2d99c64 100644
--- a/xen/arch/x86/msr.c
+++ b/xen/arch/x86/msr.c
@@ -181,7 +181,20 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
                      (cp->feat.stibp ? SPEC_CTRL_STIBP : 0)) )
             goto gp_fault; /* Rsvd bit set? */
         vp->spec_ctrl.guest = val;
-        vp->spec_ctrl.host  = val;
+
+        /*
+         * For guests which are not told about STIBP, running on hardware
+         * supporting hyperthreading, the guest doesn't know to protect itself
+         * fully.  (Such a guest won't be permitted direct access to the MSR.)
+         * When IBRS is not in force, have Xen fill in the gaps, so an unaware
+         * guest can't be interfered with by a meddling guest on an adjacent
+         * hyperthread.
+         */
+        if ( !cp->feat.stibp && cpu_has_stibp &&
+             !(val & (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP)) )
+            vp->spec_ctrl.host = SPEC_CTRL_STIBP;
+        else
+            vp->spec_ctrl.host = val;
         break;
 
     case MSR_PRED_CMD:
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index adc333f..988a834 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -100,6 +100,9 @@
 /* CPUID level 0x80000007.edx */
 #define cpu_has_itsc            boot_cpu_has(X86_FEATURE_ITSC)
 
+/* CPUID level 0x00000007:0.edx */
+#define cpu_has_stibp           boot_cpu_has(X86_FEATURE_STIBP)
+
 /* Synthesized. */
 #define cpu_has_arch_perfmon    boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
 #define cpu_has_cpuid_faulting  boot_cpu_has(X86_FEATURE_CPUID_FAULTING)
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 21/26] x86/entry: Use MSR_SPEC_CTRL at each entry/exit point
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (19 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 20/26] x86: Protect unaware domains from meddling hyperthreads Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04 10:14   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 22/26] x86/boot: Calculate the most appropriate BTI mitigation to use Andrew Cooper
                   ` (4 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Set or clear IBRS in Xen context, and appropriate guest values in guest
context.  See the documentation in asm-x86/spec_ctrl_asm.h for details.

Two semi-unrelated bugfixes are that various asm_defn.h macros have a hidden
dependency on PAGE_SIZE, which results in an assembler error if used in a
.macro definition.  Secondly, _ASM_MK_NOP() needs a separator at the end,
rather than relying on its calling context for separation.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v3:
 * Basically rewritten from scratch
v4:
 * Use STACK* macrocs
 * Drop semicolons
 * Fix several offset bugs
 * Introduce init_shadow_spec_ctrl_state() rather than opencoding it for the
   BSP and APs
 * Rebase over AMD changes
---
 xen/arch/x86/hvm/svm/entry.S        |   8 +-
 xen/arch/x86/hvm/vmx/entry.S        |  11 ++
 xen/arch/x86/setup.c                |   1 +
 xen/arch/x86/smpboot.c              |   2 +
 xen/arch/x86/x86_64/asm-offsets.c   |   6 +
 xen/arch/x86/x86_64/compat/entry.S  |  12 ++
 xen/arch/x86/x86_64/entry.S         |  33 ++++++
 xen/include/asm-x86/asm_defns.h     |   3 +
 xen/include/asm-x86/current.h       |   6 +
 xen/include/asm-x86/nops.h          |   8 +-
 xen/include/asm-x86/spec_ctrl.h     |   9 ++
 xen/include/asm-x86/spec_ctrl_asm.h | 230 ++++++++++++++++++++++++++++++++++++
 12 files changed, 327 insertions(+), 2 deletions(-)
 create mode 100644 xen/include/asm-x86/spec_ctrl_asm.h

diff --git a/xen/arch/x86/hvm/svm/entry.S b/xen/arch/x86/hvm/svm/entry.S
index df86da0..fb1048b 100644
--- a/xen/arch/x86/hvm/svm/entry.S
+++ b/xen/arch/x86/hvm/svm/entry.S
@@ -79,6 +79,9 @@ UNLIKELY_END(svm_trace)
         or   $X86_EFLAGS_MBS,%rax
         mov  %rax,VMCB_rflags(%rcx)
 
+        /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */
+        SPEC_CTRL_EXIT_TO_GUEST /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */
+
         pop  %r15
         pop  %r14
         pop  %r13
@@ -101,8 +104,11 @@ UNLIKELY_END(svm_trace)
         SAVE_ALL
 
         GET_CURRENT(bx)
-        mov  VCPU_svm_vmcb(%rbx),%rcx
 
+        SPEC_CTRL_ENTRY_FROM_VMEXIT /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
+        mov  VCPU_svm_vmcb(%rbx),%rcx
         movb $0,VCPU_svm_vmcb_in_sync(%rbx)
         mov  VMCB_rax(%rcx),%rax
         mov  %rax,UREGS_rax(%rsp)
diff --git a/xen/arch/x86/hvm/vmx/entry.S b/xen/arch/x86/hvm/vmx/entry.S
index b2f98be..21e959f 100644
--- a/xen/arch/x86/hvm/vmx/entry.S
+++ b/xen/arch/x86/hvm/vmx/entry.S
@@ -38,6 +38,9 @@ ENTRY(vmx_asm_vmexit_handler)
         movb $1,VCPU_vmx_launched(%rbx)
         mov  %rax,VCPU_hvm_guest_cr2(%rbx)
 
+        SPEC_CTRL_ENTRY_FROM_VMEXIT /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
         mov  %rsp,%rdi
         call vmx_vmexit_handler
 
@@ -68,6 +71,10 @@ UNLIKELY_END(realmode)
         call vmx_vmenter_helper
         test %al, %al
         jz .Lvmx_vmentry_restart
+
+        /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */
+        SPEC_CTRL_EXIT_TO_GUEST /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */
+
         mov  VCPU_hvm_guest_cr2(%rbx),%rax
 
         pop  %r15
@@ -99,6 +106,10 @@ UNLIKELY_END(realmode)
 .Lvmx_vmentry_fail:
         sti
         SAVE_ALL
+
+        SPEC_CTRL_ENTRY_FROM_PV /* Req: %rsp=regs/cpuinfo Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
         call vmx_vmentry_failure
         BUG  /* vmx_vmentry_failure() shouldn't return. */
 
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 470427b..b2aa281 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -668,6 +668,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     set_processor_id(0);
     set_current(INVALID_VCPU); /* debug sanity. */
     idle_vcpu[0] = current;
+    init_shadow_spec_ctrl_state();
 
     percpu_init_areas();
 
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 7b97ff8..a695d12 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -40,6 +40,7 @@
 #include <asm/flushtlb.h>
 #include <asm/msr.h>
 #include <asm/mtrr.h>
+#include <asm/spec_ctrl.h>
 #include <asm/time.h>
 #include <asm/tboot.h>
 #include <mach_apic.h>
@@ -308,6 +309,7 @@ void start_secondary(void *unused)
     set_current(idle_vcpu[cpu]);
     this_cpu(curr_vcpu) = idle_vcpu[cpu];
     rdmsrl(MSR_EFER, this_cpu(efer));
+    init_shadow_spec_ctrl_state();
 
     /*
      * Just as during early bootstrap, it is convenient here to disable
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
index e136af6..7d36185 100644
--- a/xen/arch/x86/x86_64/asm-offsets.c
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -88,6 +88,7 @@ void __dummy__(void)
     OFFSET(VCPU_kernel_ss, struct vcpu, arch.pv_vcpu.kernel_ss);
     OFFSET(VCPU_iopl, struct vcpu, arch.pv_vcpu.iopl);
     OFFSET(VCPU_guest_context_flags, struct vcpu, arch.vgc_flags);
+    OFFSET(VCPU_arch_msr, struct vcpu, arch.msr);
     OFFSET(VCPU_nmi_pending, struct vcpu, nmi_pending);
     OFFSET(VCPU_mce_pending, struct vcpu, mce_pending);
     OFFSET(VCPU_nmi_old_mask, struct vcpu, nmi_state.old_mask);
@@ -137,6 +138,8 @@ void __dummy__(void)
     OFFSET(CPUINFO_processor_id, struct cpu_info, processor_id);
     OFFSET(CPUINFO_current_vcpu, struct cpu_info, current_vcpu);
     OFFSET(CPUINFO_cr4, struct cpu_info, cr4);
+    OFFSET(CPUINFO_shadow_spec_ctrl, struct cpu_info, shadow_spec_ctrl);
+    OFFSET(CPUINFO_use_shadow_spec_ctrl, struct cpu_info, use_shadow_spec_ctrl);
     DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
     BLANK();
 
@@ -152,6 +155,9 @@ void __dummy__(void)
     OFFSET(TRAPBOUNCE_eip, struct trap_bounce, eip);
     BLANK();
 
+    OFFSET(VCPUMSR_spec_ctrl_host, struct msr_vcpu_policy, spec_ctrl.host);
+    BLANK();
+
 #ifdef CONFIG_PERF_COUNTERS
     DEFINE(ASM_PERFC_exceptions, PERFC_exceptions);
     BLANK();
diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
index 3fea54e..422c25d 100644
--- a/xen/arch/x86/x86_64/compat/entry.S
+++ b/xen/arch/x86/x86_64/compat/entry.S
@@ -18,6 +18,10 @@ ENTRY(entry_int82)
         pushq $0
         movl  $HYPERCALL_VECTOR, 4(%rsp)
         SAVE_ALL compat=1 /* DPL1 gate, restricted to 32bit PV guests only. */
+
+        SPEC_CTRL_ENTRY_FROM_PV /* Req: %rsp=regs/cpuinfo Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
         CR4_PV32_RESTORE
 
         GET_CURRENT(bx)
@@ -142,6 +146,10 @@ ENTRY(compat_restore_all_guest)
         .popsection
         or    $X86_EFLAGS_IF,%r11
         mov   %r11d,UREGS_eflags(%rsp)
+
+        /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */
+        SPEC_CTRL_EXIT_TO_GUEST /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */
+
         RESTORE_ALL adj=8 compat=1
 .Lft0:  iretq
         _ASM_PRE_EXTABLE(.Lft0, handle_exception)
@@ -199,6 +207,10 @@ ENTRY(cstar_enter)
         pushq $0
         movl  $TRAP_syscall, 4(%rsp)
         SAVE_ALL
+
+        SPEC_CTRL_ENTRY_FROM_PV /* Req: %rsp=regs/cpuinfo Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
         GET_CURRENT(bx)
         movq  VCPU_domain(%rbx),%rcx
         cmpb  $0,DOMAIN_is_32bit_pv(%rcx)
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index b49d62b..ba7c5e9 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -37,6 +37,10 @@ ENTRY(switch_to_kernel)
 /* %rbx: struct vcpu, interrupts disabled */
 restore_all_guest:
         ASSERT_INTERRUPTS_DISABLED
+
+        /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */
+        SPEC_CTRL_EXIT_TO_GUEST /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */
+
         RESTORE_ALL
         testw $TRAP_syscall,4(%rsp)
         jz    iret_exit_to_guest
@@ -71,6 +75,8 @@ iret_exit_to_guest:
         ALIGN
 /* No special register assumptions. */
 restore_all_xen:
+        /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */
+        SPEC_CTRL_EXIT_TO_XEN /* Req: nothing           Clob: acd */
         RESTORE_ALL adj=8
         iretq
 
@@ -100,6 +106,10 @@ ENTRY(lstar_enter)
         pushq $0
         movl  $TRAP_syscall, 4(%rsp)
         SAVE_ALL
+
+        SPEC_CTRL_ENTRY_FROM_PV /* Req: %rsp=regs/cpuinfo Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
         GET_CURRENT(bx)
         testb $TF_kernel_mode,VCPU_thread_flags(%rbx)
         jz    switch_to_kernel
@@ -192,6 +202,10 @@ GLOBAL(sysenter_eflags_saved)
         pushq $0
         movl  $TRAP_syscall, 4(%rsp)
         SAVE_ALL
+
+        SPEC_CTRL_ENTRY_FROM_PV /* Req: %rsp=regs/cpuinfo Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
         GET_CURRENT(bx)
         cmpb  $0,VCPU_sysenter_disables_events(%rbx)
         movq  VCPU_sysenter_addr(%rbx),%rax
@@ -228,6 +242,9 @@ ENTRY(int80_direct_trap)
         movl  $0x80, 4(%rsp)
         SAVE_ALL
 
+        SPEC_CTRL_ENTRY_FROM_PV /* Req: %rsp=regs/cpuinfo Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
         cmpb  $0,untrusted_msi(%rip)
 UNLIKELY_START(ne, msi_check)
         movl  $0x80,%edi
@@ -391,6 +408,10 @@ ENTRY(dom_crash_sync_extable)
 
 ENTRY(common_interrupt)
         SAVE_ALL CLAC
+
+        SPEC_CTRL_ENTRY_FROM_INTR /* Req: %rsp=regs         Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
         CR4_PV32_RESTORE
         movq %rsp,%rdi
         callq do_IRQ
@@ -411,6 +432,10 @@ ENTRY(page_fault)
 /* No special register assumptions. */
 GLOBAL(handle_exception)
         SAVE_ALL CLAC
+
+        SPEC_CTRL_ENTRY_FROM_INTR /* Req: %rsp=regs         Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
 handle_exception_saved:
         GET_CURRENT(bx)
         testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%rsp)
@@ -586,6 +611,10 @@ ENTRY(double_fault)
         movl  $TRAP_double_fault,4(%rsp)
         /* Set AC to reduce chance of further SMAP faults */
         SAVE_ALL STAC
+
+        SPEC_CTRL_ENTRY_FROM_INTR /* Req: %rsp=regs Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
         movq  %rsp,%rdi
         call  do_double_fault
         BUG   /* do_double_fault() shouldn't return. */
@@ -604,6 +633,10 @@ ENTRY(nmi)
         movl  $TRAP_nmi,4(%rsp)
 handle_ist_exception:
         SAVE_ALL CLAC
+
+        SPEC_CTRL_ENTRY_FROM_INTR /* Req: %rsp=regs Clob: acd */
+        /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
+
         CR4_PV32_RESTORE
         testb $3,UREGS_cs(%rsp)
         jz    1f
diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h
index 40b0250..bc10167 100644
--- a/xen/include/asm-x86/asm_defns.h
+++ b/xen/include/asm-x86/asm_defns.h
@@ -7,6 +7,7 @@
 #include <asm/asm-offsets.h>
 #endif
 #include <asm/bug.h>
+#include <asm/page.h>
 #include <asm/processor.h>
 #include <asm/percpu.h>
 #include <xen/stringify.h>
@@ -344,4 +345,6 @@ static always_inline void stac(void)
 #define REX64_PREFIX "rex64/"
 #endif
 
+#include <asm/spec_ctrl_asm.h>
+
 #endif /* __X86_ASM_DEFNS_H__ */
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index 8984992..749d7aa 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -41,6 +41,12 @@ struct cpu_info {
     struct vcpu *current_vcpu;
     unsigned long per_cpu_offset;
     unsigned long cr4;
+
+    /* See asm-x86/spec_ctrl_asm.h for usage. */
+    unsigned int shadow_spec_ctrl;
+    bool         use_shadow_spec_ctrl;
+
+    unsigned long __pad;
     /* get_stack_bottom() must be 16-byte aligned */
 };
 
diff --git a/xen/include/asm-x86/nops.h b/xen/include/asm-x86/nops.h
index 1a46b97..9e8f530 100644
--- a/xen/include/asm-x86/nops.h
+++ b/xen/include/asm-x86/nops.h
@@ -50,7 +50,7 @@
 #define P6_NOP9 0x66,0x0f,0x1f,0x84,0x00,0,0,0,0
 
 #ifdef __ASSEMBLY__
-#define _ASM_MK_NOP(x) .byte x
+#define _ASM_MK_NOP(x) .byte x;
 #else
 #define _ASM_MK_NOP(x) ".byte " __stringify(x) "\n"
 #endif
@@ -65,6 +65,12 @@
 #define ASM_NOP8 _ASM_MK_NOP(P6_NOP8)
 #define ASM_NOP9 _ASM_MK_NOP(P6_NOP9)
 
+#define ASM_NOP22 ASM_NOP8 ASM_NOP8 ASM_NOP6
+#define ASM_NOP26 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP2
+#define ASM_NOP32 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8
+#define ASM_NOP33 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP7 ASM_NOP2
+#define ASM_NOP39 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP7
+
 #define ASM_NOP_MAX 9
 
 #endif /* __X86_ASM_NOPS_H__ */
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
index d0b44f6..29a31a9 100644
--- a/xen/include/asm-x86/spec_ctrl.h
+++ b/xen/include/asm-x86/spec_ctrl.h
@@ -20,8 +20,17 @@
 #ifndef __X86_SPEC_CTRL_H__
 #define __X86_SPEC_CTRL_H__
 
+#include <asm/current.h>
+
 void init_speculation_mitigations(void);
 
+static inline void init_shadow_spec_ctrl_state(void)
+{
+    struct cpu_info *info = get_cpu_info();
+
+    info->shadow_spec_ctrl = info->use_shadow_spec_ctrl = 0;
+}
+
 #endif /* !__X86_SPEC_CTRL_H__ */
 
 /*
diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h
new file mode 100644
index 0000000..13e058c
--- /dev/null
+++ b/xen/include/asm-x86/spec_ctrl_asm.h
@@ -0,0 +1,230 @@
+/******************************************************************************
+ * include/asm-x86/spec_ctrl.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2017 Citrix Systems Ltd.
+ */
+
+#ifndef __X86_SPEC_CTRL_ASM_H__
+#define __X86_SPEC_CTRL_ASM_H__
+
+#ifdef __ASSEMBLY__
+#include <asm/msr.h>
+
+/*
+ * Saving and restoring MSR_SPEC_CTRL state is a little tricky.
+ *
+ * We want the guests choice of SPEC_CTRL while in guest context, and IBRS
+ * (set or clear, depending on the hardware) while running in Xen context.
+ * Therefore, a simplistic algorithm is:
+ *
+ *  - Set/clear IBRS on entry to Xen
+ *  - Set the guests' choice on exit to guest
+ *  - Leave SPEC_CTRL unchanged on exit to xen
+ *
+ * There are two complicating factors:
+ *  1) HVM guests can have direct access to the MSR, so it can change
+ *     behind Xen's back.
+ *  2) An NMI or MCE can interrupt at any point, including early in the entry
+ *     path, or late in the exit path after restoring the guest value.  This
+ *     will corrupt the guest value.
+ *
+ * Factor 1 is dealt with by relying on NMIs/MCEs being blocked immediately
+ * after VMEXIT.  The VMEXIT-specific code reads MSR_SPEC_CTRL and updates
+ * current before loading Xen's MSR_SPEC_CTRL setting.
+ *
+ * Factor 2 is harder.  We maintain a shadow_spec_ctrl value, and
+ * use_shadow_spec_ctrl boolean per cpu.  The synchronous use is:
+ *
+ *  1) Store guest value in shadow_spec_ctrl
+ *  2) Set use_shadow_spec_ctrl boolean
+ *  3) Load guest value into MSR_SPEC_CTRL
+ *  4) Exit to guest
+ *  5) Entry from guest
+ *  6) Clear use_shadow_spec_ctrl boolean
+ *
+ * The asynchronous use for interrupts/exceptions is:
+ *  -  Set/clear IBRS on entry to Xen
+ *  -  On exit to Xen, check use_shadow_spec_ctrl
+ *  -  If set, load shadow_spec_ctrl
+ *
+ * Therefore, an interrupt/exception which hits the synchronous path between
+ * steps 2 and 6 will restore the shadow value rather than leaving Xen's value
+ * loaded and corrupting the value used in guest context.
+ *
+ * The following ASM fragments implement this algorithm.  See their local
+ * comments for further details.
+ *  - SPEC_CTRL_ENTRY_FROM_VMEXIT
+ *  - SPEC_CTRL_ENTRY_FROM_PV
+ *  - SPEC_CTRL_ENTRY_FROM_INTR
+ *  - SPEC_CTRL_EXIT_TO_XEN
+ *  - SPEC_CTRL_EXIT_TO_GUEST
+ */
+
+.macro DO_SPEC_CTRL_ENTRY_FROM_VMEXIT ibrs_val:req
+/*
+ * Requires %rbx=current, %rsp=regs/cpuinfo
+ * Clobbers %rax, %rcx, %rdx
+ *
+ * The common case is that a guest has direct access to MSR_SPEC_CTRL, at
+ * which point we need to save the guest value before setting IBRS for Xen.
+ * Unilaterally saving the guest value is shorter and faster than checking.
+ */
+    mov $MSR_SPEC_CTRL, %ecx
+    rdmsr
+
+    /* Stash the value from hardware. */
+    mov VCPU_arch_msr(%rbx), %rdx
+    mov %al, VCPUMSR_spec_ctrl_host(%rdx)
+    xor %edx, %edx
+
+    /* Clear SPEC_CTRL shadowing *before* loading Xen's value. */
+    movb %dl, CPUINFO_use_shadow_spec_ctrl(%rsp)
+
+    /* Load Xen's indented value. */
+    mov $\ibrs_val, %eax
+    wrmsr
+.endm
+
+.macro DO_SPEC_CTRL_ENTRY maybexen:req ibrs_val:req
+/*
+ * Requires %rsp=regs (also cpuinfo if !maybexen)
+ * Clobbers %rax, %rcx, %rdx
+ *
+ * PV guests can't update MSR_SPEC_CTRL behind Xen's back, so no need to read
+ * it back.  Entries from guest context need to clear SPEC_CTRL shadowing,
+ * while entries from Xen must leave shadowing in its current state.
+ */
+    mov $MSR_SPEC_CTRL, %ecx
+
+    .if \maybexen
+        cmpl $__HYPERVISOR_CS, UREGS_cs(%rsp)
+        je .Lentry_from_xen\@
+    .endif
+
+    /*
+     * Clear SPEC_CTRL shadowing *before* loading Xen's value.  If entering
+     * from a possibly-xen context, %rsp doesn't necesserily alias the cpuinfo
+     * block so calculate the position directly.
+     */
+    .if \maybexen
+        GET_STACK_END(dx)
+        movb $0, STACK_CPUINFO_FIELD(use_shadow_spec_ctrl)(%rdx)
+    .else
+        movb $0, CPUINFO_use_shadow_spec_ctrl(%rsp)
+    .endif
+
+.Lentry_from_xen\@:
+    /* Load Xen's indented value. */
+    mov $\ibrs_val, %eax
+    xor %edx, %edx
+    wrmsr
+.endm
+
+.macro DO_SPEC_CTRL_EXIT_TO_XEN
+/*
+ * Requires nothing
+ * Clobbers %rax, %rcx, %rdx
+ *
+ * When returning to Xen context, look to see whether SPEC_CTRL shadowing is
+ * in effect, and reload the shadow value.  This covers race conditions which
+ * exist with an NMI/MCE/etc hitting late in the return-to-guest path.
+ */
+    GET_STACK_END(dx)
+    cmpb $0, STACK_CPUINFO_FIELD(use_shadow_spec_ctrl)(%rdx)
+    je .Lend_\@
+
+    mov STACK_CPUINFO_FIELD(shadow_spec_ctrl)(%rdx), %eax
+    mov $MSR_SPEC_CTRL, %ecx
+    xor %edx, %edx
+    wrmsr
+
+.Lend_\@:
+.endm
+
+.macro DO_SPEC_CTRL_EXIT_TO_GUEST
+/*
+ * Requires %rbx=current, %rsp=regs/cpuinfo
+ * Clobbers %rax, %rcx, %rdx
+ *
+ * When returning to guest context, set up SPEC_CTRL shadowing and load the
+ * guest value.
+ */
+    mov VCPU_arch_msr(%rbx), %rdx
+    mov VCPUMSR_spec_ctrl_host(%rdx), %eax
+
+    /* Set up shadow value *before* enabling shadowing. */
+    mov %eax, CPUINFO_shadow_spec_ctrl(%rsp)
+
+    /* Set SPEC_CTRL shadowing *before* loading the guest value. */
+    movb $1, CPUINFO_use_shadow_spec_ctrl(%rsp)
+
+    mov $MSR_SPEC_CTRL, %ecx
+    xor %edx, %edx
+    wrmsr
+.endm
+
+/* Use after a VMEXIT from an HVM guest. */
+#define SPEC_CTRL_ENTRY_FROM_VMEXIT                                     \
+    ALTERNATIVE_2 __stringify(ASM_NOP32),                               \
+        __stringify(DO_SPEC_CTRL_ENTRY_FROM_VMEXIT                      \
+                    ibrs_val=SPEC_CTRL_IBRS),                           \
+        X86_FEATURE_XEN_IBRS_SET,                                       \
+        __stringify(DO_SPEC_CTRL_ENTRY_FROM_VMEXIT                      \
+                    ibrs_val=0),                                        \
+        X86_FEATURE_XEN_IBRS_CLEAR
+
+/* Use after an entry from PV context (syscall/sysenter/int80/int82/etc). */
+#define SPEC_CTRL_ENTRY_FROM_PV                                         \
+    ALTERNATIVE_2 __stringify(ASM_NOP22),                               \
+        __stringify(DO_SPEC_CTRL_ENTRY maybexen=0                       \
+                    ibrs_val=SPEC_CTRL_IBRS),                           \
+        X86_FEATURE_XEN_IBRS_SET,                                       \
+        __stringify(DO_SPEC_CTRL_ENTRY maybexen=0 ibrs_val=0),          \
+        X86_FEATURE_XEN_IBRS_CLEAR
+
+/* Use in interrupt/exception context.  May interrupt Xen or PV context. */
+#define SPEC_CTRL_ENTRY_FROM_INTR                                       \
+    ALTERNATIVE_2 __stringify(ASM_NOP39),                               \
+        __stringify(DO_SPEC_CTRL_ENTRY maybexen=1                       \
+                    ibrs_val=SPEC_CTRL_IBRS),                           \
+        X86_FEATURE_XEN_IBRS_SET,                                       \
+        __stringify(DO_SPEC_CTRL_ENTRY maybexen=1 ibrs_val=0),          \
+        X86_FEATURE_XEN_IBRS_CLEAR
+
+/* Use when exiting to Xen context. */
+#define SPEC_CTRL_EXIT_TO_XEN                                           \
+    ALTERNATIVE_2 __stringify(ASM_NOP26),                               \
+        DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_XEN_IBRS_SET,             \
+        DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_XEN_IBRS_CLEAR
+
+/* Use when exiting to guest context. */
+#define SPEC_CTRL_EXIT_TO_GUEST                                         \
+    ALTERNATIVE_2 __stringify(ASM_NOP33),                               \
+        DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_XEN_IBRS_SET,           \
+        DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_XEN_IBRS_CLEAR
+
+#endif /* __ASSEMBLY__ */
+#endif /* !__X86_SPEC_CTRL_ASM_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 22/26] x86/boot: Calculate the most appropriate BTI mitigation to use
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (20 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 21/26] x86/entry: Use MSR_SPEC_CTRL at each entry/exit point Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04 10:17   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 23/26] x86/entry: Clobber the Return Stack Buffer on entry to Xen Andrew Cooper
                   ` (3 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v4:
 * New
v5:
 * Whitespace fixes
---
 docs/misc/xen-command-line.markdown |   6 ++-
 xen/arch/x86/spec_ctrl.c            | 103 ++++++++++++++++++++++++++++++++++--
 2 files changed, 104 insertions(+), 5 deletions(-)

diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index 19e12ac..3429484 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -246,7 +246,7 @@ enough. Setting this to a high value may cause boot failure, particularly if
 the NMI watchdog is also enabled.
 
 ### bti (x86)
-> `= List of [ thunk=retpoline|lfence|plain ]`
+> `= List of [ thunk=retpoline|lfence|plain, ibrs=<bool> ]`
 
 Branch Target Injection controls.  By default, Xen will pick the most
 appropriate BTI mitigations based on compiled in support, loaded microcode,
@@ -259,6 +259,10 @@ select which of the thunks gets patched into the `__x86.indirect_thunk.%reg`
 locations.  The default thunk is `retpoline`, with the alternatives being
 `plain` (a `jmp *%reg` gadget), and `lfence` (an `lfence; jmp *%reg` gadget).
 
+On hardware supporting IBRS, the `ibrs=` option can be used to force or
+prevent Xen using the feature itself.  If Xen is not using IBRS itself,
+functionality is still set up so IBRS can be virtualised for guests.
+
 ### xenheap\_megabytes (arm32)
 > `= <size>`
 
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index d9ace2d..1cccb8a 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -20,6 +20,7 @@
 #include <xen/init.h>
 #include <xen/lib.h>
 
+#include <asm/microcode.h>
 #include <asm/processor.h>
 #include <asm/spec_ctrl.h>
 
@@ -31,11 +32,12 @@ enum ind_thunk {
     THUNK_LFENCE,
     THUNK_JMP,
 } opt_thunk __initdata = THUNK_DEFAULT;
+int opt_ibrs __initdata = -1;
 
 static int __init parse_bti(const char *s)
 {
     const char *ss;
-    int rc = 0;
+    int val, rc = 0;
 
     do {
         ss = strchr(s, ',');
@@ -55,6 +57,8 @@ static int __init parse_bti(const char *s)
             else
                 rc = -EINVAL;
         }
+        else if ( (val = parse_boolean("ibrs", s, ss)) >= 0 )
+            opt_ibrs = val;
         else
             rc = -EINVAL;
 
@@ -91,24 +95,82 @@ static void __init print_details(enum ind_thunk thunk)
         printk(XENLOG_DEBUG "  Compiled-in support: INDIRECT_THUNK\n");
 
     printk(XENLOG_INFO
-           "BTI mitigations: Thunk %s\n",
+           "BTI mitigations: Thunk %s, Others:%s\n",
            thunk == THUNK_NONE      ? "N/A" :
            thunk == THUNK_RETPOLINE ? "RETPOLINE" :
            thunk == THUNK_LFENCE    ? "LFENCE" :
-           thunk == THUNK_JMP       ? "JMP" : "?");
+           thunk == THUNK_JMP       ? "JMP" : "?",
+           boot_cpu_has(X86_FEATURE_XEN_IBRS_SET)    ? " IBRS+" :
+           boot_cpu_has(X86_FEATURE_XEN_IBRS_CLEAR)  ? " IBRS-"      : "");
+}
+
+/* Calculate whether Retpoline is known-safe on this CPU. */
+static bool __init retpoline_safe(void)
+{
+    unsigned int ucode_rev = this_cpu(ucode_cpu_info).cpu_sig.rev;
+
+    if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+        return true;
+
+    if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
+         boot_cpu_data.x86 != 6 )
+        return false;
+
+    switch ( boot_cpu_data.x86_model )
+    {
+    case 0x17: /* Penryn */
+    case 0x1d: /* Dunnington */
+    case 0x1e: /* Nehalem */
+    case 0x1f: /* Auburndale / Havendale */
+    case 0x1a: /* Nehalem EP */
+    case 0x2e: /* Nehalem EX */
+    case 0x25: /* Westmere */
+    case 0x2c: /* Westmere EP */
+    case 0x2f: /* Westmere EX */
+    case 0x2a: /* SandyBridge */
+    case 0x2d: /* SandyBridge EP/EX */
+    case 0x3a: /* IvyBridge */
+    case 0x3e: /* IvyBridge EP/EX */
+    case 0x3c: /* Haswell */
+    case 0x3f: /* Haswell EX/EP */
+    case 0x45: /* Haswell D */
+    case 0x46: /* Haswell H */
+        return true;
+
+        /*
+         * Broadwell processors are retpoline-safe after specific microcode
+         * versions.
+         */
+    case 0x3d: /* Broadwell */
+        return ucode_rev >= 0x28;
+    case 0x47: /* Broadwell H */
+        return ucode_rev >= 0x1b;
+    case 0x4f: /* Broadwell EP/EX */
+        return ucode_rev >= 0xb000025;
+    case 0x56: /* Broadwell D */
+        return false; /* TBD. */
+
+        /*
+         * Skylake and later processors are not retpoline-safe.
+         */
+    default:
+        return false;
+    }
 }
 
 void __init init_speculation_mitigations(void)
 {
     enum ind_thunk thunk = THUNK_DEFAULT;
+    bool ibrs = false;
 
     /*
      * Has the user specified any custom BTI mitigations?  If so, follow their
      * instructions exactly and disable all heuristics.
      */
-    if ( opt_thunk != THUNK_DEFAULT )
+    if ( opt_thunk != THUNK_DEFAULT || opt_ibrs != -1 )
     {
         thunk = opt_thunk;
+        ibrs  = !!opt_ibrs;
     }
     else
     {
@@ -124,7 +186,21 @@ void __init init_speculation_mitigations(void)
              */
             if ( cpu_has_lfence_dispatch )
                 thunk = THUNK_LFENCE;
+            /*
+             * On Intel hardware, we'd like to use retpoline in preference to
+             * IBRS, but only if it is safe on this hardware.
+             */
+            else if ( boot_cpu_has(X86_FEATURE_IBRSB) )
+            {
+                if ( retpoline_safe() )
+                    thunk = THUNK_RETPOLINE;
+                else
+                    ibrs = true;
+            }
         }
+        /* Without compiler thunk support, use IBRS if available. */
+        else if ( boot_cpu_has(X86_FEATURE_IBRSB) )
+            ibrs = true;
     }
 
     /*
@@ -135,6 +211,13 @@ void __init init_speculation_mitigations(void)
         thunk = THUNK_NONE;
 
     /*
+     * If IBRS is in use and thunks are compiled in, there is no point
+     * suffering extra overhead.  Switch to the least-overhead thunk.
+     */
+    if ( ibrs && thunk == THUNK_DEFAULT )
+        thunk = THUNK_JMP;
+
+    /*
      * If there are still no thunk preferences, the compiled default is
      * actually retpoline, and it is better than nothing.
      */
@@ -147,6 +230,18 @@ void __init init_speculation_mitigations(void)
     else if ( thunk == THUNK_JMP )
         setup_force_cpu_cap(X86_FEATURE_IND_THUNK_JMP);
 
+    /*
+     * Even if we've chosen not to use IBRS for Xen itself, we still need the
+     * IBRS entry/exit logic to virtualise IBRS support for guests.
+     */
+    if ( boot_cpu_has(X86_FEATURE_IBRSB) )
+    {
+        if ( ibrs )
+            setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_SET);
+        else
+            setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_CLEAR);
+    }
+
     print_details(thunk);
 }
 
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 23/26] x86/entry: Clobber the Return Stack Buffer on entry to Xen
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (21 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 22/26] x86/boot: Calculate the most appropriate BTI mitigation to use Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04 10:22   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 24/26] x86/ctxt: Issue a speculation barrier between vcpu contexts Andrew Cooper
                   ` (2 subsequent siblings)
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

ret instructions are unconditionally speculated based on values in the RSB.
If any path in Xen executes more ret than call instructions, speculation can
start following a guest controlled RSB entry.

There is at least one path (wake from waitqueue) which can end up executing
more ret than call instructions.  There may be other paths as well.

To mitigate, overwrite the RSB (when appropriate; see code for details) when
entering Xen from guest context.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v2:
 * Rename pv/hvm to native/vmexit to be clearer
 * Reorder before SPEC_CTRL_ENTRY
 * Calculate when to clobber the RSB
 * Skip clobbering the RSB when interrupting Xen
v3:
 * Rework to be consistent the rewritten SPEC_CTRL_* patch
v4:
 * Merge OVERWRITE_RSB_* into SPEC_CTRL_ENTRY_* to enforce the ordering
   dependency.
 * Rebase over AMD changes
---
 docs/misc/xen-command-line.markdown |  6 ++-
 xen/arch/x86/spec_ctrl.c            | 81 +++++++++++++++++++++++++++++++++----
 xen/include/asm-x86/cpufeature.h    |  1 +
 xen/include/asm-x86/cpufeatures.h   |  4 ++
 xen/include/asm-x86/nops.h          |  2 +
 xen/include/asm-x86/spec_ctrl_asm.h | 46 +++++++++++++++++++++
 6 files changed, 131 insertions(+), 9 deletions(-)

diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index 3429484..8bffe44 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -246,7 +246,7 @@ enough. Setting this to a high value may cause boot failure, particularly if
 the NMI watchdog is also enabled.
 
 ### bti (x86)
-> `= List of [ thunk=retpoline|lfence|plain, ibrs=<bool> ]`
+> `= List of [ thunk=retpoline|lfence|plain, ibrs=<bool>, rsb_{vmexit,native}=bool ]`
 
 Branch Target Injection controls.  By default, Xen will pick the most
 appropriate BTI mitigations based on compiled in support, loaded microcode,
@@ -263,6 +263,10 @@ On hardware supporting IBRS, the `ibrs=` option can be used to force or
 prevent Xen using the feature itself.  If Xen is not using IBRS itself,
 functionality is still set up so IBRS can be virtualised for guests.
 
+The `rsb_vmexit=` and `rsb_native=` options can be used to fine tune when the
+RSB gets overwritten.  There are individual controls for an entry from HVM
+context, and an entry from a native (PV or Xen) context.
+
 ### xenheap\_megabytes (arm32)
 > `= <size>`
 
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index 1cccb8a..bbf8f96 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -33,6 +33,7 @@ enum ind_thunk {
     THUNK_JMP,
 } opt_thunk __initdata = THUNK_DEFAULT;
 int opt_ibrs __initdata = -1;
+int opt_rsb_native __initdata = -1, opt_rsb_vmexit __initdata = -1;
 
 static int __init parse_bti(const char *s)
 {
@@ -59,6 +60,10 @@ static int __init parse_bti(const char *s)
         }
         else if ( (val = parse_boolean("ibrs", s, ss)) >= 0 )
             opt_ibrs = val;
+        else if ( (val = parse_boolean("rsb_native", s, ss)) >= 0 )
+            opt_rsb_native = val;
+        else if ( (val = parse_boolean("rsb_vmexit", s, ss)) >= 0 )
+            opt_rsb_vmexit = val;
         else
             rc = -EINVAL;
 
@@ -71,21 +76,23 @@ custom_param("bti", parse_bti);
 
 static void __init print_details(enum ind_thunk thunk)
 {
-    unsigned int _7d0 = 0, e8b = 0, tmp;
+    unsigned int _7b0 = 0, _7d0 = 0, e8b = 0, tmp;
 
     /* Collect diagnostics about available mitigations. */
     if ( boot_cpu_data.cpuid_level >= 7 )
-        cpuid_count(7, 0, &tmp, &tmp, &tmp, &_7d0);
+        cpuid_count(7, 0, &tmp, &_7b0, &tmp, &_7d0);
     if ( boot_cpu_data.extended_cpuid_level >= 0x80000008 )
         cpuid(0x80000008, &tmp, &e8b, &tmp, &tmp);
 
     printk(XENLOG_DEBUG "Speculative mitigation facilities:\n");
 
     /* Hardware features which pertain to speculative mitigations. */
-    if ( (_7d0 & (cpufeat_mask(X86_FEATURE_IBRSB) |
+    if ( (_7b0 & cpufeat_mask(X86_FEATURE_SMEP)) ||
+         (_7d0 & (cpufeat_mask(X86_FEATURE_IBRSB) |
                   cpufeat_mask(X86_FEATURE_STIBP))) ||
          (e8b & cpufeat_mask(X86_FEATURE_IBPB)) )
-        printk(XENLOG_DEBUG "  Hardware features:%s%s%s\n",
+        printk(XENLOG_DEBUG "  Hardware features:%s%s%s%s\n",
+               (_7b0 & cpufeat_mask(X86_FEATURE_SMEP))  ? " SMEP"      : "",
                (_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "",
                (_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP"     : "",
                (e8b  & cpufeat_mask(X86_FEATURE_IBPB))  ? " IBPB"      : "");
@@ -95,13 +102,18 @@ static void __init print_details(enum ind_thunk thunk)
         printk(XENLOG_DEBUG "  Compiled-in support: INDIRECT_THUNK\n");
 
     printk(XENLOG_INFO
-           "BTI mitigations: Thunk %s, Others:%s\n",
+           "BTI mitigations: Thunk %s, Others:%s%s%s%s\n",
            thunk == THUNK_NONE      ? "N/A" :
            thunk == THUNK_RETPOLINE ? "RETPOLINE" :
            thunk == THUNK_LFENCE    ? "LFENCE" :
            thunk == THUNK_JMP       ? "JMP" : "?",
            boot_cpu_has(X86_FEATURE_XEN_IBRS_SET)    ? " IBRS+" :
-           boot_cpu_has(X86_FEATURE_XEN_IBRS_CLEAR)  ? " IBRS-"      : "");
+           boot_cpu_has(X86_FEATURE_XEN_IBRS_CLEAR)  ? " IBRS-"      : "",
+           cpu_has_xen_smep                          ? " SMEP"       : "",
+           (boot_cpu_has(X86_FEATURE_RSB_VMEXIT) ||
+            boot_cpu_has(X86_FEATURE_RSB_VMEXIT_SS)) ? " RSB_VMEXIT" : "",
+           (boot_cpu_has(X86_FEATURE_RSB_NATIVE) ||
+            boot_cpu_has(X86_FEATURE_RSB_NATIVE_SS)) ? " RSB_NATIVE" : "");
 }
 
 /* Calculate whether Retpoline is known-safe on this CPU. */
@@ -161,13 +173,14 @@ static bool __init retpoline_safe(void)
 void __init init_speculation_mitigations(void)
 {
     enum ind_thunk thunk = THUNK_DEFAULT;
-    bool ibrs = false;
+    bool ibrs = false, have_mitigation = true;
 
     /*
      * Has the user specified any custom BTI mitigations?  If so, follow their
      * instructions exactly and disable all heuristics.
      */
-    if ( opt_thunk != THUNK_DEFAULT || opt_ibrs != -1 )
+    if ( opt_thunk != THUNK_DEFAULT || opt_ibrs != -1 ||
+         opt_rsb_native != -1 || opt_rsb_vmexit != -1 )
     {
         thunk = opt_thunk;
         ibrs  = !!opt_ibrs;
@@ -201,6 +214,9 @@ void __init init_speculation_mitigations(void)
         /* Without compiler thunk support, use IBRS if available. */
         else if ( boot_cpu_has(X86_FEATURE_IBRSB) )
             ibrs = true;
+        /* Or give up completely. */
+        else
+            have_mitigation = false;
     }
 
     /*
@@ -242,6 +258,55 @@ void __init init_speculation_mitigations(void)
             setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_CLEAR);
     }
 
+    /*
+     * Only bother overwriting the RSBs if we have a BTI mitigation available.
+     * Otherwise, we're already wide open to easier attacks than RSB-poisoning.
+     */
+    if ( have_mitigation )
+    {
+        /*
+         * If we are writing to MSR_SPEC_CTRL, the WRMSR is sufficiently
+         * serialising to protect against speculative exits of the RSB loop.
+         * If not, the RSB loop needs to provide its own speculative defence.
+         */
+        bool ss = !(boot_cpu_has(X86_FEATURE_XEN_IBRS_SET) ||
+                    boot_cpu_has(X86_FEATURE_XEN_IBRS_CLEAR));
+
+        /*
+         * HVM guests can always poison the RSB to point at Xen supervisor
+         * mappings.
+         */
+        if ( opt_rsb_vmexit )
+        {
+            BUILD_BUG_ON(X86_FEATURE_RSB_VMEXIT_SS !=
+                         X86_FEATURE_RSB_VMEXIT + 1);
+
+            setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT + ss);
+        }
+
+        /*
+         * PV guests can poison the RSB to any virtual address from which
+         * they can execute a call instruction.  This is necessarily outside
+         * of the Xen supervisor mappings.
+         *
+         * With SMEP enabled, the processor won't speculate into user
+         * mappings, and therefore, don't need to worry about poisioned
+         * entries.
+         *
+         * 32bit PV guest kernels run in ring 1, so use supervisor mappings.
+         * However, nothing secret lives below the 4G boundary, so a 32bit PV
+         * guest can't do anything useful by hijacking execution.
+         */
+        if ( opt_rsb_native == 1 ||
+             (opt_rsb_native == -1 && !cpu_has_xen_smep) )
+        {
+            BUILD_BUG_ON(X86_FEATURE_RSB_NATIVE_SS !=
+                         X86_FEATURE_RSB_NATIVE + 1);
+
+            setup_force_cpu_cap(X86_FEATURE_RSB_NATIVE + ss);
+        }
+    }
+
     print_details(thunk);
 }
 
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index 988a834..b7667b4 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -107,6 +107,7 @@
 #define cpu_has_arch_perfmon    boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
 #define cpu_has_cpuid_faulting  boot_cpu_has(X86_FEATURE_CPUID_FAULTING)
 #define cpu_has_aperfmperf      boot_cpu_has(X86_FEATURE_APERFMPERF)
+#define cpu_has_xen_smep        boot_cpu_has(X86_FEATURE_XEN_SMEP)
 #define cpu_has_lfence_dispatch boot_cpu_has(X86_FEATURE_LFENCE_DISPATCH)
 
 enum _cache_type {
diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h
index dd2388f..56dd8f4 100644
--- a/xen/include/asm-x86/cpufeatures.h
+++ b/xen/include/asm-x86/cpufeatures.h
@@ -28,3 +28,7 @@ XEN_CPUFEATURE(IND_THUNK_JMP,   (FSCAPINTS+0)*32+14) /* Use IND_THUNK_JMP */
 XEN_CPUFEATURE(XEN_IBPB,        (FSCAPINTS+0)*32+15) /* IBRSB || IBPB */
 XEN_CPUFEATURE(XEN_IBRS_SET,    (FSCAPINTS+0)*32+16) /* IBRSB && IRBS set in Xen */
 XEN_CPUFEATURE(XEN_IBRS_CLEAR,  (FSCAPINTS+0)*32+17) /* IBRSB && IBRS clear in Xen */
+XEN_CPUFEATURE(RSB_NATIVE,      (FSCAPINTS+0)*32+18) /* RSB overwrite needed for native */
+XEN_CPUFEATURE(RSB_NATIVE_SS,   (FSCAPINTS+0)*32+19) /* RSB_NATIVE must self-serialise */
+XEN_CPUFEATURE(RSB_VMEXIT,      (FSCAPINTS+0)*32+20) /* RSB overwrite needed for vmexit */
+XEN_CPUFEATURE(RSB_VMEXIT_SS,   (FSCAPINTS+0)*32+21) /* RSB_VMEXIT must self-serialise */
diff --git a/xen/include/asm-x86/nops.h b/xen/include/asm-x86/nops.h
index 9e8f530..752fb0e 100644
--- a/xen/include/asm-x86/nops.h
+++ b/xen/include/asm-x86/nops.h
@@ -67,9 +67,11 @@
 
 #define ASM_NOP22 ASM_NOP8 ASM_NOP8 ASM_NOP6
 #define ASM_NOP26 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP2
+#define ASM_NOP27 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP3
 #define ASM_NOP32 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8
 #define ASM_NOP33 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP7 ASM_NOP2
 #define ASM_NOP39 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP7
+#define ASM_NOP40 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8
 
 #define ASM_NOP_MAX 9
 
diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h
index 13e058c..430b440 100644
--- a/xen/include/asm-x86/spec_ctrl_asm.h
+++ b/xen/include/asm-x86/spec_ctrl_asm.h
@@ -73,6 +73,37 @@
  *  - SPEC_CTRL_EXIT_TO_GUEST
  */
 
+.macro DO_OVERWRITE_RSB maybexen:req ss:req
+/*
+ * Req: %rsp=regs
+ * Clobbers %ecx
+ *
+ * Requires 256 bytes of stack space, but %rsp has no net change.  Optionally
+ * checks for interrupting Xen context, and skipping the clobber.
+ *
+ * For safety, there must be an instruction stream serialising event between
+ * this loop and the next unmatched ret, to prevent an early speculative exit.
+ * If IBRS is in use, its WRMSR is sufficiently serialising.  If IBRS is not
+ * available, place an lfence after the loop to seriailse.
+ */
+    .if \maybexen
+        cmpl $__HYPERVISOR_CS, UREGS_cs(%rsp)
+        je .Lend_\@
+    .endif
+
+    mov $32, %ecx
+.Lloop_\@: call .Lcall_\@
+    pause
+.Lcall_\@: sub $1, %ecx
+    jnz .Lloop_\@
+    add $32*8, %rsp
+.Lend_\@:
+
+    .if \ss /* Need to self-serialise? */
+        lfence
+    .endif
+.endm
+
 .macro DO_SPEC_CTRL_ENTRY_FROM_VMEXIT ibrs_val:req
 /*
  * Requires %rbx=current, %rsp=regs/cpuinfo
@@ -178,6 +209,11 @@
 
 /* Use after a VMEXIT from an HVM guest. */
 #define SPEC_CTRL_ENTRY_FROM_VMEXIT                                     \
+    ALTERNATIVE_2 __stringify(ASM_NOP27),                               \
+        "DO_OVERWRITE_RSB maybexen=0 ss=1",                             \
+        X86_FEATURE_RSB_VMEXIT_SS,                                      \
+        "DO_OVERWRITE_RSB maybexen=0 ss=0",                             \
+        X86_FEATURE_RSB_VMEXIT;                                         \
     ALTERNATIVE_2 __stringify(ASM_NOP32),                               \
         __stringify(DO_SPEC_CTRL_ENTRY_FROM_VMEXIT                      \
                     ibrs_val=SPEC_CTRL_IBRS),                           \
@@ -188,6 +224,11 @@
 
 /* Use after an entry from PV context (syscall/sysenter/int80/int82/etc). */
 #define SPEC_CTRL_ENTRY_FROM_PV                                         \
+    ALTERNATIVE_2 __stringify(ASM_NOP27),                               \
+        "DO_OVERWRITE_RSB maybexen=0 ss=1",                             \
+        X86_FEATURE_RSB_NATIVE_SS,                                      \
+        "DO_OVERWRITE_RSB maybexen=0 ss=0",                             \
+        X86_FEATURE_RSB_NATIVE;                                         \
     ALTERNATIVE_2 __stringify(ASM_NOP22),                               \
         __stringify(DO_SPEC_CTRL_ENTRY maybexen=0                       \
                     ibrs_val=SPEC_CTRL_IBRS),                           \
@@ -197,6 +238,11 @@
 
 /* Use in interrupt/exception context.  May interrupt Xen or PV context. */
 #define SPEC_CTRL_ENTRY_FROM_INTR                                       \
+    ALTERNATIVE_2 __stringify(ASM_NOP40),                               \
+        "DO_OVERWRITE_RSB maybexen=1 ss=1",                             \
+        X86_FEATURE_RSB_NATIVE_SS,                                      \
+        "DO_OVERWRITE_RSB maybexen=1 ss=0",                             \
+        X86_FEATURE_RSB_NATIVE;                                         \
     ALTERNATIVE_2 __stringify(ASM_NOP39),                               \
         __stringify(DO_SPEC_CTRL_ENTRY maybexen=1                       \
                     ibrs_val=SPEC_CTRL_IBRS),                           \
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 24/26] x86/ctxt: Issue a speculation barrier between vcpu contexts
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (22 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 23/26] x86/entry: Clobber the Return Stack Buffer on entry to Xen Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04 10:25   ` Jan Beulich
  2018-01-04  0:15 ` [PATCH v6.5 25/26] x86/cpuid: Offer Indirect Branch Controls to guests Andrew Cooper
  2018-01-04  0:15 ` [PATCH v6.5 26/26] x86/idle: Clear SPEC_CTRL while idle Andrew Cooper
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
v4:
 * Adjust for AMD changes
---
 docs/misc/xen-command-line.markdown |  5 ++++-
 xen/arch/x86/domain.c               |  3 +++
 xen/arch/x86/spec_ctrl.c            | 13 ++++++++++---
 xen/include/asm-x86/cpufeature.h    |  1 +
 4 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index 8bffe44..65d94f2 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -246,7 +246,7 @@ enough. Setting this to a high value may cause boot failure, particularly if
 the NMI watchdog is also enabled.
 
 ### bti (x86)
-> `= List of [ thunk=retpoline|lfence|plain, ibrs=<bool>, rsb_{vmexit,native}=bool ]`
+> `= List of [ thunk=retpoline|lfence|plain, ibrs=<bool>, ibpb=<bool>, rsb_{vmexit,native}=bool ]`
 
 Branch Target Injection controls.  By default, Xen will pick the most
 appropriate BTI mitigations based on compiled in support, loaded microcode,
@@ -263,6 +263,9 @@ On hardware supporting IBRS, the `ibrs=` option can be used to force or
 prevent Xen using the feature itself.  If Xen is not using IBRS itself,
 functionality is still set up so IBRS can be virtualised for guests.
 
+On hardware supporting IBPB, the `ibpb=` option can be used to prevent Xen
+from issuing Branch Prediction Barriers on vcpu context switches.
+
 The `rsb_vmexit=` and `rsb_native=` options can be used to fine tune when the
 RSB gets overwritten.  There are individual controls for an entry from HVM
 context, and an entry from a native (PV or Xen) context.
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 698346e..62002f1 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1732,6 +1732,9 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
         }
 
         ctxt_switch_levelling(next);
+
+        if ( cpu_has_xen_ibpb )
+            wrmsrl(MSR_PRED_CMD, PRED_CMD_IBPB);
     }
 
     context_saved(prev);
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index bbf8f96..79aedf7 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -32,7 +32,7 @@ enum ind_thunk {
     THUNK_LFENCE,
     THUNK_JMP,
 } opt_thunk __initdata = THUNK_DEFAULT;
-int opt_ibrs __initdata = -1;
+int opt_ibrs __initdata = -1, opt_ibpb __initdata = -1;
 int opt_rsb_native __initdata = -1, opt_rsb_vmexit __initdata = -1;
 
 static int __init parse_bti(const char *s)
@@ -60,6 +60,8 @@ static int __init parse_bti(const char *s)
         }
         else if ( (val = parse_boolean("ibrs", s, ss)) >= 0 )
             opt_ibrs = val;
+        else if ( (val = parse_boolean("ibpb", s, ss)) >= 0 )
+            opt_ibpb = val;
         else if ( (val = parse_boolean("rsb_native", s, ss)) >= 0 )
             opt_rsb_native = val;
         else if ( (val = parse_boolean("rsb_vmexit", s, ss)) >= 0 )
@@ -102,13 +104,14 @@ static void __init print_details(enum ind_thunk thunk)
         printk(XENLOG_DEBUG "  Compiled-in support: INDIRECT_THUNK\n");
 
     printk(XENLOG_INFO
-           "BTI mitigations: Thunk %s, Others:%s%s%s%s\n",
+           "BTI mitigations: Thunk %s, Others:%s%s%s%s%s\n",
            thunk == THUNK_NONE      ? "N/A" :
            thunk == THUNK_RETPOLINE ? "RETPOLINE" :
            thunk == THUNK_LFENCE    ? "LFENCE" :
            thunk == THUNK_JMP       ? "JMP" : "?",
            boot_cpu_has(X86_FEATURE_XEN_IBRS_SET)    ? " IBRS+" :
            boot_cpu_has(X86_FEATURE_XEN_IBRS_CLEAR)  ? " IBRS-"      : "",
+           cpu_has_xen_ibpb                          ? " IBPB"       : "",
            cpu_has_xen_smep                          ? " SMEP"       : "",
            (boot_cpu_has(X86_FEATURE_RSB_VMEXIT) ||
             boot_cpu_has(X86_FEATURE_RSB_VMEXIT_SS)) ? " RSB_VMEXIT" : "",
@@ -179,7 +182,7 @@ void __init init_speculation_mitigations(void)
      * Has the user specified any custom BTI mitigations?  If so, follow their
      * instructions exactly and disable all heuristics.
      */
-    if ( opt_thunk != THUNK_DEFAULT || opt_ibrs != -1 ||
+    if ( opt_thunk != THUNK_DEFAULT || opt_ibrs != -1 || opt_ibrs != -1 ||
          opt_rsb_native != -1 || opt_rsb_vmexit != -1 )
     {
         thunk = opt_thunk;
@@ -307,6 +310,10 @@ void __init init_speculation_mitigations(void)
         }
     }
 
+    if ( (boot_cpu_has(X86_FEATURE_IBRSB) ||
+          boot_cpu_has(X86_FEATURE_IBPB)) && opt_ibpb )
+        setup_force_cpu_cap(X86_FEATURE_XEN_IBPB);
+
     print_details(thunk);
 }
 
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index b7667b4..f1c30f1 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -109,6 +109,7 @@
 #define cpu_has_aperfmperf      boot_cpu_has(X86_FEATURE_APERFMPERF)
 #define cpu_has_xen_smep        boot_cpu_has(X86_FEATURE_XEN_SMEP)
 #define cpu_has_lfence_dispatch boot_cpu_has(X86_FEATURE_LFENCE_DISPATCH)
+#define cpu_has_xen_ibpb        boot_cpu_has(X86_FEATURE_XEN_IBPB)
 
 enum _cache_type {
     CACHE_TYPE_NULL = 0,
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 25/26] x86/cpuid: Offer Indirect Branch Controls to guests
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (23 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 24/26] x86/ctxt: Issue a speculation barrier between vcpu contexts Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-09 11:44   ` Wei Liu
  2018-01-04  0:15 ` [PATCH v6.5 26/26] x86/idle: Clear SPEC_CTRL while idle Andrew Cooper
  25 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

With all infrastructure in place, it is now safe to let guests see and use
these features.  Allow AMD's IBPB to be set even on Intel hardware, so the
toolstack can express "IBPB only" to guests.

This also requires updating the libxc logic to understand the e8b feature
leaf, which has the side effect of also offering CLZERO on applicable
hardware.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
v4:
 * Adjust for AMD changes
v5:
 * Support for IBRB-only
v6:
 * Fix AMD CPUID
---
 tools/libxc/xc_cpuid_x86.c                  | 4 +++-
 xen/arch/x86/cpuid.c                        | 8 ++++++++
 xen/include/public/arch-x86/cpufeatureset.h | 6 +++---
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index 25b922e..9fa2f7c 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -465,7 +465,9 @@ static void xc_cpuid_hvm_policy(xc_interface *xch,
 
     case 0x80000008:
         regs[0] &= 0x0000ffffu;
-        regs[1] = regs[3] = 0;
+        regs[1] = info->featureset[featureword_of(X86_FEATURE_CLZERO)];
+        /* regs[2] handled in the per-vendor logic. */
+        regs[3] = 0;
         break;
 
     case 0x00000002: /* Intel cache info (dumped by AMD policy) */
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 2ef71d2..e1b8c7a 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -354,6 +354,14 @@ static void __init calculate_host_policy(void)
     recalculate_xstate(p);
     recalculate_misc(p);
 
+    /*
+     * AMD's IPBP is a subset of Intel's IBRS/IBPB.  For performance reasons,
+     * we may want to offer a guest only IBPB and not IBRS, so allow the AMD
+     * CPUID bit to be used whenever the hardware supports IBPB.
+     */
+    if ( p->feat.ibrsb )
+        p->extd.ibpb = true;
+
     if ( p->extd.svm )
     {
         /* Clamp to implemented features which require hardware support. */
diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h
index e148755..aaeb149 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -237,13 +237,13 @@ XEN_CPUFEATURE(EFRO,          7*32+10) /*   APERF/MPERF Read Only interface */
 
 /* AMD-defined CPU features, CPUID level 0x80000008.ebx, word 8 */
 XEN_CPUFEATURE(CLZERO,        8*32+ 0) /*A  CLZERO instruction */
-XEN_CPUFEATURE(IBPB,          8*32+12) /*   IBPB support only (no IBRS, used by AMD) */
+XEN_CPUFEATURE(IBPB,          8*32+12) /*A  IBPB support only (no IBRS, used by AMD) */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0.edx, word 9 */
 XEN_CPUFEATURE(AVX512_4VNNIW, 9*32+ 2) /*A  AVX512 Neural Network Instructions */
 XEN_CPUFEATURE(AVX512_4FMAPS, 9*32+ 3) /*A  AVX512 Multiply Accumulation Single Precision */
-XEN_CPUFEATURE(IBRSB,         9*32+26) /*   IBRS and IBPB support (used by Intel) */
-XEN_CPUFEATURE(STIBP,         9*32+27) /*   STIBP */
+XEN_CPUFEATURE(IBRSB,         9*32+26) /*A  IBRS and IBPB support (used by Intel) */
+XEN_CPUFEATURE(STIBP,         9*32+27) /*A  STIBP */
 
 #endif /* XEN_CPUFEATURE */
 
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v6.5 26/26] x86/idle: Clear SPEC_CTRL while idle
  2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
                   ` (24 preceding siblings ...)
  2018-01-04  0:15 ` [PATCH v6.5 25/26] x86/cpuid: Offer Indirect Branch Controls to guests Andrew Cooper
@ 2018-01-04  0:15 ` Andrew Cooper
  2018-01-04 10:29   ` Jan Beulich
  2018-01-04 10:41   ` Jan Beulich
  25 siblings, 2 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  0:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

On contemporary hardware, setting IBRS/STIBP has a performance impact on
adjacent hyperthreads.  It is therefore recommended to clear the setting
before becoming idle, to avoid an idle core preventing adjacent userspace
execution from running at full performance.

Care must be taken to ensure there are no ret or indirect branch instructions
between spec_ctrl_{enter,exit}_idle() invocations, which are forced always
inline.  Care must also be taken to avoid using spec_ctrl_enter_idle() between
flushing caches and becoming idle, in cases where that matters.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v2:
 * Use spec_ctrl_{enter,exit}_idle() rather than opencoding
v3:
 * Reimplement almost from scratch.
v4:
 * Spelling fixes.
 * Drop k constraints.  They aren't actually modifiers.
---
 xen/arch/x86/acpi/cpu_idle.c    | 21 +++++++++++++++++++++
 xen/arch/x86/cpu/mwait-idle.c   |  7 +++++++
 xen/arch/x86/domain.c           |  8 ++++++++
 xen/include/asm-x86/spec_ctrl.h | 34 ++++++++++++++++++++++++++++++++++
 4 files changed, 70 insertions(+)

diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
index cb1c5da..3f72bda 100644
--- a/xen/arch/x86/acpi/cpu_idle.c
+++ b/xen/arch/x86/acpi/cpu_idle.c
@@ -55,6 +55,7 @@
 #include <asm/mwait.h>
 #include <xen/notifier.h>
 #include <xen/cpu.h>
+#include <asm/spec_ctrl.h>
 
 /*#define DEBUG_PM_CX*/
 
@@ -414,8 +415,14 @@ void mwait_idle_with_hints(unsigned int eax, unsigned int ecx)
      */
     if ( (expires > NOW() || expires == 0) && !softirq_pending(cpu) )
     {
+        struct cpu_info *info = get_cpu_info();
+
         cpumask_set_cpu(cpu, &cpuidle_mwait_flags);
+
+        spec_ctrl_enter_idle(info);
         __mwait(eax, ecx);
+        spec_ctrl_exit_idle(info);
+
         cpumask_clear_cpu(cpu, &cpuidle_mwait_flags);
     }
 
@@ -430,6 +437,8 @@ static void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
 
 static void acpi_idle_do_entry(struct acpi_processor_cx *cx)
 {
+    struct cpu_info *info = get_cpu_info();
+
     switch ( cx->entry_method )
     {
     case ACPI_CSTATE_EM_FFH:
@@ -437,15 +446,19 @@ static void acpi_idle_do_entry(struct acpi_processor_cx *cx)
         acpi_processor_ffh_cstate_enter(cx);
         return;
     case ACPI_CSTATE_EM_SYSIO:
+        spec_ctrl_enter_idle(info);
         /* IO port based C-state */
         inb(cx->address);
         /* Dummy wait op - must do something useless after P_LVL2 read
            because chipsets cannot guarantee that STPCLK# signal
            gets asserted in time to freeze execution properly. */
         inl(pmtmr_ioport);
+        spec_ctrl_exit_idle(info);
         return;
     case ACPI_CSTATE_EM_HALT:
+        spec_ctrl_enter_idle(info);
         safe_halt();
+        spec_ctrl_exit_idle(info);
         local_irq_disable();
         return;
     }
@@ -573,7 +586,13 @@ static void acpi_processor_idle(void)
         if ( pm_idle_save )
             pm_idle_save();
         else
+        {
+            struct cpu_info *info = get_cpu_info();
+
+            spec_ctrl_enter_idle(info);
             safe_halt();
+            spec_ctrl_exit_idle(info);
+        }
         return;
     }
 
@@ -752,6 +771,7 @@ void acpi_dead_idle(void)
          * Otherwise, CPU may still hold dirty data, breaking cache coherency,
          * leading to strange errors.
          */
+        spec_ctrl_enter_idle(get_cpu_info());
         wbinvd();
 
         while ( 1 )
@@ -781,6 +801,7 @@ void acpi_dead_idle(void)
         u32 address = cx->address;
         u32 pmtmr_ioport_local = pmtmr_ioport;
 
+        spec_ctrl_enter_idle(get_cpu_info());
         wbinvd();
 
         while ( 1 )
diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c
index 762dff1..e357f29 100644
--- a/xen/arch/x86/cpu/mwait-idle.c
+++ b/xen/arch/x86/cpu/mwait-idle.c
@@ -58,6 +58,7 @@
 #include <asm/hpet.h>
 #include <asm/mwait.h>
 #include <asm/msr.h>
+#include <asm/spec_ctrl.h>
 #include <acpi/cpufreq/cpufreq.h>
 
 #define MWAIT_IDLE_VERSION "0.4.1"
@@ -736,7 +737,13 @@ static void mwait_idle(void)
 		if (pm_idle_save)
 			pm_idle_save();
 		else
+		{
+			struct cpu_info *info = get_cpu_info();
+
+			spec_ctrl_enter_idle(info);
 			safe_halt();
+			spec_ctrl_exit_idle(info);
+		}
 		return;
 	}
 
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 62002f1..392e4f3 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -55,6 +55,7 @@
 #include <asm/hvm/viridian.h>
 #include <asm/debugreg.h>
 #include <asm/msr.h>
+#include <asm/spec_ctrl.h>
 #include <asm/traps.h>
 #include <asm/nmi.h>
 #include <asm/mce.h>
@@ -74,9 +75,15 @@ void (*dead_idle) (void) __read_mostly = default_dead_idle;
 
 static void default_idle(void)
 {
+    struct cpu_info *info = get_cpu_info();
+
     local_irq_disable();
     if ( cpu_is_haltable(smp_processor_id()) )
+    {
+        spec_ctrl_enter_idle(info);
         safe_halt();
+        spec_ctrl_exit_idle(info);
+    }
     else
         local_irq_enable();
 }
@@ -88,6 +95,7 @@ void default_dead_idle(void)
      * held by the CPUs spinning here indefinitely, and get discarded by
      * a subsequent INIT.
      */
+    spec_ctrl_enter_idle(get_cpu_info());
     wbinvd();
     for ( ; ; )
         halt();
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
index 29a31a9..20e9a5b 100644
--- a/xen/include/asm-x86/spec_ctrl.h
+++ b/xen/include/asm-x86/spec_ctrl.h
@@ -20,7 +20,9 @@
 #ifndef __X86_SPEC_CTRL_H__
 #define __X86_SPEC_CTRL_H__
 
+#include <asm/alternative.h>
 #include <asm/current.h>
+#include <asm/msr-index.h>
 
 void init_speculation_mitigations(void);
 
@@ -31,6 +33,38 @@ static inline void init_shadow_spec_ctrl_state(void)
     info->shadow_spec_ctrl = info->use_shadow_spec_ctrl = 0;
 }
 
+/* WARNING! `ret`, `call *`, `jmp *` not safe after this call. */
+static always_inline void spec_ctrl_enter_idle(struct cpu_info *info)
+{
+    uint32_t val = 0;
+
+    /*
+     * Latch the new shadow value, then enable shadowing, then update the MSR.
+     * There are no SMP issues here; only local processor ordering concerns.
+     */
+    info->shadow_spec_ctrl = val;
+    barrier();
+    info->use_shadow_spec_ctrl = true;
+    barrier();
+    asm volatile (ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET)
+                  :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory");
+}
+
+/* WARNING! `ret`, `call *`, `jmp *` not safe before this call. */
+static always_inline void spec_ctrl_exit_idle(struct cpu_info *info)
+{
+    uint32_t val = SPEC_CTRL_IBRS;
+
+    /*
+     * Disable shadowing before updating the MSR.  There are no SMP issues
+     * here; only local processor ordering concerns.
+     */
+    info->use_shadow_spec_ctrl = false;
+    barrier();
+    asm volatile (ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET)
+                  :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory");
+}
+
 #endif /* !__X86_SPEC_CTRL_H__ */
 
 /*
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls
  2018-01-04  0:15 ` [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls Andrew Cooper
@ 2018-01-04  1:14   ` Doug Goldstein
  2018-01-04  1:16     ` Andrew Cooper
  2018-01-04  4:05     ` Anthony Liguori
  2018-01-04  9:42   ` Jan Beulich
  2018-01-04 18:51   ` Wei Liu
  2 siblings, 2 replies; 69+ messages in thread
From: Doug Goldstein @ 2018-01-04  1:14 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel


[-- Attachment #1.1.1: Type: text/plain, Size: 405 bytes --]

On 1/3/18 6:15 PM, Andrew Cooper wrote:
> Contemporary processors are gaining Indirect Branch Controls via microcode
> updates.  Intel are introducing one bit to indicate IBRS and IBPB support, and
> a second bit for STIBP.  AMD are introducing IPBP only, so enumerate it with a
> separate bit.

s/IPBP/IBPB/ no? Still getting caught up here so I could certainly be wrong.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 981 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls
  2018-01-04  1:14   ` Doug Goldstein
@ 2018-01-04  1:16     ` Andrew Cooper
  2018-01-04  4:05     ` Anthony Liguori
  1 sibling, 0 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-04  1:16 UTC (permalink / raw)
  To: Doug Goldstein, Xen-devel


[-- Attachment #1.1.1: Type: text/plain, Size: 580 bytes --]

On 04/01/2018 01:14, Doug Goldstein wrote:
> On 1/3/18 6:15 PM, Andrew Cooper wrote:
>> Contemporary processors are gaining Indirect Branch Controls via microcode
>> updates.  Intel are introducing one bit to indicate IBRS and IBPB support, and
>> a second bit for STIBP.  AMD are introducing IPBP only, so enumerate it with a
>> separate bit.
> s/IPBP/IBPB/ no? Still getting caught up here so I could certainly be wrong.

Correct.  I'll add this to the fixup list.

I've lost count of how many times I've mis-typed or mixed these two
initialisms up :(

~Andrew


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 834 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls
  2018-01-04  1:14   ` Doug Goldstein
  2018-01-04  1:16     ` Andrew Cooper
@ 2018-01-04  4:05     ` Anthony Liguori
  1 sibling, 0 replies; 69+ messages in thread
From: Anthony Liguori @ 2018-01-04  4:05 UTC (permalink / raw)
  To: Doug Goldstein; +Cc: Andrew Cooper, Xen-devel

On Wed, Jan 3, 2018 at 5:14 PM, Doug Goldstein <cardoe@cardoe.com> wrote:
> On 1/3/18 6:15 PM, Andrew Cooper wrote:
>> Contemporary processors are gaining Indirect Branch Controls via microcode
>> updates.  Intel are introducing one bit to indicate IBRS and IBPB support, and
>> a second bit for STIBP.  AMD are introducing IPBP only, so enumerate it with a
>> separate bit.
>
> s/IPBP/IBPB/ no? Still getting caught up here so I could certainly be wrong.

IBPB is indeed right.

Regards,

Anthony Liguori

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

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 05/26] x86/entry: Remove support for partial cpu_user_regs frames
  2018-01-04  0:15 ` [PATCH v6.5 05/26] x86/entry: Remove support for partial cpu_user_regs frames Andrew Cooper
@ 2018-01-04  8:51   ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-04  8:51 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> Save all GPRs on entry to Xen.
> 
> The entry_int82() path is via a DPL1 gate, only usable by 32bit PV guests, so
> can get away with only saving the 32bit registers.  All other entrypoints can
> be reached from 32 or 64bit contexts.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Reviewed-by: Wei Liu <wei.liu2@citrix.com>

While I don't fully agree with outright removing the code, for it to
be able to go in
Acked-by: Jan Beulich <jbeulich@suse.com>

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 09/26] x86: Support compiling with indirect branch thunks
  2018-01-04  0:15 ` [PATCH v6.5 09/26] x86: Support compiling with indirect branch thunks Andrew Cooper
@ 2018-01-04  9:02   ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-04  9:02 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> Use -mindirect-branch=thunk-extern/-mindirect-branch-register when available.
> To begin with, use the retpoline thunk.  Later work will add alternative
> thunks which can be selected at boot time.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

For the sake of completeness I'm going to reproduce my v6
comments here which weren't already addressed one way or the
other.

> --- a/xen/arch/x86/Rules.mk
> +++ b/xen/arch/x86/Rules.mk
> @@ -30,3 +30,10 @@ CFLAGS += -fno-asynchronous-unwind-tables
>  ifneq ($(call cc-option,$(CC),-fvisibility=hidden,n),n)
>  CFLAGS += -DGCC_HAS_VISIBILITY_ATTRIBUTE
>  endif
> +
> +# Compile with thunk-extern, indirect-branch-register if avaiable.
> +ifneq ($(call cc-option,$(CC),-mindirect-branch-register,n),n)

Why you don't use cc-option-add in favor of cc-option inside the
ifneq ()?

> +CFLAGS += -mindirect-branch=thunk-extern -mindirect-branch-register
> +CFLAGS += -DCONFIG_INDIRECT_THUNK
> +export CONFIG_INDIRECT_THUNK=y

Perhaps it would be better (more consistent) to make this a normal
config option, with the help text saying that enabling it requires a
capable compiler.

> --- /dev/null
> +++ b/xen/arch/x86/indirect_thunk.S

From the purely cosmetic angle, personally I would have preferred
indirect-thunk.S as a file name.

> @@ -0,0 +1,28 @@
> +#include <asm/asm_defns.h>
> +
> +.macro IND_THUNK_RETPOLINE reg:req
> +        call 2f
> +1:
> +        lfence
> +        jmp 1b
> +2:
> +        mov \reg, (%rsp)
> +        ret
> +.endm
> +
> +/*
> + * Build the __x86.indirect_thunk.* symbols.  Execution lands on an
> + * alternative patch point which implements one of the above THUNK_*'s
> + */
> +.macro GEN_INDIRECT_THUNK name:req reg:req
> +        .section .text.__x86.indirect_thunk.\name, "ax", @progbits
> +
> +ENTRY(__x86.indirect_thunk.\name)
> +        IND_THUNK_RETPOLINE \reg
> +.endm

I don't see why this needs two parameters:

.macro GEN_INDIRECT_THUNK name:req
        .section .text.__x86.indirect_thunk.\name, "ax", @progbits

ENTRY(__x86.indirect_thunk.\name)
        IND_THUNK_RETPOLINE %\name
.endm

or even push the addition of the % down into IND_THUNK_RETPOLINE.

I also don't see the need for the double underscores in the section
name - I think just .text.\name would suffice.

> +/* Instantiate GEN_INDIRECT_THUNK for each register except %rsp. */
> +.irp enc, rax, rbx, rcx, rdx, rsi, rdi, rbp, \
> +          r8, r9, r10, r11, r12, r13, r14, r15

Again purely cosmetic: Preferably these would be sorted either
by encoding value (my preference) or alphabetically. Personally
I would also have dropped the recurring r-s from here, adding
them upon use of the parameter (which with the earlier comment
would be exactly one instance).

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code
  2018-01-04  0:15 ` [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code Andrew Cooper
@ 2018-01-04  9:23   ` Jan Beulich
  2018-01-08 18:24     ` Andrew Cooper
  2018-01-11 13:03   ` David Woodhouse
  1 sibling, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2018-01-04  9:23 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/boot/trampoline.S
> +++ b/xen/arch/x86/boot/trampoline.S
> @@ -153,8 +153,28 @@ trampoline_protmode_entry:
>          .code64
>  start64:
>          /* Jump to high mappings. */
> -        movabs  $__high_start,%rax
> -        jmpq    *%rax
> +        movabs  $__high_start, %rdi
> +
> +#ifdef CONFIG_INDIRECT_THUNK
> +        /*
> +         * If booting virtualised, or hot-onlining a CPU, sibling threads can
> +         * attempt Branch Target Injection against this jmp.
> +         *
> +         * We've got no usable stack so can't use a RETPOLINE thunk, and are
> +         * further than +- 2G from the high mappings so couldn't use JUMP_THUNK
> +         * even if was a non-RETPOLINE thunk.  Futhermore, an LFENCE isn't
> +         * necesserily safe to use at this point.
> +         *
> +         * As this isn't a hotpath, use a fully serialising event to reduce
> +         * the speculation window as much as possible.  %ebx needs preserving
> +         * for __high_start.
> +         */
> +        mov     %ebx, %esi
> +        cpuid
> +        mov     %esi, %ebx
> +#endif
> +
> +        jmpq    *%rdi

Would there be anything wrong with omitting the #ifdef, slightly
improving readability?

> --- a/xen/arch/x86/pv/emul-priv-op.c
> +++ b/xen/arch/x86/pv/emul-priv-op.c
> @@ -73,37 +73,58 @@ void (*pv_post_outb_hook)(unsigned int port, u8 value);
>  
>  typedef void io_emul_stub_t(struct cpu_user_regs *);
>  
> +#ifdef CONFIG_INDIRECT_THUNK
> +extern char ind_thunk_rcx[] asm ("__x86.indirect_thunk.rcx");
> +#endif

Again I don't see the value of the #ifdef.

>  static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode,
>                                            unsigned int port, unsigned int bytes)
>  {
> +    struct stubs *this_stubs = &this_cpu(stubs);
> +    unsigned long stub_va = this_stubs->addr + STUB_BUF_SIZE / 2;
> +
>      if ( !ctxt->io_emul_stub )
> -        ctxt->io_emul_stub = map_domain_page(_mfn(this_cpu(stubs.mfn))) +
> -                                             (this_cpu(stubs.addr) &
> -                                              ~PAGE_MASK) +
> -                                             STUB_BUF_SIZE / 2;
> +        ctxt->io_emul_stub =
> +            map_domain_page(_mfn(this_stubs->mfn)) + (stub_va & ~PAGE_MASK);
>  
>      /* movq $host_to_guest_gpr_switch,%rcx */
>      ctxt->io_emul_stub[0] = 0x48;
>      ctxt->io_emul_stub[1] = 0xb9;
>      *(void **)&ctxt->io_emul_stub[2] = (void *)host_to_guest_gpr_switch;
> +
> +#ifdef CONFIG_INDIRECT_THUNK
> +    /* callq __x86.indirect_thunk.rcx */
> +    ctxt->io_emul_stub[10] = 0xe8;
> +    *(int32_t *)&ctxt->io_emul_stub[11] =
> +        _p(ind_thunk_rcx) - _p(stub_va + 11 + 4);

Why two (hidden) casts when one (clearly visible one) would do:

    *(int32_t *)&ctxt->io_emul_stub[11] =
        (unsigned long)ind_thunk_rcx - (stub_va + 11 + 4);

?

> +#else
>      /* callq *%rcx */
>      ctxt->io_emul_stub[10] = 0xff;
>      ctxt->io_emul_stub[11] = 0xd1;
> +
> +    /*
> +     * 3 bytes of P6_NOPS.
> +     * TODO: untangle ideal_nops from init/livepatch Kconfig options.
> +     */
> +    memcpy(&ctxt->io_emul_stub[12], "\x0f\x1f\x00", 3);
> +#endif

Same here - rather than making everything more complicated to
read/understand, why don't we avoid conditionals in places where
performance is of no concern. In the end it may well be that we
wouldn't need CONFIG_INDIRECT_THUNK at all, unless it became
a user-selectable option (as suggested in reply to patch 9).

> --- a/xen/include/asm-x86/asm_defns.h
> +++ b/xen/include/asm-x86/asm_defns.h
> @@ -13,6 +13,14 @@
>  #include <asm/cpufeature.h>
>  #include <asm/alternative.h>
>  
> +#ifdef __ASSEMBLY__
> +# include <asm/indirect_thunk_asm.h>
> +#else
> +asm ( "\t.equ CONFIG_INDIRECT_THUNK, "
> +      __stringify(IS_ENABLED(CONFIG_INDIRECT_THUNK)) );
> +asm ( "\t.include \"asm/indirect_thunk_asm.h\"" );
> +#endif

For this to work with all compilers, aren't you still missing the
addition of -Wa,-I$(BASEDIR)/include on top of the other
compiler option additions done in patch 9?

> --- /dev/null
> +++ b/xen/include/asm-x86/indirect_thunk_asm.h
> @@ -0,0 +1,41 @@
> +/*
> + * Warning!  This file is included at an assembler level for .c files, causing
> + * usual #ifdef'ary to turn into comments.
> + */
> +
> +.macro IND_THUNK insn:req arg:req
> +/*
> + * Create an indirect branch.  insn is one of call/jmp, arg is a single
> + * register.
> + *
> + * With no compiler support, this degrated into a plain indirect call/jmp.

"degrades" or "degenerates" or yet something else?

> + * With compiler support, dispatch to the correct __x86.indirect_thunk.*
> + */
> +    .if CONFIG_INDIRECT_THUNK == 1

If we really want/need to keep this config option, why not without
the "== 1"?

> +        $done = 0
> +        .irp reg, rax, rbx, rcx, rdx, rsi, rdi, rbp, r8, r9, r10, r11, r12, r13, r14, r15

Same cosmetic remark as earlier regarding the ordering and the
possible omission of the r-s here.

Jan

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 12/26] x86/boot: Report details of speculative mitigations
  2018-01-04  0:15 ` [PATCH v6.5 12/26] x86/boot: Report details of speculative mitigations Andrew Cooper
@ 2018-01-04  9:29   ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-04  9:29 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> Nothing very interesting at the moment, but the logic will grow as new
> mitigations are added.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

Acked-by: Jan Beulich <jbeulich@suse.com>

init_speculation_mitigations() looks to be far more involved than it
needs to be at this point, but I see this sort of justified by the
additions in patch 14.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 13/26] x86/amd: Try to set lfence as being Dispatch Serialising
  2018-01-04  0:15 ` [PATCH v6.5 13/26] x86/amd: Try to set lfence as being Dispatch Serialising Andrew Cooper
@ 2018-01-04  9:32   ` Jan Beulich
  2018-01-08 19:01     ` Andrew Cooper
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2018-01-04  9:32 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/cpu/amd.c
> +++ b/xen/arch/x86/cpu/amd.c
> @@ -558,8 +558,41 @@ static void init_amd(struct cpuinfo_x86 *c)
>  			wrmsr_amd_safe(0xc001100d, l, h & ~1);
>  	}
>  
> +	/*
> +	 * Attempt to set lfence to be Dispatch Serialising.  This MSR almost
> +	 * certainly isn't virtualised (and Xen at least will leak the real
> +	 * value in but silently discard writes), as well as being per-core
> +	 * rather than per-thread, so do a full safe read/write/readback cycle
> +	 * in the worst case.
> +	 */
> +	if (c->x86 == 0x0f || c->x86 == 0x11)
> +		/* Always dispatch serialising on this hardare. */
> +		__set_bit(X86_FEATURE_LFENCE_DISPATCH, c->x86_capability);
> +	else if (c->x86 == 0x10 || c->x86 >= 0x12) {

I think this could be just "else", as models below 0xf aren't 64-bit
capable. Anyway
Reviewed-by: Jan Beulich <jbeulich@suse.com>

For completeness I'm also reproducing an earlier remark I made:
A question though is whether it is a good idea to set the MSR
bit unconditionally. For example, with "bti=" being given other
than "lfence", it seems quite pointless to impact guest (and
in particular user mode) code by making LFENCE dispatch
serializing. Otoh a valid question is whether LFENCE is being
used much for purposes other than the one here.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 14/26] x86: Introduce alternative indirect thunks
  2018-01-04  0:15 ` [PATCH v6.5 14/26] x86: Introduce alternative indirect thunks Andrew Cooper
@ 2018-01-04  9:40   ` Jan Beulich
  2018-01-09 11:44     ` Andrew Cooper
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2018-01-04  9:40 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> --- a/docs/misc/xen-command-line.markdown
> +++ b/docs/misc/xen-command-line.markdown
> @@ -245,6 +245,20 @@ and not running softirqs. Reduce this if softirqs are not being run frequently
>  enough. Setting this to a high value may cause boot failure, particularly if
>  the NMI watchdog is also enabled.
>  
> +### bti (x86)
> +> `= List of [ thunk=retpoline|lfence|plain ]`
> +
> +Branch Target Injection controls.  By default, Xen will pick the most
> +appropriate BTI mitigations based on compiled in support, loaded microcode,
> +and hardware details.
> +
> +**WARNING: Any use of this option inhibits all heristcs.  Use with extreme care.**

"heuristics"

> @@ -27,7 +28,42 @@ enum ind_thunk {
>      THUNK_NONE,    /* Missing compiler support for thunks. */
>  
>      THUNK_RETPOLINE,
> -};
> +    THUNK_LFENCE,
> +    THUNK_JMP,
> +} opt_thunk __initdata = THUNK_DEFAULT;

This wants to be static.

> @@ -48,6 +86,31 @@ void __init init_speculation_mitigations(void)
>      enum ind_thunk thunk = THUNK_DEFAULT;
>  
>      /*
> +     * Has the user specified any custom BTI mitigations?  If so, follow their
> +     * instructions exactly and disable all heuristics.
> +     */
> +    if ( opt_thunk != THUNK_DEFAULT )
> +    {
> +        thunk = opt_thunk;
> +    }

The braces aren't really needed here.

> +    else
> +    {
> +        /*
> +         * Evaluate the safest Branch Target Injection mitigations to use.
> +         * First, begin with compiler-aided mitigations.
> +         */
> +        if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) )
> +        {
> +            /*
> +             * AMD's recommended mitigation is to set lfence as being dispatch
> +             * serialising, and to use IND_THUNK_LFENCE.
> +             */
> +            if ( cpu_has_lfence_dispatch )
> +                thunk = THUNK_LFENCE;
> +        }
> +    }

As asked elsewhere, is the CONFIG_INDIRECT_THUNK dependency
here really meaningful for the overall effect? Surely if we can't use
thunks in the first place it doesn't matter which variant of them we
don't use?

Anyway, with at least the first two remarks taken care of
Reviewed-by: Jan Beulich <jbeulich@suse.com>

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls
  2018-01-04  0:15 ` [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls Andrew Cooper
  2018-01-04  1:14   ` Doug Goldstein
@ 2018-01-04  9:42   ` Jan Beulich
  2018-01-04 18:51   ` Wei Liu
  2 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-04  9:42 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> Contemporary processors are gaining Indirect Branch Controls via microcode
> updates.  Intel are introducing one bit to indicate IBRS and IBPB support, and
> a second bit for STIBP.  AMD are introducing IPBP only, so enumerate it with a
> separate bit.
> 
> Furthermore, depending on compiler and microcode availability, we may want to
> run Xen with IBRS set, or clear.
> 
> To use these facilities, we synthesise separate IBRS and IBPB bits for
> internal use.  A lot of infrastructure is required before these features are
> safe to offer to guests.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

As before
Reviewed-by: Jan Beulich <jbeulich@suse.com>
despite my dislike of ...

> --- a/xen/include/asm-x86/msr-index.h
> +++ b/xen/include/asm-x86/msr-index.h
> @@ -31,6 +31,17 @@
>  #define EFER_LMSLE		(1<<_EFER_LMSLE)
>  #define EFER_FFXSE		(1<<_EFER_FFXSE)
>  
> +/* Speculation Controls. */
> +#define MSR_SPEC_CTRL			0x00000048
> +#define _SPEC_CTRL_IBRS			0
> +#define SPEC_CTRL_IBRS			(_AC(1, ULL) << _SPEC_CTRL_IBRS)
> +#define _SPEC_CTRL_STIBP		1
> +#define SPEC_CTRL_STIBP			(_AC(1, ULL) << _SPEC_CTRL_STIBP)
> +
> +#define MSR_PRED_CMD			0x00000049
> +#define _PRED_CMD_IBPB			0
> +#define PRED_CMD_IBPB			(_AC(1, ULL) << _PRED_CMD_IBPB)

... the further introduction of reserved names here (I do
realize this is consistent with other names in this file, but
anyway).

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 16/26] x86/cmdline: Introduce a command line option to disable IBRS/IBPB, STIBP and IBPB
  2018-01-04  0:15 ` [PATCH v6.5 16/26] x86/cmdline: Introduce a command line option to disable IBRS/IBPB, STIBP and IBPB Andrew Cooper
@ 2018-01-04  9:43   ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-04  9:43 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> Instead of gaining yet another top level boolean, introduce a more generic
> cpuid= option.  Also introduce a helper function to parse a generic boolean
> value.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

As before
Reviewed-by: Jan Beulich <jbeulich@suse.com>



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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD}
  2018-01-04  0:15 ` [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD} Andrew Cooper
@ 2018-01-04  9:52   ` Jan Beulich
  2018-01-09 12:03     ` Andrew Cooper
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2018-01-04  9:52 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> @@ -292,6 +301,16 @@ static int update_domain_cpuid_info(struct domain *d,
>              d->arch.pv_domain.cpuidmasks->e1cd = mask;
>          }
>          break;
> +
> +    case 0x80000008:
> +        /*
> +         * If the IBRB policy has changed, we need to recalculate the MSR
> +         * interception bitmaps.
> +         */
> +        call_policy_changed = (is_hvm_domain(d) &&
> +                               ((old_e8b ^ p->extd.raw[8].b) &
> +                                (cpufeat_mask(X86_FEATURE_IBPB))));

There's a stray pair of parentheses here.

> --- a/xen/arch/x86/msr.c
> +++ b/xen/arch/x86/msr.c
> @@ -132,7 +132,8 @@ int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
>      case MSR_SPEC_CTRL:
>          if ( !cp->feat.ibrsb )
>              goto gp_fault;
> -        *val = vp->spec_ctrl.guest;
> +        *val = (vp->spec_ctrl.direct_access
> +                ? vp->spec_ctrl.host : vp->spec_ctrl.guest);
>          break;

To recap, I had asked whether this is valid ahead of later changes,
which you replied to saying this won't have any "by not permitting
the guest any access until patch 25". In which case at the very
least the patch title is misleading. Yet I don't even agree with what
you say - patch 25 only fiddles with CPUID bits. Did you perhaps
mean to say "By not permitting a well behaved guest any access
until patch 25," as one trying to access the MSRs without consulting
the CPUID bits would be able to starting with the patch here aiui?

I do realize that re-ordering the series may be impossible, so I'm
not necessarily asking for a code change. But at least the
description should explain the situation.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 20/26] x86: Protect unaware domains from meddling hyperthreads
  2018-01-04  0:15 ` [PATCH v6.5 20/26] x86: Protect unaware domains from meddling hyperthreads Andrew Cooper
@ 2018-01-04  9:59   ` Jan Beulich
  2018-01-09 14:21     ` Andrew Cooper
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2018-01-04  9:59 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

Fundamentally (as before)
Reviewed-by: Jan Beulich <jbeulich@suse.com>
However:

> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -2027,6 +2027,25 @@ int domain_relinquish_resources(struct domain *d)
>   */
>  void cpuid_policy_updated(struct vcpu *v)
>  {
> +    const struct cpuid_policy *cp = v->domain->arch.cpuid;
> +    struct msr_vcpu_policy *vp = v->arch.msr;
> +
> +    /*
> +     * For guests which know about IBRS but are not told about STIBP running
> +     * on hardware supporting hyperthreading, the guest doesn't know to
> +     * protect itself fully.  (Such a guest won't be permitted direct access
> +     * to the MSR.)  Have Xen fill in the gaps, so an unaware guest can't be
> +     * interfered with by a meddling guest on an adjacent hyperthread.
> +     */
> +    if ( cp->feat.ibrsb )
> +    {
> +        if ( !cp->feat.stibp && cpu_has_stibp &&
> +             !(vp->spec_ctrl.guest & (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP)) )
> +            vp->spec_ctrl.host = SPEC_CTRL_STIBP;
> +        else
> +            vp->spec_ctrl.host = vp->spec_ctrl.guest;

This code is so similar to ...

> --- a/xen/arch/x86/msr.c
> +++ b/xen/arch/x86/msr.c
> @@ -181,7 +181,20 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
>                       (cp->feat.stibp ? SPEC_CTRL_STIBP : 0)) )
>              goto gp_fault; /* Rsvd bit set? */
>          vp->spec_ctrl.guest = val;
> -        vp->spec_ctrl.host  = val;
> +
> +        /*
> +         * For guests which are not told about STIBP, running on hardware
> +         * supporting hyperthreading, the guest doesn't know to protect itself
> +         * fully.  (Such a guest won't be permitted direct access to the MSR.)
> +         * When IBRS is not in force, have Xen fill in the gaps, so an unaware
> +         * guest can't be interfered with by a meddling guest on an adjacent
> +         * hyperthread.
> +         */
> +        if ( !cp->feat.stibp && cpu_has_stibp &&
> +             !(val & (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP)) )
> +            vp->spec_ctrl.host = SPEC_CTRL_STIBP;
> +        else
> +            vp->spec_ctrl.host = val;

... this that I think a helper function would be warranted, unless you
have reasons to believe that future changes might break the
similarity.

I'm also a little puzzled by you checking SPEC_CTRL_STIBP there -
this bit ought to be clear when !cp->feat.stibp due to the earlier
reserved bit check (part of which is even visible in context above).
IOW the check is not wrong, but perhaps misleading. You had
replied to this remark with

"The SPEC_CTRL_STIBP check exists solely because of v3 review which
 objected to me implying a link between IBRS and STIPB."

I'm afraid I don't understand, for two reasons:

1) The change to guest_wrmsr() is the same here as it was in v3.
The difference is that now the change to cpuid_policy_updated()
is rather more similar to that to guest_wrmsr().

2) Going through the mails I've sent, it must have been review
comments by someone else, which I didn't get to see. Hence I
understand neither the context nor the reasons.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 21/26] x86/entry: Use MSR_SPEC_CTRL at each entry/exit point
  2018-01-04  0:15 ` [PATCH v6.5 21/26] x86/entry: Use MSR_SPEC_CTRL at each entry/exit point Andrew Cooper
@ 2018-01-04 10:14   ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-04 10:14 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> Set or clear IBRS in Xen context, and appropriate guest values in guest
> context.  See the documentation in asm-x86/spec_ctrl_asm.h for details.

I think this is misleading - there is no setting or clearing in Xen context
here, as the controlling features (X86_FEATURE_XEN_IBRS_{SET,CLEAR})
get set only in the next patch.

> --- a/xen/include/asm-x86/asm_defns.h
> +++ b/xen/include/asm-x86/asm_defns.h
> @@ -7,6 +7,7 @@
>  #include <asm/asm-offsets.h>
>  #endif
>  #include <asm/bug.h>
> +#include <asm/page.h>
>  #include <asm/processor.h>
>  #include <asm/percpu.h>
>  #include <xen/stringify.h>
> @@ -344,4 +345,6 @@ static always_inline void stac(void)
>  #define REX64_PREFIX "rex64/"
>  #endif
>  
> +#include <asm/spec_ctrl_asm.h>

Why do all consumers of asm_defns.h need to also see the
definitions that other header holds? If there are include ordering
issues, can't interested .c and/or .S files include that other
header first? In fact I have a patch pending (in a yet to be
finished series) which does that for processor.h: It shouldn't
really be included by this header, as nothing in here needs
anything out of there (the things needed live in x86-defns.h).

> --- a/xen/include/asm-x86/nops.h
> +++ b/xen/include/asm-x86/nops.h
> @@ -50,7 +50,7 @@
>  #define P6_NOP9 0x66,0x0f,0x1f,0x84,0x00,0,0,0,0
>  
>  #ifdef __ASSEMBLY__
> -#define _ASM_MK_NOP(x) .byte x
> +#define _ASM_MK_NOP(x) .byte x;

Imo the semicolon doesn't belong here, but ...

> @@ -65,6 +65,12 @@
>  #define ASM_NOP8 _ASM_MK_NOP(P6_NOP8)
>  #define ASM_NOP9 _ASM_MK_NOP(P6_NOP9)
>  
> +#define ASM_NOP22 ASM_NOP8 ASM_NOP8 ASM_NOP6
> +#define ASM_NOP26 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP2
> +#define ASM_NOP32 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8
> +#define ASM_NOP33 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP7 ASM_NOP2
> +#define ASM_NOP39 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP7

... here (between the elements, matching e.g. ASM_AC() and
CR4_PV32_RESTORE).

If you really want to keep introducing these (instead of the - imo -
much more clean use of suitable .skip in the macros, as is being
done in the 32-bit PV SMEP/SMAP handling), please at least use
ASM_NOP9 here as far as possible.

> +.macro DO_SPEC_CTRL_ENTRY_FROM_VMEXIT ibrs_val:req
> +/*
> + * Requires %rbx=current, %rsp=regs/cpuinfo
> + * Clobbers %rax, %rcx, %rdx
> + *
> + * The common case is that a guest has direct access to MSR_SPEC_CTRL, at
> + * which point we need to save the guest value before setting IBRS for Xen.
> + * Unilaterally saving the guest value is shorter and faster than checking.
> + */
> +    mov $MSR_SPEC_CTRL, %ecx
> +    rdmsr
> +
> +    /* Stash the value from hardware. */
> +    mov VCPU_arch_msr(%rbx), %rdx
> +    mov %al, VCPUMSR_spec_ctrl_host(%rdx)
> +    xor %edx, %edx
> +
> +    /* Clear SPEC_CTRL shadowing *before* loading Xen's value. */
> +    movb %dl, CPUINFO_use_shadow_spec_ctrl(%rsp)
> +
> +    /* Load Xen's indented value. */

"intended" (also another time below)?

> +.macro DO_SPEC_CTRL_ENTRY maybexen:req ibrs_val:req
> +/*
> + * Requires %rsp=regs (also cpuinfo if !maybexen)
> + * Clobbers %rax, %rcx, %rdx
> + *
> + * PV guests can't update MSR_SPEC_CTRL behind Xen's back, so no need to read
> + * it back.  Entries from guest context need to clear SPEC_CTRL shadowing,
> + * while entries from Xen must leave shadowing in its current state.
> + */
> +    mov $MSR_SPEC_CTRL, %ecx
> +
> +    .if \maybexen
> +        cmpl $__HYPERVISOR_CS, UREGS_cs(%rsp)

Perhaps better "cmpw", and if you're afraid of the length changing
prefix decode stall, then use an intermediate register.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 22/26] x86/boot: Calculate the most appropriate BTI mitigation to use
  2018-01-04  0:15 ` [PATCH v6.5 22/26] x86/boot: Calculate the most appropriate BTI mitigation to use Andrew Cooper
@ 2018-01-04 10:17   ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-04 10:17 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> @@ -31,11 +32,12 @@ enum ind_thunk {
>      THUNK_LFENCE,
>      THUNK_JMP,
>  } opt_thunk __initdata = THUNK_DEFAULT;
> +int opt_ibrs __initdata = -1;

static

> @@ -147,6 +230,18 @@ void __init init_speculation_mitigations(void)
>      else if ( thunk == THUNK_JMP )
>          setup_force_cpu_cap(X86_FEATURE_IND_THUNK_JMP);
>  
> +    /*
> +     * Even if we've chosen not to use IBRS for Xen itself, we still need the
> +     * IBRS entry/exit logic to virtualise IBRS support for guests.
> +     */
> +    if ( boot_cpu_has(X86_FEATURE_IBRSB) )
> +    {
> +        if ( ibrs )
> +            setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_SET);
> +        else
> +            setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_CLEAR);
> +    }

You've already indicated you would try to change the comment,
for it to not be misleading the way it's currently placed.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 23/26] x86/entry: Clobber the Return Stack Buffer on entry to Xen
  2018-01-04  0:15 ` [PATCH v6.5 23/26] x86/entry: Clobber the Return Stack Buffer on entry to Xen Andrew Cooper
@ 2018-01-04 10:22   ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-04 10:22 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> --- a/docs/misc/xen-command-line.markdown
> +++ b/docs/misc/xen-command-line.markdown
> @@ -246,7 +246,7 @@ enough. Setting this to a high value may cause boot failure, particularly if
>  the NMI watchdog is also enabled.
>  
>  ### bti (x86)
> -> `= List of [ thunk=retpoline|lfence|plain, ibrs=<bool> ]`
> +> `= List of [ thunk=retpoline|lfence|plain, ibrs=<bool>, rsb_{vmexit,native}=bool ]`

<bool>

> --- a/xen/arch/x86/spec_ctrl.c
> +++ b/xen/arch/x86/spec_ctrl.c
> @@ -33,6 +33,7 @@ enum ind_thunk {
>      THUNK_JMP,
>  } opt_thunk __initdata = THUNK_DEFAULT;
>  int opt_ibrs __initdata = -1;
> +int opt_rsb_native __initdata = -1, opt_rsb_vmexit __initdata = -1;

static

> --- a/xen/include/asm-x86/nops.h
> +++ b/xen/include/asm-x86/nops.h
> @@ -67,9 +67,11 @@
>  
>  #define ASM_NOP22 ASM_NOP8 ASM_NOP8 ASM_NOP6
>  #define ASM_NOP26 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP2
> +#define ASM_NOP27 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP3
>  #define ASM_NOP32 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8
>  #define ASM_NOP33 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP7 ASM_NOP2
>  #define ASM_NOP39 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP7
> +#define ASM_NOP40 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8 ASM_NOP8

See how this is getting more and more ugly?

> @@ -178,6 +209,11 @@
>  
>  /* Use after a VMEXIT from an HVM guest. */
>  #define SPEC_CTRL_ENTRY_FROM_VMEXIT                                     \
> +    ALTERNATIVE_2 __stringify(ASM_NOP27),                               \
> +        "DO_OVERWRITE_RSB maybexen=0 ss=1",                             \
> +        X86_FEATURE_RSB_VMEXIT_SS,                                      \
> +        "DO_OVERWRITE_RSB maybexen=0 ss=0",                             \
> +        X86_FEATURE_RSB_VMEXIT;                                         \
>      ALTERNATIVE_2 __stringify(ASM_NOP32),                               \
>          __stringify(DO_SPEC_CTRL_ENTRY_FROM_VMEXIT                      \
>                      ibrs_val=SPEC_CTRL_IBRS),                           \

The use of __stringify() wants to become consistent: Either you
never use plain quoting, or you only ever use __stringify() when
plain quoting wouldn't yield the intended effect (of, in particular,
macro expansion before stringification).

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 24/26] x86/ctxt: Issue a speculation barrier between vcpu contexts
  2018-01-04  0:15 ` [PATCH v6.5 24/26] x86/ctxt: Issue a speculation barrier between vcpu contexts Andrew Cooper
@ 2018-01-04 10:25   ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-04 10:25 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/spec_ctrl.c
> +++ b/xen/arch/x86/spec_ctrl.c
> @@ -32,7 +32,7 @@ enum ind_thunk {
>      THUNK_LFENCE,
>      THUNK_JMP,
>  } opt_thunk __initdata = THUNK_DEFAULT;
> -int opt_ibrs __initdata = -1;
> +int opt_ibrs __initdata = -1, opt_ibpb __initdata = -1;

static, but see below.

> --- a/xen/include/asm-x86/cpufeature.h
> +++ b/xen/include/asm-x86/cpufeature.h
> @@ -109,6 +109,7 @@
>  #define cpu_has_aperfmperf      boot_cpu_has(X86_FEATURE_APERFMPERF)
>  #define cpu_has_xen_smep        boot_cpu_has(X86_FEATURE_XEN_SMEP)
>  #define cpu_has_lfence_dispatch boot_cpu_has(X86_FEATURE_LFENCE_DISPATCH)
> +#define cpu_has_xen_ibpb        boot_cpu_has(X86_FEATURE_XEN_IBPB)

Upon second look I'm actually not convinced using a CPU feature
flag here is warranted: You don't key any patching off of it,
so simply making opt_ibpb global (and non-init) should suffice. I
do realize that this would mean a change to an earlier patch.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 26/26] x86/idle: Clear SPEC_CTRL while idle
  2018-01-04  0:15 ` [PATCH v6.5 26/26] x86/idle: Clear SPEC_CTRL while idle Andrew Cooper
@ 2018-01-04 10:29   ` Jan Beulich
  2018-01-04 10:41   ` Jan Beulich
  1 sibling, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-04 10:29 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> On contemporary hardware, setting IBRS/STIBP has a performance impact on
> adjacent hyperthreads.  It is therefore recommended to clear the setting
> before becoming idle, to avoid an idle core preventing adjacent userspace
> execution from running at full performance.
> 
> Care must be taken to ensure there are no ret or indirect branch instructions
> between spec_ctrl_{enter,exit}_idle() invocations, which are forced always
> inline.  Care must also be taken to avoid using spec_ctrl_enter_idle() between
> flushing caches and becoming idle, in cases where that matters.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>
with one remark:

> @@ -31,6 +33,38 @@ static inline void init_shadow_spec_ctrl_state(void)
>      info->shadow_spec_ctrl = info->use_shadow_spec_ctrl = 0;
>  }
>  
> +/* WARNING! `ret`, `call *`, `jmp *` not safe after this call. */
> +static always_inline void spec_ctrl_enter_idle(struct cpu_info *info)
> +{
> +    uint32_t val = 0;
> +
> +    /*
> +     * Latch the new shadow value, then enable shadowing, then update the MSR.
> +     * There are no SMP issues here; only local processor ordering concerns.
> +     */
> +    info->shadow_spec_ctrl = val;
> +    barrier();
> +    info->use_shadow_spec_ctrl = true;
> +    barrier();
> +    asm volatile (ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET)
> +                  :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory");
> +}
> +
> +/* WARNING! `ret`, `call *`, `jmp *` not safe before this call. */
> +static always_inline void spec_ctrl_exit_idle(struct cpu_info *info)
> +{
> +    uint32_t val = SPEC_CTRL_IBRS;
> +
> +    /*
> +     * Disable shadowing before updating the MSR.  There are no SMP issues
> +     * here; only local processor ordering concerns.
> +     */
> +    info->use_shadow_spec_ctrl = false;
> +    barrier();
> +    asm volatile (ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET)
> +                  :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory");
> +}

The comments ahead of these new functions imply that we rely on
the compiler inlining all function calls inside the critical section - I
don't think there's any such guarantee, but I also don't see what
we can do about it. We may want to change some "inline" to
"always_inline" though (we've already worked out that this would
appear to only affect inb() and inl() in io.h; the R-b stands with
that addition).

Jan



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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 26/26] x86/idle: Clear SPEC_CTRL while idle
  2018-01-04  0:15 ` [PATCH v6.5 26/26] x86/idle: Clear SPEC_CTRL while idle Andrew Cooper
  2018-01-04 10:29   ` Jan Beulich
@ 2018-01-04 10:41   ` Jan Beulich
  1 sibling, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-04 10:41 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
> @@ -31,6 +33,38 @@ static inline void init_shadow_spec_ctrl_state(void)
>      info->shadow_spec_ctrl = info->use_shadow_spec_ctrl = 0;
>  }
>  
> +/* WARNING! `ret`, `call *`, `jmp *` not safe after this call. */
> +static always_inline void spec_ctrl_enter_idle(struct cpu_info *info)
> +{
> +    uint32_t val = 0;
> +
> +    /*
> +     * Latch the new shadow value, then enable shadowing, then update the MSR.
> +     * There are no SMP issues here; only local processor ordering concerns.
> +     */
> +    info->shadow_spec_ctrl = val;
> +    barrier();
> +    info->use_shadow_spec_ctrl = true;
> +    barrier();
> +    asm volatile (ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET)
> +                  :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory");

Missing blanks immediately inside the outermost parentheses (also
another time further down).

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls
  2018-01-04  0:15 ` [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls Andrew Cooper
  2018-01-04  1:14   ` Doug Goldstein
  2018-01-04  9:42   ` Jan Beulich
@ 2018-01-04 18:51   ` Wei Liu
  2 siblings, 0 replies; 69+ messages in thread
From: Wei Liu @ 2018-01-04 18:51 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Wei Liu, Xen-devel

On Thu, Jan 04, 2018 at 12:15:44AM +0000, Andrew Cooper wrote:
> Contemporary processors are gaining Indirect Branch Controls via microcode
> updates.  Intel are introducing one bit to indicate IBRS and IBPB support, and
> a second bit for STIBP.  AMD are introducing IPBP only, so enumerate it with a
> separate bit.
> 
> Furthermore, depending on compiler and microcode availability, we may want to
> run Xen with IBRS set, or clear.
> 
> To use these facilities, we synthesise separate IBRS and IBPB bits for
> internal use.  A lot of infrastructure is required before these features are
> safe to offer to guests.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> v4:
>  * Update for AMD, drop acks/reviews.
> ---
>  tools/libxl/libxl_cpuid.c                   |  3 +++
>  tools/misc/xen-cpuid.c                      | 12 ++++++++++--

Acked-by: Wei Liu <wei.liu2@citrix.com>

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code
  2018-01-04  9:23   ` Jan Beulich
@ 2018-01-08 18:24     ` Andrew Cooper
  2018-01-09  8:36       ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-08 18:24 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 04/01/18 09:23, Jan Beulich wrote:
>>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
>> --- a/xen/arch/x86/boot/trampoline.S
>> +++ b/xen/arch/x86/boot/trampoline.S
>> @@ -153,8 +153,28 @@ trampoline_protmode_entry:
>>          .code64
>>  start64:
>>          /* Jump to high mappings. */
>> -        movabs  $__high_start,%rax
>> -        jmpq    *%rax
>> +        movabs  $__high_start, %rdi
>> +
>> +#ifdef CONFIG_INDIRECT_THUNK
>> +        /*
>> +         * If booting virtualised, or hot-onlining a CPU, sibling threads can
>> +         * attempt Branch Target Injection against this jmp.
>> +         *
>> +         * We've got no usable stack so can't use a RETPOLINE thunk, and are
>> +         * further than +- 2G from the high mappings so couldn't use JUMP_THUNK
>> +         * even if was a non-RETPOLINE thunk.  Futhermore, an LFENCE isn't
>> +         * necesserily safe to use at this point.
>> +         *
>> +         * As this isn't a hotpath, use a fully serialising event to reduce
>> +         * the speculation window as much as possible.  %ebx needs preserving
>> +         * for __high_start.
>> +         */
>> +        mov     %ebx, %esi
>> +        cpuid
>> +        mov     %esi, %ebx
>> +#endif
>> +
>> +        jmpq    *%rdi
> Would there be anything wrong with omitting the #ifdef, slightly
> improving readability?

Functionally, not, but I'm not convinced it would make anything better
either.

>
>> --- a/xen/arch/x86/pv/emul-priv-op.c
>> +++ b/xen/arch/x86/pv/emul-priv-op.c
>> @@ -73,37 +73,58 @@ void (*pv_post_outb_hook)(unsigned int port, u8 value);
>>  
>>  typedef void io_emul_stub_t(struct cpu_user_regs *);
>>  
>> +#ifdef CONFIG_INDIRECT_THUNK
>> +extern char ind_thunk_rcx[] asm ("__x86.indirect_thunk.rcx");
>> +#endif
> Again I don't see the value of the #ifdef.

This ifdef is strictly required.  asm ("__x86.indirect_thunk.rcx");
doesn't exist when building with an incapable toolchain.

>
>>  static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode,
>>                                            unsigned int port, unsigned int bytes)
>>  {
>> +    struct stubs *this_stubs = &this_cpu(stubs);
>> +    unsigned long stub_va = this_stubs->addr + STUB_BUF_SIZE / 2;
>> +
>>      if ( !ctxt->io_emul_stub )
>> -        ctxt->io_emul_stub = map_domain_page(_mfn(this_cpu(stubs.mfn))) +
>> -                                             (this_cpu(stubs.addr) &
>> -                                              ~PAGE_MASK) +
>> -                                             STUB_BUF_SIZE / 2;
>> +        ctxt->io_emul_stub =
>> +            map_domain_page(_mfn(this_stubs->mfn)) + (stub_va & ~PAGE_MASK);
>>  
>>      /* movq $host_to_guest_gpr_switch,%rcx */
>>      ctxt->io_emul_stub[0] = 0x48;
>>      ctxt->io_emul_stub[1] = 0xb9;
>>      *(void **)&ctxt->io_emul_stub[2] = (void *)host_to_guest_gpr_switch;
>> +
>> +#ifdef CONFIG_INDIRECT_THUNK
>> +    /* callq __x86.indirect_thunk.rcx */
>> +    ctxt->io_emul_stub[10] = 0xe8;
>> +    *(int32_t *)&ctxt->io_emul_stub[11] =
>> +        _p(ind_thunk_rcx) - _p(stub_va + 11 + 4);
> Why two (hidden) casts when one (clearly visible one) would do:
>
>     *(int32_t *)&ctxt->io_emul_stub[11] =
>         (unsigned long)ind_thunk_rcx - (stub_va + 11 + 4);
>
> ?
>
>> +#else
>>      /* callq *%rcx */
>>      ctxt->io_emul_stub[10] = 0xff;
>>      ctxt->io_emul_stub[11] = 0xd1;
>> +
>> +    /*
>> +     * 3 bytes of P6_NOPS.
>> +     * TODO: untangle ideal_nops from init/livepatch Kconfig options.
>> +     */
>> +    memcpy(&ctxt->io_emul_stub[12], "\x0f\x1f\x00", 3);
>> +#endif
> Same here - rather than making everything more complicated to
> read/understand, why don't we avoid conditionals in places where
> performance is of no concern.

Again, these are strictly required, because of ind_thunk_rcx[].

> In the end it may well be that we
> wouldn't need CONFIG_INDIRECT_THUNK at all, unless it became
> a user-selectable option (as suggested in reply to patch 9).
>
>> --- a/xen/include/asm-x86/asm_defns.h
>> +++ b/xen/include/asm-x86/asm_defns.h
>> @@ -13,6 +13,14 @@
>>  #include <asm/cpufeature.h>
>>  #include <asm/alternative.h>
>>  
>> +#ifdef __ASSEMBLY__
>> +# include <asm/indirect_thunk_asm.h>
>> +#else
>> +asm ( "\t.equ CONFIG_INDIRECT_THUNK, "
>> +      __stringify(IS_ENABLED(CONFIG_INDIRECT_THUNK)) );
>> +asm ( "\t.include \"asm/indirect_thunk_asm.h\"" );
>> +#endif
> For this to work with all compilers, aren't you still missing the
> addition of -Wa,-I$(BASEDIR)/include on top of the other
> compiler option additions done in patch 9?

Ah yes - I will fold that in.

>
>> --- /dev/null
>> +++ b/xen/include/asm-x86/indirect_thunk_asm.h
>> @@ -0,0 +1,41 @@
>> +/*
>> + * Warning!  This file is included at an assembler level for .c files, causing
>> + * usual #ifdef'ary to turn into comments.
>> + */
>> +
>> +.macro IND_THUNK insn:req arg:req
>> +/*
>> + * Create an indirect branch.  insn is one of call/jmp, arg is a single
>> + * register.
>> + *
>> + * With no compiler support, this degrated into a plain indirect call/jmp.
> "degrades" or "degenerates" or yet something else?

Degrades.

~Andrew

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 13/26] x86/amd: Try to set lfence as being Dispatch Serialising
  2018-01-04  9:32   ` Jan Beulich
@ 2018-01-08 19:01     ` Andrew Cooper
  2018-01-09  8:38       ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-08 19:01 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 04/01/18 09:32, Jan Beulich wrote:
>>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
>> --- a/xen/arch/x86/cpu/amd.c
>> +++ b/xen/arch/x86/cpu/amd.c
>> @@ -558,8 +558,41 @@ static void init_amd(struct cpuinfo_x86 *c)
>>  			wrmsr_amd_safe(0xc001100d, l, h & ~1);
>>  	}
>>  
>> +	/*
>> +	 * Attempt to set lfence to be Dispatch Serialising.  This MSR almost
>> +	 * certainly isn't virtualised (and Xen at least will leak the real
>> +	 * value in but silently discard writes), as well as being per-core
>> +	 * rather than per-thread, so do a full safe read/write/readback cycle
>> +	 * in the worst case.
>> +	 */
>> +	if (c->x86 == 0x0f || c->x86 == 0x11)
>> +		/* Always dispatch serialising on this hardare. */
>> +		__set_bit(X86_FEATURE_LFENCE_DISPATCH, c->x86_capability);
>> +	else if (c->x86 == 0x10 || c->x86 >= 0x12) {
> I think this could be just "else", as models below 0xf aren't 64-bit
> capable. Anyway
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
>
> For completeness I'm also reproducing an earlier remark I made:
> A question though is whether it is a good idea to set the MSR
> bit unconditionally. For example, with "bti=" being given other
> than "lfence", it seems quite pointless to impact guest (and
> in particular user mode) code by making LFENCE dispatch
> serializing. Otoh a valid question is whether LFENCE is being
> used much for purposes other than the one here.

I suppose it might be interesting for perf testing, but I can't think of
any reasonable command line for tweaking this.

uarch=no-lfence-dispatch ?

This is the best I can think of, but its not exactly great.

~Andrew

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code
  2018-01-08 18:24     ` Andrew Cooper
@ 2018-01-09  8:36       ` Jan Beulich
  2018-01-09 11:23         ` Andrew Cooper
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2018-01-09  8:36 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 08.01.18 at 19:24, <andrew.cooper3@citrix.com> wrote:
> On 04/01/18 09:23, Jan Beulich wrote:
>>>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
>>> --- a/xen/arch/x86/pv/emul-priv-op.c
>>> +++ b/xen/arch/x86/pv/emul-priv-op.c
>>> @@ -73,37 +73,58 @@ void (*pv_post_outb_hook)(unsigned int port, u8 value);
>>>  
>>>  typedef void io_emul_stub_t(struct cpu_user_regs *);
>>>  
>>> +#ifdef CONFIG_INDIRECT_THUNK
>>> +extern char ind_thunk_rcx[] asm ("__x86.indirect_thunk.rcx");
>>> +#endif
>> Again I don't see the value of the #ifdef.
> 
> This ifdef is strictly required.  asm ("__x86.indirect_thunk.rcx");
> doesn't exist when building with an incapable toolchain.

I don't understand - it's only a declaration. Without users, no
reference to the symbol will be put anywhere.

>>>  static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode,
>>>                                            unsigned int port, unsigned int bytes)
>>>  {
>>> +    struct stubs *this_stubs = &this_cpu(stubs);
>>> +    unsigned long stub_va = this_stubs->addr + STUB_BUF_SIZE / 2;
>>> +
>>>      if ( !ctxt->io_emul_stub )
>>> -        ctxt->io_emul_stub = map_domain_page(_mfn(this_cpu(stubs.mfn))) +
>>> -                                             (this_cpu(stubs.addr) &
>>> -                                              ~PAGE_MASK) +
>>> -                                             STUB_BUF_SIZE / 2;
>>> +        ctxt->io_emul_stub =
>>> +            map_domain_page(_mfn(this_stubs->mfn)) + (stub_va & ~PAGE_MASK);
>>>  
>>>      /* movq $host_to_guest_gpr_switch,%rcx */
>>>      ctxt->io_emul_stub[0] = 0x48;
>>>      ctxt->io_emul_stub[1] = 0xb9;
>>>      *(void **)&ctxt->io_emul_stub[2] = (void *)host_to_guest_gpr_switch;
>>> +
>>> +#ifdef CONFIG_INDIRECT_THUNK
>>> +    /* callq __x86.indirect_thunk.rcx */
>>> +    ctxt->io_emul_stub[10] = 0xe8;
>>> +    *(int32_t *)&ctxt->io_emul_stub[11] =
>>> +        _p(ind_thunk_rcx) - _p(stub_va + 11 + 4);
>> Why two (hidden) casts when one (clearly visible one) would do:
>>
>>     *(int32_t *)&ctxt->io_emul_stub[11] =
>>         (unsigned long)ind_thunk_rcx - (stub_va + 11 + 4);
>>
>> ?
>>
>>> +#else
>>>      /* callq *%rcx */
>>>      ctxt->io_emul_stub[10] = 0xff;
>>>      ctxt->io_emul_stub[11] = 0xd1;
>>> +
>>> +    /*
>>> +     * 3 bytes of P6_NOPS.
>>> +     * TODO: untangle ideal_nops from init/livepatch Kconfig options.
>>> +     */
>>> +    memcpy(&ctxt->io_emul_stub[12], "\x0f\x1f\x00", 3);
>>> +#endif
>> Same here - rather than making everything more complicated to
>> read/understand, why don't we avoid conditionals in places where
>> performance is of no concern.
> 
> Again, these are strictly required, because of ind_thunk_rcx[].

Oh, right, other than above here I agree in general. However, I
think I did suggest to unconditionally build the thunks as well - they
do no harm if unused.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 13/26] x86/amd: Try to set lfence as being Dispatch Serialising
  2018-01-08 19:01     ` Andrew Cooper
@ 2018-01-09  8:38       ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-09  8:38 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 08.01.18 at 20:01, <andrew.cooper3@citrix.com> wrote:
> On 04/01/18 09:32, Jan Beulich wrote:
>>>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
>>> --- a/xen/arch/x86/cpu/amd.c
>>> +++ b/xen/arch/x86/cpu/amd.c
>>> @@ -558,8 +558,41 @@ static void init_amd(struct cpuinfo_x86 *c)
>>>  			wrmsr_amd_safe(0xc001100d, l, h & ~1);
>>>  	}
>>>  
>>> +	/*
>>> +	 * Attempt to set lfence to be Dispatch Serialising.  This MSR almost
>>> +	 * certainly isn't virtualised (and Xen at least will leak the real
>>> +	 * value in but silently discard writes), as well as being per-core
>>> +	 * rather than per-thread, so do a full safe read/write/readback cycle
>>> +	 * in the worst case.
>>> +	 */
>>> +	if (c->x86 == 0x0f || c->x86 == 0x11)
>>> +		/* Always dispatch serialising on this hardare. */
>>> +		__set_bit(X86_FEATURE_LFENCE_DISPATCH, c->x86_capability);
>>> +	else if (c->x86 == 0x10 || c->x86 >= 0x12) {
>> I think this could be just "else", as models below 0xf aren't 64-bit
>> capable. Anyway
>> Reviewed-by: Jan Beulich <jbeulich@suse.com>
>>
>> For completeness I'm also reproducing an earlier remark I made:
>> A question though is whether it is a good idea to set the MSR
>> bit unconditionally. For example, with "bti=" being given other
>> than "lfence", it seems quite pointless to impact guest (and
>> in particular user mode) code by making LFENCE dispatch
>> serializing. Otoh a valid question is whether LFENCE is being
>> used much for purposes other than the one here.
> 
> I suppose it might be interesting for perf testing, but I can't think of
> any reasonable command line for tweaking this.
> 
> uarch=no-lfence-dispatch ?
> 
> This is the best I can think of, but its not exactly great.

I was actually meaning the MSR change to be tied to
existing options/decisions. But let's keep this for later.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code
  2018-01-09  8:36       ` Jan Beulich
@ 2018-01-09 11:23         ` Andrew Cooper
  2018-01-09 13:18           ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-09 11:23 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 09/01/18 08:36, Jan Beulich wrote:
>>>>  static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode,
>>>>                                            unsigned int port, unsigned int bytes)
>>>>  {
>>>> +    struct stubs *this_stubs = &this_cpu(stubs);
>>>> +    unsigned long stub_va = this_stubs->addr + STUB_BUF_SIZE / 2;
>>>> +
>>>>      if ( !ctxt->io_emul_stub )
>>>> -        ctxt->io_emul_stub = map_domain_page(_mfn(this_cpu(stubs.mfn))) +
>>>> -                                             (this_cpu(stubs.addr) &
>>>> -                                              ~PAGE_MASK) +
>>>> -                                             STUB_BUF_SIZE / 2;
>>>> +        ctxt->io_emul_stub =
>>>> +            map_domain_page(_mfn(this_stubs->mfn)) + (stub_va & ~PAGE_MASK);
>>>>  
>>>>      /* movq $host_to_guest_gpr_switch,%rcx */
>>>>      ctxt->io_emul_stub[0] = 0x48;
>>>>      ctxt->io_emul_stub[1] = 0xb9;
>>>>      *(void **)&ctxt->io_emul_stub[2] = (void *)host_to_guest_gpr_switch;
>>>> +
>>>> +#ifdef CONFIG_INDIRECT_THUNK
>>>> +    /* callq __x86.indirect_thunk.rcx */
>>>> +    ctxt->io_emul_stub[10] = 0xe8;
>>>> +    *(int32_t *)&ctxt->io_emul_stub[11] =
>>>> +        _p(ind_thunk_rcx) - _p(stub_va + 11 + 4);
>>> Why two (hidden) casts when one (clearly visible one) would do:
>>>
>>>     *(int32_t *)&ctxt->io_emul_stub[11] =
>>>         (unsigned long)ind_thunk_rcx - (stub_va + 11 + 4);
>>>
>>> ?
>>>
>>>> +#else
>>>>      /* callq *%rcx */
>>>>      ctxt->io_emul_stub[10] = 0xff;
>>>>      ctxt->io_emul_stub[11] = 0xd1;
>>>> +
>>>> +    /*
>>>> +     * 3 bytes of P6_NOPS.
>>>> +     * TODO: untangle ideal_nops from init/livepatch Kconfig options.
>>>> +     */
>>>> +    memcpy(&ctxt->io_emul_stub[12], "\x0f\x1f\x00", 3);
>>>> +#endif
>>> Same here - rather than making everything more complicated to
>>> read/understand, why don't we avoid conditionals in places where
>>> performance is of no concern.
>> Again, these are strictly required, because of ind_thunk_rcx[].
> Oh, right, other than above here I agree in general. However, I
> think I did suggest to unconditionally build the thunks as well - they
> do no harm if unused.

Actually, including them does do harm, in the case that a user wants to
compile without these modifications.  Excluding the symbols guarantees
the resulting binary wont link, if there is a mistake elsewhere which is
accidentally using them.

~Andrew

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 25/26] x86/cpuid: Offer Indirect Branch Controls to guests
  2018-01-04  0:15 ` [PATCH v6.5 25/26] x86/cpuid: Offer Indirect Branch Controls to guests Andrew Cooper
@ 2018-01-09 11:44   ` Wei Liu
  0 siblings, 0 replies; 69+ messages in thread
From: Wei Liu @ 2018-01-09 11:44 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Wei Liu, Xen-devel

On Thu, Jan 04, 2018 at 12:15:54AM +0000, Andrew Cooper wrote:
> With all infrastructure in place, it is now safe to let guests see and use
> these features.  Allow AMD's IBPB to be set even on Intel hardware, so the
> toolstack can express "IBPB only" to guests.
> 
> This also requires updating the libxc logic to understand the e8b feature
> leaf, which has the side effect of also offering CLZERO on applicable
> hardware.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Acked-by: Jan Beulich <jbeulich@suse.com>
> ---
> v4:
>  * Adjust for AMD changes
> v5:
>  * Support for IBRB-only
> v6:
>  * Fix AMD CPUID
> ---
>  tools/libxc/xc_cpuid_x86.c                  | 4 +++-

Acked-by: Wei Liu <wei.liu2@citrix.com>

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 14/26] x86: Introduce alternative indirect thunks
  2018-01-04  9:40   ` Jan Beulich
@ 2018-01-09 11:44     ` Andrew Cooper
  2018-01-09 13:24       ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-09 11:44 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 04/01/18 09:40, Jan Beulich wrote:
>>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
>> --- a/docs/misc/xen-command-line.markdown
>> +++ b/docs/misc/xen-command-line.markdown
>> @@ -245,6 +245,20 @@ and not running softirqs. Reduce this if softirqs are not being run frequently
>>  enough. Setting this to a high value may cause boot failure, particularly if
>>  the NMI watchdog is also enabled.
>>  
>> +### bti (x86)
>> +> `= List of [ thunk=retpoline|lfence|plain ]`
>> +
>> +Branch Target Injection controls.  By default, Xen will pick the most
>> +appropriate BTI mitigations based on compiled in support, loaded microcode,
>> +and hardware details.
>> +
>> +**WARNING: Any use of this option inhibits all heristcs.  Use with extreme care.**
> "heuristics"
>
>> @@ -27,7 +28,42 @@ enum ind_thunk {
>>      THUNK_NONE,    /* Missing compiler support for thunks. */
>>  
>>      THUNK_RETPOLINE,
>> -};
>> +    THUNK_LFENCE,
>> +    THUNK_JMP,
>> +} opt_thunk __initdata = THUNK_DEFAULT;
> This wants to be static.
>
>> @@ -48,6 +86,31 @@ void __init init_speculation_mitigations(void)
>>      enum ind_thunk thunk = THUNK_DEFAULT;
>>  
>>      /*
>> +     * Has the user specified any custom BTI mitigations?  If so, follow their
>> +     * instructions exactly and disable all heuristics.
>> +     */
>> +    if ( opt_thunk != THUNK_DEFAULT )
>> +    {
>> +        thunk = opt_thunk;
>> +    }
> The braces aren't really needed here.

They are in later patches.

>
>> +    else
>> +    {
>> +        /*
>> +         * Evaluate the safest Branch Target Injection mitigations to use.
>> +         * First, begin with compiler-aided mitigations.
>> +         */
>> +        if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) )
>> +        {
>> +            /*
>> +             * AMD's recommended mitigation is to set lfence as being dispatch
>> +             * serialising, and to use IND_THUNK_LFENCE.
>> +             */
>> +            if ( cpu_has_lfence_dispatch )
>> +                thunk = THUNK_LFENCE;
>> +        }
>> +    }
> As asked elsewhere, is the CONFIG_INDIRECT_THUNK dependency
> here really meaningful for the overall effect? Surely if we can't use
> thunks in the first place it doesn't matter which variant of them we
> don't use?

In later patches, the lack of INDIRECT_THUNK causes us to choose to use
IBRS+ if available in microcode.

~Andrew

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD}
  2018-01-04  9:52   ` Jan Beulich
@ 2018-01-09 12:03     ` Andrew Cooper
  2018-01-09 13:28       ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-09 12:03 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 04/01/18 09:52, Jan Beulich wrote:
>
>> --- a/xen/arch/x86/msr.c
>> +++ b/xen/arch/x86/msr.c
>> @@ -132,7 +132,8 @@ int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
>>      case MSR_SPEC_CTRL:
>>          if ( !cp->feat.ibrsb )
>>              goto gp_fault;
>> -        *val = vp->spec_ctrl.guest;
>> +        *val = (vp->spec_ctrl.direct_access
>> +                ? vp->spec_ctrl.host : vp->spec_ctrl.guest);
>>          break;
> To recap, I had asked whether this is valid ahead of later changes,
> which you replied to saying this won't have any "by not permitting
> the guest any access until patch 25". In which case at the very
> least the patch title is misleading. Yet I don't even agree with what
> you say - patch 25 only fiddles with CPUID bits. Did you perhaps
> mean to say "By not permitting a well behaved guest any access
> until patch 25," as one trying to access the MSRs without consulting
> the CPUID bits would be able to starting with the patch here aiui?

The guest access bit being clear in cpufeatureset.h means that the
maximum featureset calculations for guests will guarantee that
cp->feat.ibrsb is currently false.

~Andrew

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code
  2018-01-09 11:23         ` Andrew Cooper
@ 2018-01-09 13:18           ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-09 13:18 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 09.01.18 at 12:23, <andrew.cooper3@citrix.com> wrote:
> On 09/01/18 08:36, Jan Beulich wrote:
>>>>>  static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 
> opcode,
>>>>>                                            unsigned int port, unsigned int 
> bytes)
>>>>>  {
>>>>> +    struct stubs *this_stubs = &this_cpu(stubs);
>>>>> +    unsigned long stub_va = this_stubs->addr + STUB_BUF_SIZE / 2;
>>>>> +
>>>>>      if ( !ctxt->io_emul_stub )
>>>>> -        ctxt->io_emul_stub = map_domain_page(_mfn(this_cpu(stubs.mfn))) +
>>>>> -                                             (this_cpu(stubs.addr) &
>>>>> -                                              ~PAGE_MASK) +
>>>>> -                                             STUB_BUF_SIZE / 2;
>>>>> +        ctxt->io_emul_stub =
>>>>> +            map_domain_page(_mfn(this_stubs->mfn)) + (stub_va & ~PAGE_MASK);
>>>>>  
>>>>>      /* movq $host_to_guest_gpr_switch,%rcx */
>>>>>      ctxt->io_emul_stub[0] = 0x48;
>>>>>      ctxt->io_emul_stub[1] = 0xb9;
>>>>>      *(void **)&ctxt->io_emul_stub[2] = (void *)host_to_guest_gpr_switch;
>>>>> +
>>>>> +#ifdef CONFIG_INDIRECT_THUNK
>>>>> +    /* callq __x86.indirect_thunk.rcx */
>>>>> +    ctxt->io_emul_stub[10] = 0xe8;
>>>>> +    *(int32_t *)&ctxt->io_emul_stub[11] =
>>>>> +        _p(ind_thunk_rcx) - _p(stub_va + 11 + 4);
>>>> Why two (hidden) casts when one (clearly visible one) would do:
>>>>
>>>>     *(int32_t *)&ctxt->io_emul_stub[11] =
>>>>         (unsigned long)ind_thunk_rcx - (stub_va + 11 + 4);
>>>>
>>>> ?
>>>>
>>>>> +#else
>>>>>      /* callq *%rcx */
>>>>>      ctxt->io_emul_stub[10] = 0xff;
>>>>>      ctxt->io_emul_stub[11] = 0xd1;
>>>>> +
>>>>> +    /*
>>>>> +     * 3 bytes of P6_NOPS.
>>>>> +     * TODO: untangle ideal_nops from init/livepatch Kconfig options.
>>>>> +     */
>>>>> +    memcpy(&ctxt->io_emul_stub[12], "\x0f\x1f\x00", 3);
>>>>> +#endif
>>>> Same here - rather than making everything more complicated to
>>>> read/understand, why don't we avoid conditionals in places where
>>>> performance is of no concern.
>>> Again, these are strictly required, because of ind_thunk_rcx[].
>> Oh, right, other than above here I agree in general. However, I
>> think I did suggest to unconditionally build the thunks as well - they
>> do no harm if unused.
> 
> Actually, including them does do harm, in the case that a user wants to
> compile without these modifications.  Excluding the symbols guarantees
> the resulting binary wont link, if there is a mistake elsewhere which is
> accidentally using them.

Hmm, yes, I can see your point. Yet the harm done is minimal -
unintended/accidental use of the stubs is not going to result in
misbehavior, just in somewhat reduced performance.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 14/26] x86: Introduce alternative indirect thunks
  2018-01-09 11:44     ` Andrew Cooper
@ 2018-01-09 13:24       ` Jan Beulich
  2018-01-09 13:30         ` Andrew Cooper
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2018-01-09 13:24 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 09.01.18 at 12:44, <andrew.cooper3@citrix.com> wrote:
> On 04/01/18 09:40, Jan Beulich wrote:
>>>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
>>> +    else
>>> +    {
>>> +        /*
>>> +         * Evaluate the safest Branch Target Injection mitigations to use.
>>> +         * First, begin with compiler-aided mitigations.
>>> +         */
>>> +        if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) )
>>> +        {
>>> +            /*
>>> +             * AMD's recommended mitigation is to set lfence as being dispatch
>>> +             * serialising, and to use IND_THUNK_LFENCE.
>>> +             */
>>> +            if ( cpu_has_lfence_dispatch )
>>> +                thunk = THUNK_LFENCE;
>>> +        }
>>> +    }
>> As asked elsewhere, is the CONFIG_INDIRECT_THUNK dependency
>> here really meaningful for the overall effect? Surely if we can't use
>> thunks in the first place it doesn't matter which variant of them we
>> don't use?
> 
> In later patches, the lack of INDIRECT_THUNK causes us to choose to use
> IBRS+ if available in microcode.

Oh, I see, but that patch has no description so far, and hence it
is not really clear what the backgrounds of the decisions there is
(even to me, having been involved in this for some time). Is the
expected (or measured?) overhead of using the thunks lower
than that of IBRS?

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD}
  2018-01-09 12:03     ` Andrew Cooper
@ 2018-01-09 13:28       ` Jan Beulich
  2018-01-09 13:34         ` Andrew Cooper
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2018-01-09 13:28 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 09.01.18 at 13:03, <andrew.cooper3@citrix.com> wrote:
> On 04/01/18 09:52, Jan Beulich wrote:
>>
>>> --- a/xen/arch/x86/msr.c
>>> +++ b/xen/arch/x86/msr.c
>>> @@ -132,7 +132,8 @@ int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
>>>      case MSR_SPEC_CTRL:
>>>          if ( !cp->feat.ibrsb )
>>>              goto gp_fault;
>>> -        *val = vp->spec_ctrl.guest;
>>> +        *val = (vp->spec_ctrl.direct_access
>>> +                ? vp->spec_ctrl.host : vp->spec_ctrl.guest);
>>>          break;
>> To recap, I had asked whether this is valid ahead of later changes,
>> which you replied to saying this won't have any "by not permitting
>> the guest any access until patch 25". In which case at the very
>> least the patch title is misleading. Yet I don't even agree with what
>> you say - patch 25 only fiddles with CPUID bits. Did you perhaps
>> mean to say "By not permitting a well behaved guest any access
>> until patch 25," as one trying to access the MSRs without consulting
>> the CPUID bits would be able to starting with the patch here aiui?
> 
> The guest access bit being clear in cpufeatureset.h means that the
> maximum featureset calculations for guests will guarantee that
> cp->feat.ibrsb is currently false.

Well, that was the point of my reply: You mean well behaved
guests (ones consulting CPUID), but you don't say so, and - as
said - I think ones trying to access the MSRs anyway will observe
the accesses to work as of this patch, yet as it seems not fully
correctly (until that later patch is in place).

As pointed out before - I fine with things not working fully right
until that later patch, but the situation should be stated clearly.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 14/26] x86: Introduce alternative indirect thunks
  2018-01-09 13:24       ` Jan Beulich
@ 2018-01-09 13:30         ` Andrew Cooper
  0 siblings, 0 replies; 69+ messages in thread
From: Andrew Cooper @ 2018-01-09 13:30 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 09/01/18 13:24, Jan Beulich wrote:
>>>> On 09.01.18 at 12:44, <andrew.cooper3@citrix.com> wrote:
>> On 04/01/18 09:40, Jan Beulich wrote:
>>>>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
>>>> +    else
>>>> +    {
>>>> +        /*
>>>> +         * Evaluate the safest Branch Target Injection mitigations to use.
>>>> +         * First, begin with compiler-aided mitigations.
>>>> +         */
>>>> +        if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) )
>>>> +        {
>>>> +            /*
>>>> +             * AMD's recommended mitigation is to set lfence as being dispatch
>>>> +             * serialising, and to use IND_THUNK_LFENCE.
>>>> +             */
>>>> +            if ( cpu_has_lfence_dispatch )
>>>> +                thunk = THUNK_LFENCE;
>>>> +        }
>>>> +    }
>>> As asked elsewhere, is the CONFIG_INDIRECT_THUNK dependency
>>> here really meaningful for the overall effect? Surely if we can't use
>>> thunks in the first place it doesn't matter which variant of them we
>>> don't use?
>> In later patches, the lack of INDIRECT_THUNK causes us to choose to use
>> IBRS+ if available in microcode.
> Oh, I see, but that patch has no description so far, and hence it
> is not really clear what the backgrounds of the decisions there is
> (even to me, having been involved in this for some time). Is the
> expected (or measured?) overhead of using the thunks lower
> than that of IBRS?

These thunks have lower overhead that IBRS in all measurements I've
seen.  ISTR retpoline was specifically put together to combat the IBRS
perf hit.

One complication is that Skylake (and Broadwell before a specific
microcode version) are not safe even with retpoline, so IBRS is used
unconditionally.  (The microcode version to add IBRS to Broadwell causes
it to pass the retpoline-safety test).

~Andrew

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD}
  2018-01-09 13:28       ` Jan Beulich
@ 2018-01-09 13:34         ` Andrew Cooper
  2018-01-09 13:58           ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-09 13:34 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 09/01/18 13:28, Jan Beulich wrote:
>>>> On 09.01.18 at 13:03, <andrew.cooper3@citrix.com> wrote:
>> On 04/01/18 09:52, Jan Beulich wrote:
>>>> --- a/xen/arch/x86/msr.c
>>>> +++ b/xen/arch/x86/msr.c
>>>> @@ -132,7 +132,8 @@ int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
>>>>      case MSR_SPEC_CTRL:
>>>>          if ( !cp->feat.ibrsb )
>>>>              goto gp_fault;
>>>> -        *val = vp->spec_ctrl.guest;
>>>> +        *val = (vp->spec_ctrl.direct_access
>>>> +                ? vp->spec_ctrl.host : vp->spec_ctrl.guest);
>>>>          break;
>>> To recap, I had asked whether this is valid ahead of later changes,
>>> which you replied to saying this won't have any "by not permitting
>>> the guest any access until patch 25". In which case at the very
>>> least the patch title is misleading. Yet I don't even agree with what
>>> you say - patch 25 only fiddles with CPUID bits. Did you perhaps
>>> mean to say "By not permitting a well behaved guest any access
>>> until patch 25," as one trying to access the MSRs without consulting
>>> the CPUID bits would be able to starting with the patch here aiui?
>> The guest access bit being clear in cpufeatureset.h means that the
>> maximum featureset calculations for guests will guarantee that
>> cp->feat.ibrsb is currently false.
> Well, that was the point of my reply: You mean well behaved
> guests (ones consulting CPUID), but you don't say so, and - as
> said - I think ones trying to access the MSRs anyway will observe
> the accesses to work as of this patch, yet as it seems not fully
> correctly (until that later patch is in place).
>
> As pointed out before - I fine with things not working fully right
> until that later patch, but the situation should be stated clearly.

But it still functions correctly.  A guest which ignores CPUID will
still find two MSRs which unconditionally #GP when poked.  The logic to
allow passthrough is also derived from the cpuid policy, which disallows
the passthrough until patch 25.

(In fact, before this patch, a guest which poked at the MSRs wouldn't
find a #GP everywhere, because our MSR infrastructure is leaky.)

~Andrew

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD}
  2018-01-09 13:34         ` Andrew Cooper
@ 2018-01-09 13:58           ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-09 13:58 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 09.01.18 at 14:34, <andrew.cooper3@citrix.com> wrote:
> On 09/01/18 13:28, Jan Beulich wrote:
>>>>> On 09.01.18 at 13:03, <andrew.cooper3@citrix.com> wrote:
>>> On 04/01/18 09:52, Jan Beulich wrote:
>>>>> --- a/xen/arch/x86/msr.c
>>>>> +++ b/xen/arch/x86/msr.c
>>>>> @@ -132,7 +132,8 @@ int guest_rdmsr(const struct vcpu *v, uint32_t msr, 
> uint64_t *val)
>>>>>      case MSR_SPEC_CTRL:
>>>>>          if ( !cp->feat.ibrsb )
>>>>>              goto gp_fault;
>>>>> -        *val = vp->spec_ctrl.guest;
>>>>> +        *val = (vp->spec_ctrl.direct_access
>>>>> +                ? vp->spec_ctrl.host : vp->spec_ctrl.guest);
>>>>>          break;
>>>> To recap, I had asked whether this is valid ahead of later changes,
>>>> which you replied to saying this won't have any "by not permitting
>>>> the guest any access until patch 25". In which case at the very
>>>> least the patch title is misleading. Yet I don't even agree with what
>>>> you say - patch 25 only fiddles with CPUID bits. Did you perhaps
>>>> mean to say "By not permitting a well behaved guest any access
>>>> until patch 25," as one trying to access the MSRs without consulting
>>>> the CPUID bits would be able to starting with the patch here aiui?
>>> The guest access bit being clear in cpufeatureset.h means that the
>>> maximum featureset calculations for guests will guarantee that
>>> cp->feat.ibrsb is currently false.
>> Well, that was the point of my reply: You mean well behaved
>> guests (ones consulting CPUID), but you don't say so, and - as
>> said - I think ones trying to access the MSRs anyway will observe
>> the accesses to work as of this patch, yet as it seems not fully
>> correctly (until that later patch is in place).
>>
>> As pointed out before - I fine with things not working fully right
>> until that later patch, but the situation should be stated clearly.
> 
> But it still functions correctly.  A guest which ignores CPUID will
> still find two MSRs which unconditionally #GP when poked.  The logic to
> allow passthrough is also derived from the cpuid policy, which disallows
> the passthrough until patch 25.

Oh, right - I keep not realizing that the variable named "cp" is
the cpuid policy of the guest.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 20/26] x86: Protect unaware domains from meddling hyperthreads
  2018-01-04  9:59   ` Jan Beulich
@ 2018-01-09 14:21     ` Andrew Cooper
  2018-01-09 14:29       ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-09 14:21 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 04/01/18 09:59, Jan Beulich wrote:
>>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Fundamentally (as before)
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> However:
>
>> --- a/xen/arch/x86/domain.c
>> +++ b/xen/arch/x86/domain.c
>> @@ -2027,6 +2027,25 @@ int domain_relinquish_resources(struct domain *d)
>>   */
>>  void cpuid_policy_updated(struct vcpu *v)
>>  {
>> +    const struct cpuid_policy *cp = v->domain->arch.cpuid;
>> +    struct msr_vcpu_policy *vp = v->arch.msr;
>> +
>> +    /*
>> +     * For guests which know about IBRS but are not told about STIBP running
>> +     * on hardware supporting hyperthreading, the guest doesn't know to
>> +     * protect itself fully.  (Such a guest won't be permitted direct access
>> +     * to the MSR.)  Have Xen fill in the gaps, so an unaware guest can't be
>> +     * interfered with by a meddling guest on an adjacent hyperthread.
>> +     */
>> +    if ( cp->feat.ibrsb )
>> +    {
>> +        if ( !cp->feat.stibp && cpu_has_stibp &&
>> +             !(vp->spec_ctrl.guest & (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP)) )
>> +            vp->spec_ctrl.host = SPEC_CTRL_STIBP;
>> +        else
>> +            vp->spec_ctrl.host = vp->spec_ctrl.guest;
> This code is so similar to ...
>
>> --- a/xen/arch/x86/msr.c
>> +++ b/xen/arch/x86/msr.c
>> @@ -181,7 +181,20 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
>>                       (cp->feat.stibp ? SPEC_CTRL_STIBP : 0)) )
>>              goto gp_fault; /* Rsvd bit set? */
>>          vp->spec_ctrl.guest = val;
>> -        vp->spec_ctrl.host  = val;
>> +
>> +        /*
>> +         * For guests which are not told about STIBP, running on hardware
>> +         * supporting hyperthreading, the guest doesn't know to protect itself
>> +         * fully.  (Such a guest won't be permitted direct access to the MSR.)
>> +         * When IBRS is not in force, have Xen fill in the gaps, so an unaware
>> +         * guest can't be interfered with by a meddling guest on an adjacent
>> +         * hyperthread.
>> +         */
>> +        if ( !cp->feat.stibp && cpu_has_stibp &&
>> +             !(val & (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP)) )
>> +            vp->spec_ctrl.host = SPEC_CTRL_STIBP;
>> +        else
>> +            vp->spec_ctrl.host = val;
> ... this that I think a helper function would be warranted, unless you
> have reasons to believe that future changes might break the
> similarity.

I don't expect them to diverge, and will pull it out into a separate helper.

>
> I'm also a little puzzled by you checking SPEC_CTRL_STIBP there -
> this bit ought to be clear when !cp->feat.stibp due to the earlier
> reserved bit check (part of which is even visible in context above).
> IOW the check is not wrong, but perhaps misleading. You had
> replied to this remark with
>
> "The SPEC_CTRL_STIBP check exists solely because of v3 review which
>  objected to me implying a link between IBRS and STIPB."

The original logic was was "!cp->feat.stibp && cpu_has_stibp && val ==
0", which you argued would go stale as new SPEC_CTRL_ bits got added.

~Andrew

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 20/26] x86: Protect unaware domains from meddling hyperthreads
  2018-01-09 14:21     ` Andrew Cooper
@ 2018-01-09 14:29       ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2018-01-09 14:29 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 09.01.18 at 15:21, <andrew.cooper3@citrix.com> wrote:
> On 04/01/18 09:59, Jan Beulich wrote:
>>>>> On 04.01.18 at 01:15, <andrew.cooper3@citrix.com> wrote:
>>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> Fundamentally (as before)
>> Reviewed-by: Jan Beulich <jbeulich@suse.com>
>> However:
>>
>>> --- a/xen/arch/x86/domain.c
>>> +++ b/xen/arch/x86/domain.c
>>> @@ -2027,6 +2027,25 @@ int domain_relinquish_resources(struct domain *d)
>>>   */
>>>  void cpuid_policy_updated(struct vcpu *v)
>>>  {
>>> +    const struct cpuid_policy *cp = v->domain->arch.cpuid;
>>> +    struct msr_vcpu_policy *vp = v->arch.msr;
>>> +
>>> +    /*
>>> +     * For guests which know about IBRS but are not told about STIBP 
> running
>>> +     * on hardware supporting hyperthreading, the guest doesn't know to
>>> +     * protect itself fully.  (Such a guest won't be permitted direct 
> access
>>> +     * to the MSR.)  Have Xen fill in the gaps, so an unaware guest can't 
> be
>>> +     * interfered with by a meddling guest on an adjacent hyperthread.
>>> +     */
>>> +    if ( cp->feat.ibrsb )
>>> +    {
>>> +        if ( !cp->feat.stibp && cpu_has_stibp &&
>>> +             !(vp->spec_ctrl.guest & (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP)) )
>>> +            vp->spec_ctrl.host = SPEC_CTRL_STIBP;
>>> +        else
>>> +            vp->spec_ctrl.host = vp->spec_ctrl.guest;
>> This code is so similar to ...
>>
>>> --- a/xen/arch/x86/msr.c
>>> +++ b/xen/arch/x86/msr.c
>>> @@ -181,7 +181,20 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t 
> val)
>>>                       (cp->feat.stibp ? SPEC_CTRL_STIBP : 0)) )
>>>              goto gp_fault; /* Rsvd bit set? */
>>>          vp->spec_ctrl.guest = val;
>>> -        vp->spec_ctrl.host  = val;
>>> +
>>> +        /*
>>> +         * For guests which are not told about STIBP, running on hardware
>>> +         * supporting hyperthreading, the guest doesn't know to protect itself
>>> +         * fully.  (Such a guest won't be permitted direct access to the MSR.)
>>> +         * When IBRS is not in force, have Xen fill in the gaps, so an unaware
>>> +         * guest can't be interfered with by a meddling guest on an adjacent
>>> +         * hyperthread.
>>> +         */
>>> +        if ( !cp->feat.stibp && cpu_has_stibp &&
>>> +             !(val & (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP)) )
>>> +            vp->spec_ctrl.host = SPEC_CTRL_STIBP;
>>> +        else
>>> +            vp->spec_ctrl.host = val;
>> ... this that I think a helper function would be warranted, unless you
>> have reasons to believe that future changes might break the
>> similarity.
> 
> I don't expect them to diverge, and will pull it out into a separate helper.
> 
>>
>> I'm also a little puzzled by you checking SPEC_CTRL_STIBP there -
>> this bit ought to be clear when !cp->feat.stibp due to the earlier
>> reserved bit check (part of which is even visible in context above).
>> IOW the check is not wrong, but perhaps misleading. You had
>> replied to this remark with
>>
>> "The SPEC_CTRL_STIBP check exists solely because of v3 review which
>>  objected to me implying a link between IBRS and STIPB."
> 
> The original logic was was "!cp->feat.stibp && cpu_has_stibp && val ==
> 0", which you argued would go stale as new SPEC_CTRL_ bits got added.

Ah, I recall now. But by just checking !(val & SPEC_CTRL_IBRS) you
would avoid the staleness; you might even consider putting an
ASSERT() in to validate the other bit is clear.

Jan


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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code
  2018-01-04  0:15 ` [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code Andrew Cooper
  2018-01-04  9:23   ` Jan Beulich
@ 2018-01-11 13:03   ` David Woodhouse
  2018-01-11 13:41     ` Andrew Cooper
  1 sibling, 1 reply; 69+ messages in thread
From: David Woodhouse @ 2018-01-11 13:03 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 1382 bytes --]

On Thu, 2018-01-04 at 00:15 +0000, Andrew Cooper wrote:
> +         * We've got no usable stack so can't use a RETPOLINE thunk, and are
> +         * further than +- 2G from the high mappings so couldn't use JUMP_THUNK
> +         * even if was a non-RETPOLINE thunk.  Futhermore, an LFENCE isn't
> +         * necesserily safe to use at this point.

I count three typos, pedantry about ± and GiB aside.
Late night? :)

> --- a/xen/arch/x86/extable.c
> +++ b/xen/arch/x86/extable.c
> @@ -158,7 +158,7 @@ static int __init stub_selftest(void)
>          memcpy(ptr, tests[i].opc, ARRAY_SIZE(tests[i].opc));
>          unmap_domain_page(ptr);
>  
> -        asm volatile ( "call *%[stb]\n"
> +        asm volatile ( "CALL_THUNK %[stb]\n"

If you make that %V[stb] then...

> +    .if CONFIG_INDIRECT_THUNK == 1
> +
> +        $done = 0
> +        .irp reg, rax, rbx, rcx, rdx, rsi, rdi, rbp, r8, r9, r10, r11, r12, r13, r14, r15
> +        .ifeqs "\arg", "%\reg"
> +            \insn __x86.indirect_thunk.\reg
> +            $done = 1
> +           .exitm
> +        .endif
> +        .endr
> +        .if $done != 1
> +        .error "Bad register arg \arg"
> +        .endif
> +

... you don't need this.

[-- Attachment #1.2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5213 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code
  2018-01-11 13:03   ` David Woodhouse
@ 2018-01-11 13:41     ` Andrew Cooper
  2018-01-11 13:46       ` David Woodhouse
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-11 13:41 UTC (permalink / raw)
  To: David Woodhouse, Xen-devel

On 11/01/18 13:03, David Woodhouse wrote:
> On Thu, 2018-01-04 at 00:15 +0000, Andrew Cooper wrote:
>> +         * We've got no usable stack so can't use a RETPOLINE thunk, and are
>> +         * further than +- 2G from the high mappings so couldn't use JUMP_THUNK
>> +         * even if was a non-RETPOLINE thunk.  Futhermore, an LFENCE isn't
>> +         * necesserily safe to use at this point.
> I count three typos, pedantry about ± and GiB aside.
> Late night? :)

Just one of many...

I've found furthermore and necessarily.  Where is the 3rd?

>
>> --- a/xen/arch/x86/extable.c
>> +++ b/xen/arch/x86/extable.c
>> @@ -158,7 +158,7 @@ static int __init stub_selftest(void)
>>          memcpy(ptr, tests[i].opc, ARRAY_SIZE(tests[i].opc));
>>          unmap_domain_page(ptr);
>>  
>> -        asm volatile ( "call *%[stb]\n"
>> +        asm volatile ( "CALL_THUNK %[stb]\n"
> If you make that %V[stb] then...
>
>> +    .if CONFIG_INDIRECT_THUNK == 1
>> +
>> +        $done = 0
>> +        .irp reg, rax, rbx, rcx, rdx, rsi, rdi, rbp, r8, r9, r10, r11, r12, r13, r14, r15
>> +        .ifeqs "\arg", "%\reg"
>> +            \insn __x86.indirect_thunk.\reg
>> +            $done = 1
>> +           .exitm
>> +        .endif
>> +        .endr
>> +        .if $done != 1
>> +        .error "Bad register arg \arg"
>> +        .endif
>> +
> ... you don't need this.

That's fine in principle, except it isn't compatible with most of the
compilers we support.  To use, the %V has to be hidden behind a
conditional macro, and I can't think of any remotely-clean way to do that.

~Andrew

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code
  2018-01-11 13:41     ` Andrew Cooper
@ 2018-01-11 13:46       ` David Woodhouse
  0 siblings, 0 replies; 69+ messages in thread
From: David Woodhouse @ 2018-01-11 13:46 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 1486 bytes --]

On Thu, 2018-01-11 at 13:41 +0000, Andrew Cooper wrote:
> On 11/01/18 13:03, David Woodhouse wrote:
> > 
> > On Thu, 2018-01-04 at 00:15 +0000, Andrew Cooper wrote:
> > > 
> > > +         * We've got no usable stack so can't use a RETPOLINE thunk, and are
> > > +         * further than +- 2G from the high mappings so couldn't use JUMP_THUNK
> > > +         * even if was a non-RETPOLINE thunk.  Futhermore, an LFENCE isn't
> > > +         * necesserily safe to use at this point.
>
> > I count three typos, pedantry about ± and GiB aside.
> > Late night? :)
> Just one of many...
> 
> I've found furthermore and necessarily.  Where is the 3rd?

* even if IT was a … 


> > > -        asm volatile ( "call *%[stb]\n"
> > > +        asm volatile ( "CALL_THUNK %[stb]\n"
> > If you make that %V[stb] then...
> > ... you don't need this.
> That's fine in principle, except it isn't compatible with most of the
> compilers we support.  To use, the %V has to be hidden behind a
> conditional macro, and I can't think of any remotely-clean way to do
> that.

In at least one incarnation I ended up with something like

#ifndef CONFIG_RETPOLINE
#define CALL_THUNK(reg) "call *%[" #reg "]"
#else
#define CALL_THUNK(reg) "CALL_THUNK %V[" #reg "]"
#endif

Or maybe I just insisted that it was called %[thunk_target] and my
CALL_THUNK C macro doesn't even take an argument. I forget. Late night…

[-- Attachment #1.2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5213 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 08/26] x86/entry: Erase guest GPR state on entry to Xen
  2018-01-04  0:15 ` [PATCH v6.5 08/26] x86/entry: Erase guest GPR state on entry to Xen Andrew Cooper
@ 2018-01-22 10:04   ` David Woodhouse
  2018-01-22 10:18     ` Andrew Cooper
  0 siblings, 1 reply; 69+ messages in thread
From: David Woodhouse @ 2018-01-22 10:04 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 745 bytes --]

On Thu, 2018-01-04 at 00:15 +0000, Andrew Cooper wrote:
> 
> --- a/xen/include/asm-x86/asm_defns.h
> +++ b/xen/include/asm-x86/asm_defns.h
> @@ -217,22 +217,34 @@ static always_inline void stac(void)
>          addq  $-(UREGS_error_code-UREGS_r15), %rsp
>          cld
>          movq  %rdi,UREGS_rdi(%rsp)
> +        xor   %edi, %edi
>          movq  %rsi,UREGS_rsi(%rsp)
> +        xor   %esi, %esi
>          movq  %rdx,UREGS_rdx(%rsp)
> +        xor   %edx, %edx
>          movq  %rcx,UREGS_rcx(%rsp)
> +        xor   %ecx, %ecx
>          movq  %rax,UREGS_rax(%rsp)
> +        xor   %eax, %eax

You didn't want to erase all 64 bits?

[-- Attachment #1.2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5213 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 08/26] x86/entry: Erase guest GPR state on entry to Xen
  2018-01-22 10:04   ` David Woodhouse
@ 2018-01-22 10:18     ` Andrew Cooper
  2018-01-22 10:27       ` David Woodhouse
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2018-01-22 10:18 UTC (permalink / raw)
  To: David Woodhouse, Xen-devel

On 22/01/2018 10:04, David Woodhouse wrote:
> On Thu, 2018-01-04 at 00:15 +0000, Andrew Cooper wrote:
>> --- a/xen/include/asm-x86/asm_defns.h
>> +++ b/xen/include/asm-x86/asm_defns.h
>> @@ -217,22 +217,34 @@ static always_inline void stac(void)
>>          addq  $-(UREGS_error_code-UREGS_r15), %rsp
>>          cld
>>          movq  %rdi,UREGS_rdi(%rsp)
>> +        xor   %edi, %edi
>>          movq  %rsi,UREGS_rsi(%rsp)
>> +        xor   %esi, %esi
>>          movq  %rdx,UREGS_rdx(%rsp)
>> +        xor   %edx, %edx
>>          movq  %rcx,UREGS_rcx(%rsp)
>> +        xor   %ecx, %ecx
>>          movq  %rax,UREGS_rax(%rsp)
>> +        xor   %eax, %eax
> You didn't want to erase all 64 bits?

This does erase all 64 bits.  (We're in long mode, so the upper 32 bits
are implicitly zeroed, without an added rex prefix.)

~Andrew

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v6.5 08/26] x86/entry: Erase guest GPR state on entry to Xen
  2018-01-22 10:18     ` Andrew Cooper
@ 2018-01-22 10:27       ` David Woodhouse
  0 siblings, 0 replies; 69+ messages in thread
From: David Woodhouse @ 2018-01-22 10:27 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 1244 bytes --]

On Mon, 2018-01-22 at 10:18 +0000, Andrew Cooper wrote:
> On 22/01/2018 10:04, David Woodhouse wrote:
> > 
> > On Thu, 2018-01-04 at 00:15 +0000, Andrew Cooper wrote:
> > > 
> > > --- a/xen/include/asm-x86/asm_defns.h
> > > +++ b/xen/include/asm-x86/asm_defns.h
> > > @@ -217,22 +217,34 @@ static always_inline void stac(void)
> > >          addq  $-(UREGS_error_code-UREGS_r15), %rsp
> > >          cld
> > >          movq  %rdi,UREGS_rdi(%rsp)
> > > +        xor   %edi, %edi
> > >          movq  %rsi,UREGS_rsi(%rsp)
> > > +        xor   %esi, %esi
> > >          movq  %rdx,UREGS_rdx(%rsp)
> > > +        xor   %edx, %edx
> > >          movq  %rcx,UREGS_rcx(%rsp)
> > > +        xor   %ecx, %ecx
> > >          movq  %rax,UREGS_rax(%rsp)
> > > +        xor   %eax, %eax
> > You didn't want to erase all 64 bits?
>
> This does erase all 64 bits.  (We're in long mode, so the upper 32 bits
> are implicitly zeroed, without an added rex prefix.)

Eww. In the grand scheme of things, I'd rather the assembler knew that
(and happily omitted the rex prefix all by itself to use the more
efficient encoding of the instruction), and not me.

[-- Attachment #1.2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5213 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

end of thread, other threads:[~2018-01-22 10:27 UTC | newest]

Thread overview: 69+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-04  0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
2018-01-04  0:15 ` [PATCH v6.5 01/26] x86/alt: Break out alternative-asm into a separate header file Andrew Cooper
2018-01-04  0:15 ` [PATCH v6.5 02/26] x86/alt: Introduce ALTERNATIVE{, _2} macros Andrew Cooper
2018-01-04  0:15 ` [PATCH v6.5 03/26] x86/hvm: Rename update_guest_vendor() callback to cpuid_policy_changed() Andrew Cooper
2018-01-04  0:15 ` [PATCH v6.5 04/26] x86: Introduce a common cpuid_policy_updated() Andrew Cooper
2018-01-04  0:15 ` [PATCH v6.5 05/26] x86/entry: Remove support for partial cpu_user_regs frames Andrew Cooper
2018-01-04  8:51   ` Jan Beulich
2018-01-04  0:15 ` [PATCH v6.5 06/26] x86/entry: Rearrange RESTORE_ALL to restore register in stack order Andrew Cooper
2018-01-04  0:15 ` [PATCH v6.5 07/26] x86/hvm: Use SAVE_ALL to construct the cpu_user_regs frame after VMExit Andrew Cooper
2018-01-04  0:15 ` [PATCH v6.5 08/26] x86/entry: Erase guest GPR state on entry to Xen Andrew Cooper
2018-01-22 10:04   ` David Woodhouse
2018-01-22 10:18     ` Andrew Cooper
2018-01-22 10:27       ` David Woodhouse
2018-01-04  0:15 ` [PATCH v6.5 09/26] x86: Support compiling with indirect branch thunks Andrew Cooper
2018-01-04  9:02   ` Jan Beulich
2018-01-04  0:15 ` [PATCH v6.5 10/26] common/wait: Clarifications to wait infrastructure Andrew Cooper
2018-01-04  0:15 ` [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code Andrew Cooper
2018-01-04  9:23   ` Jan Beulich
2018-01-08 18:24     ` Andrew Cooper
2018-01-09  8:36       ` Jan Beulich
2018-01-09 11:23         ` Andrew Cooper
2018-01-09 13:18           ` Jan Beulich
2018-01-11 13:03   ` David Woodhouse
2018-01-11 13:41     ` Andrew Cooper
2018-01-11 13:46       ` David Woodhouse
2018-01-04  0:15 ` [PATCH v6.5 12/26] x86/boot: Report details of speculative mitigations Andrew Cooper
2018-01-04  9:29   ` Jan Beulich
2018-01-04  0:15 ` [PATCH v6.5 13/26] x86/amd: Try to set lfence as being Dispatch Serialising Andrew Cooper
2018-01-04  9:32   ` Jan Beulich
2018-01-08 19:01     ` Andrew Cooper
2018-01-09  8:38       ` Jan Beulich
2018-01-04  0:15 ` [PATCH v6.5 14/26] x86: Introduce alternative indirect thunks Andrew Cooper
2018-01-04  9:40   ` Jan Beulich
2018-01-09 11:44     ` Andrew Cooper
2018-01-09 13:24       ` Jan Beulich
2018-01-09 13:30         ` Andrew Cooper
2018-01-04  0:15 ` [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls Andrew Cooper
2018-01-04  1:14   ` Doug Goldstein
2018-01-04  1:16     ` Andrew Cooper
2018-01-04  4:05     ` Anthony Liguori
2018-01-04  9:42   ` Jan Beulich
2018-01-04 18:51   ` Wei Liu
2018-01-04  0:15 ` [PATCH v6.5 16/26] x86/cmdline: Introduce a command line option to disable IBRS/IBPB, STIBP and IBPB Andrew Cooper
2018-01-04  9:43   ` Jan Beulich
2018-01-04  0:15 ` [PATCH v6.5 17/26] x86/msr: Emulation of MSR_{SPEC_CTRL, PRED_CMD} for guests Andrew Cooper
2018-01-04  0:15 ` [PATCH v6.5 18/26] x86/migrate: Move MSR_SPEC_CTRL on migrate Andrew Cooper
2018-01-04  0:15 ` [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD} Andrew Cooper
2018-01-04  9:52   ` Jan Beulich
2018-01-09 12:03     ` Andrew Cooper
2018-01-09 13:28       ` Jan Beulich
2018-01-09 13:34         ` Andrew Cooper
2018-01-09 13:58           ` Jan Beulich
2018-01-04  0:15 ` [PATCH v6.5 20/26] x86: Protect unaware domains from meddling hyperthreads Andrew Cooper
2018-01-04  9:59   ` Jan Beulich
2018-01-09 14:21     ` Andrew Cooper
2018-01-09 14:29       ` Jan Beulich
2018-01-04  0:15 ` [PATCH v6.5 21/26] x86/entry: Use MSR_SPEC_CTRL at each entry/exit point Andrew Cooper
2018-01-04 10:14   ` Jan Beulich
2018-01-04  0:15 ` [PATCH v6.5 22/26] x86/boot: Calculate the most appropriate BTI mitigation to use Andrew Cooper
2018-01-04 10:17   ` Jan Beulich
2018-01-04  0:15 ` [PATCH v6.5 23/26] x86/entry: Clobber the Return Stack Buffer on entry to Xen Andrew Cooper
2018-01-04 10:22   ` Jan Beulich
2018-01-04  0:15 ` [PATCH v6.5 24/26] x86/ctxt: Issue a speculation barrier between vcpu contexts Andrew Cooper
2018-01-04 10:25   ` Jan Beulich
2018-01-04  0:15 ` [PATCH v6.5 25/26] x86/cpuid: Offer Indirect Branch Controls to guests Andrew Cooper
2018-01-09 11:44   ` Wei Liu
2018-01-04  0:15 ` [PATCH v6.5 26/26] x86/idle: Clear SPEC_CTRL while idle Andrew Cooper
2018-01-04 10:29   ` Jan Beulich
2018-01-04 10:41   ` Jan Beulich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.