]> xenbits.xensource.com Git - xen.git/commitdiff
x86/spec_ctrl: Explicitly set Xen's default MSR_SPEC_CTRL value
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 29 May 2018 09:06:30 +0000 (11:06 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 29 May 2018 09:06:30 +0000 (11:06 +0200)
With the impending ability to disable MSR_SPEC_CTRL handling on a
per-guest-type basis, the first exit-from-guest may not have the side effect
of loading Xen's choice of value.  Explicitly set Xen's default during the BSP
and AP boot paths.

For the BSP however, delay setting a non-zero MSR_SPEC_CTRL default until
after dom0 has been constructed when safe to do so.  Oracle report that this
speeds up boots of some hardware by 50s.

"when safe to do so" is based on whether we are virtualised.  A native boot
won't have any other code running in a position to mount an attack.

Reported-by: Zhenzhong Duan <zhenzhong.duan@oracle.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
master commit: cb8c12020307b39a89273d7699e89000451987ab
master date: 2018-05-16 12:19:10 +0100

xen/arch/x86/setup.c
xen/arch/x86/smpboot.c
xen/arch/x86/spec_ctrl.c
xen/include/asm-x86/cpufeature.h
xen/include/asm-x86/spec_ctrl.h

index 606a57a1ae85399291642f96a38c24e1fd19f406..c3adee57cd0bcf66c45dbedb8e70bf5be22eff60 100644 (file)
@@ -1538,6 +1538,13 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
     setup_io_bitmap(dom0);
 
+    if ( bsp_delay_spec_ctrl )
+    {
+        get_cpu_info()->spec_ctrl_flags &= ~SCF_use_shadow;
+        barrier();
+        wrmsrl(MSR_SPEC_CTRL, default_xen_spec_ctrl);
+    }
+
     /* Jump to the 1:1 virtual mappings of cpu0_stack. */
     asm volatile ("mov %[stk], %%rsp; jmp %c[fn]" ::
                   [stk] "g" (__va(__pa(get_stack_bottom()))),
index b69d63ad09276a97fc78e1a7a5a7317cae5b1f7d..7f57dcf3e9d27e1b3eea1d3e34784a8edda2cdc6 100644 (file)
@@ -379,6 +379,14 @@ void start_secondary(void *unused)
     else
         microcode_resume_cpu(cpu);
 
+    /*
+     * If MSR_SPEC_CTRL is available, apply Xen's default setting and discard
+     * any firmware settings.  Note: MSR_SPEC_CTRL may only become available
+     * after loading microcode.
+     */
+    if ( boot_cpu_has(X86_FEATURE_IBRSB) )
+        wrmsrl(MSR_SPEC_CTRL, default_xen_spec_ctrl);
+
     smp_callin();
 
     setup_secondary_APIC_clock();
index fece1056b9b34682958b1bd0ca89afca14c2a888..844a22f9be87ba6b615c2b949701023797f96209 100644 (file)
@@ -38,6 +38,8 @@ static int8_t __initdata opt_ibrs = -1;
 static bool_t __initdata opt_rsb_pv = 1;
 static bool_t __initdata opt_rsb_hvm = 1;
 bool_t __read_mostly opt_ibpb = 1;
+
+bool_t __initdata bsp_delay_spec_ctrl;
 uint8_t __read_mostly default_xen_spec_ctrl;
 uint8_t __read_mostly default_spec_ctrl_flags;
 
@@ -331,6 +333,36 @@ void __init init_speculation_mitigations(void)
         __set_bit(X86_FEATURE_SC_MSR_IDLE, boot_cpu_data.x86_capability);
 
     print_details(thunk, caps);
+
+    /*
+     * If MSR_SPEC_CTRL is available, apply Xen's default setting and discard
+     * any firmware settings.  For performance reasons, when safe to do so, we
+     * delay applying non-zero settings until after dom0 has been constructed.
+     *
+     * "when safe to do so" is based on whether we are virtualised.  A native
+     * boot won't have any other code running in a position to mount an
+     * attack.
+     */
+    if ( boot_cpu_has(X86_FEATURE_IBRSB) )
+    {
+        bsp_delay_spec_ctrl = !cpu_has_hypervisor && default_xen_spec_ctrl;
+
+        /*
+         * If delaying MSR_SPEC_CTRL setup, use the same mechanism as
+         * spec_ctrl_enter_idle(), by using a shadow value of zero.
+         */
+        if ( bsp_delay_spec_ctrl )
+        {
+            struct cpu_info *info = get_cpu_info();
+
+            info->shadow_spec_ctrl = 0;
+            barrier();
+            info->spec_ctrl_flags |= SCF_use_shadow;
+            barrier();
+        }
+
+        wrmsrl(MSR_SPEC_CTRL, bsp_delay_spec_ctrl ? 0 : default_xen_spec_ctrl);
+    }
 }
 
 static void __init __maybe_unused build_assertions(void)
index 3aaa6c8078e82e174bd649df8c1eecf1dbab9d69..22429db282d4c5ec86616341817be2ca6314617a 100644 (file)
 #define cpu_has_svm            boot_cpu_has(X86_FEATURE_SVM)
 
 #define cpu_has_vmx            boot_cpu_has(X86_FEATURE_VMXE)
+#define cpu_has_hypervisor     boot_cpu_has(X86_FEATURE_HYPERVISOR)
 
 #define cpu_has_cpuid_faulting boot_cpu_has(X86_FEATURE_CPUID_FAULTING)
 #define cpu_has_lfence_dispatch boot_cpu_has(X86_FEATURE_LFENCE_DISPATCH)
index ec943e18e306606304fee40fdf71a239d1eb65c5..d36f0e92a89f4a0d7bba0f48c9308d11d47bac07 100644 (file)
@@ -27,6 +27,8 @@
 void init_speculation_mitigations(void);
 
 extern bool_t opt_ibpb;
+
+extern bool_t bsp_delay_spec_ctrl;
 extern uint8_t default_xen_spec_ctrl;
 extern uint8_t default_spec_ctrl_flags;