x86/cpufeatures: Disentangle MSR_SPEC_CTRL enumeration from IBRS
authorThomas Gleixner <tglx@linutronix.de>
Thu, 10 May 2018 17:13:18 +0000 (19:13 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 17 May 2018 15:09:17 +0000 (17:09 +0200)
The availability of the SPEC_CTRL MSR is enumerated by a CPUID bit on
Intel and implied by IBRS or STIBP support on AMD. That's just confusing
and in case an AMD CPU has IBRS not supported because the underlying
problem has been fixed but has another bit valid in the SPEC_CTRL MSR,
the thing falls apart.

Add a synthetic feature bit X86_FEATURE_MSR_SPEC_CTRL to denote the
availability on both Intel and AMD.

While at it replace the boot_cpu_has() checks with static_cpu_has() where
possible. This prevents late microcode loading from exposing SPEC_CTRL, but
late loading is already very limited as it does not reevaluate the
mitigation options and other bits and pieces. Having static_cpu_has() is
the simplest and least fragile solution.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
arch/x86/include/asm/cpufeatures.h
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/intel.c

index cb9bca8cecdc92de6e645245cc1f7d86c40b40a5..7d34eb0d37158c39a00d405b8c4bb6699e6d1350 100644 (file)
 #define X86_FEATURE_RETPOLINE_AMD      ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
 #define X86_FEATURE_INTEL_PPIN         ( 7*32+14) /* Intel Processor Inventory Number */
 #define X86_FEATURE_CDP_L2             ( 7*32+15) /* Code and Data Prioritization L2 */
+#define X86_FEATURE_MSR_SPEC_CTRL      ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */
 
 #define X86_FEATURE_MBA                        ( 7*32+18) /* Memory Bandwidth Allocation */
 #define X86_FEATURE_RSB_CTXSW          ( 7*32+19) /* "" Fill RSB on context switches */
index bab05913f86411933e62207035f5d9fcd9ab9154..316cb24092a3030a7880bdae98cdb9449951427a 100644 (file)
@@ -64,7 +64,7 @@ void __init check_bugs(void)
         * have unknown values. AMD64_LS_CFG MSR is cached in the early AMD
         * init code as it is not enumerated and depends on the family.
         */
-       if (boot_cpu_has(X86_FEATURE_IBRS))
+       if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
                rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
 
        /* Select the proper spectre mitigation before patching alternatives */
@@ -145,7 +145,7 @@ u64 x86_spec_ctrl_get_default(void)
 {
        u64 msrval = x86_spec_ctrl_base;
 
-       if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+       if (static_cpu_has(X86_FEATURE_SPEC_CTRL))
                msrval |= ssbd_tif_to_spec_ctrl(current_thread_info()->flags);
        return msrval;
 }
@@ -155,10 +155,12 @@ void x86_spec_ctrl_set_guest(u64 guest_spec_ctrl)
 {
        u64 host = x86_spec_ctrl_base;
 
-       if (!boot_cpu_has(X86_FEATURE_IBRS))
+       /* Is MSR_SPEC_CTRL implemented ? */
+       if (!static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
                return;
 
-       if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+       /* Intel controls SSB in MSR_SPEC_CTRL */
+       if (static_cpu_has(X86_FEATURE_SPEC_CTRL))
                host |= ssbd_tif_to_spec_ctrl(current_thread_info()->flags);
 
        if (host != guest_spec_ctrl)
@@ -170,10 +172,12 @@ void x86_spec_ctrl_restore_host(u64 guest_spec_ctrl)
 {
        u64 host = x86_spec_ctrl_base;
 
-       if (!boot_cpu_has(X86_FEATURE_IBRS))
+       /* Is MSR_SPEC_CTRL implemented ? */
+       if (!static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
                return;
 
-       if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+       /* Intel controls SSB in MSR_SPEC_CTRL */
+       if (static_cpu_has(X86_FEATURE_SPEC_CTRL))
                host |= ssbd_tif_to_spec_ctrl(current_thread_info()->flags);
 
        if (host != guest_spec_ctrl)
@@ -631,7 +635,7 @@ int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
 
 void x86_spec_ctrl_setup_ap(void)
 {
-       if (boot_cpu_has(X86_FEATURE_IBRS))
+       if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
                x86_spec_ctrl_set(x86_spec_ctrl_base & ~x86_spec_ctrl_mask);
 
        if (ssb_mode == SPEC_STORE_BYPASS_DISABLE)
index e6cd38b20375b08bb6e5b4918a0a3eb7a7fc54a2..af54dbe2df9afe5c39da66106feaf6d2fe182701 100644 (file)
@@ -761,19 +761,24 @@ static void init_speculation_control(struct cpuinfo_x86 *c)
        if (cpu_has(c, X86_FEATURE_SPEC_CTRL)) {
                set_cpu_cap(c, X86_FEATURE_IBRS);
                set_cpu_cap(c, X86_FEATURE_IBPB);
+               set_cpu_cap(c, X86_FEATURE_MSR_SPEC_CTRL);
        }
 
        if (cpu_has(c, X86_FEATURE_INTEL_STIBP))
                set_cpu_cap(c, X86_FEATURE_STIBP);
 
-       if (cpu_has(c, X86_FEATURE_AMD_IBRS))
+       if (cpu_has(c, X86_FEATURE_AMD_IBRS)) {
                set_cpu_cap(c, X86_FEATURE_IBRS);
+               set_cpu_cap(c, X86_FEATURE_MSR_SPEC_CTRL);
+       }
 
        if (cpu_has(c, X86_FEATURE_AMD_IBPB))
                set_cpu_cap(c, X86_FEATURE_IBPB);
 
-       if (cpu_has(c, X86_FEATURE_AMD_STIBP))
+       if (cpu_has(c, X86_FEATURE_AMD_STIBP)) {
                set_cpu_cap(c, X86_FEATURE_STIBP);
+               set_cpu_cap(c, X86_FEATURE_MSR_SPEC_CTRL);
+       }
 }
 
 void get_cpu_cap(struct cpuinfo_x86 *c)
index 0eab6c89c8d94858cd4bc1691becb07edf79c21c..dd37244c587a4a474363b4035afbe2994381fb6f 100644 (file)
@@ -188,6 +188,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
                setup_clear_cpu_cap(X86_FEATURE_IBPB);
                setup_clear_cpu_cap(X86_FEATURE_STIBP);
                setup_clear_cpu_cap(X86_FEATURE_SPEC_CTRL);
+               setup_clear_cpu_cap(X86_FEATURE_MSR_SPEC_CTRL);
                setup_clear_cpu_cap(X86_FEATURE_INTEL_STIBP);
                setup_clear_cpu_cap(X86_FEATURE_SSBD);
        }