]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
x86/bugs/intel: Set proper CPU features and setup RDS
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Thu, 26 Apr 2018 02:04:22 +0000 (22:04 -0400)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 14 May 2018 10:08:45 +0000 (12:08 +0200)
Intel CPUs expose methods to:

 - Detect whether RDS capability is available via CPUID.7.0.EDX[31],

 - The SPEC_CTRL MSR(0x48), bit 2 set to enable RDS.

 - MSR_IA32_ARCH_CAPABILITIES, Bit(4) no need to enable RRS.

With that in mind if spec_store_bypass_disable=[auto,on] is selected set at
boot-time the SPEC_CTRL MSR to enable RDS if the platform requires it.

Note that this does not fix the KVM case where the SPEC_CTRL is exposed to
guests which can muck with it, see patch titled :
 KVM/SVM/VMX/x86/spectre_v2: Support the combination of guest and host IBRS.

And for the firmware (IBRS to be set), see patch titled:
 x86/spectre_v2: Read SPEC_CTRL MSR during boot and re-use reserved bits

[ tglx: Distangled it from the intel implementation and kept the call order ]

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
CVE-2018-3639 (x86)

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
[backport drops clear feature for bad microcode]
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
arch/x86/include/asm/msr-index.h
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cpu.h

index fd379f7f8c34087c7b5cd03c5535b94e048007b6..ceeeadb38f925148d2a080ac6bb4764873550c7f 100644 (file)
@@ -41,6 +41,7 @@
 #define MSR_IA32_SPEC_CTRL             0x00000048      /* Speculation Control */
 #define SPEC_CTRL_IBRS                 (1 << 0)        /* Indirect Branch Restricted Speculation */
 #define SPEC_CTRL_STIBP                        (1 << 1)        /* Single Thread Indirect Branch Predictors */
+#define SPEC_CTRL_RDS                  (1 << 2)        /* Reduced Data Speculation */
 
 #define MSR_IA32_PRED_CMD              0x00000049      /* Prediction Command */
 #define PRED_CMD_IBPB                  (1 << 0)        /* Indirect Branch Prediction Barrier */
 #define MSR_IA32_ARCH_CAPABILITIES     0x0000010a
 #define ARCH_CAP_RDCL_NO               (1 << 0)        /* Not susceptible to Meltdown */
 #define ARCH_CAP_IBRS_ALL              (1 << 1)        /* Enhanced IBRS support */
+#define ARCH_CAP_RDS_NO                        (1 << 4)        /*
+                                                        * Not susceptible to Speculative Store Bypass
+                                                        * attack, so no Reduced Data Speculation control
+                                                        * required.
+                                                        */
 
 #define MSR_IA32_BBL_CR_CTL            0x00000119
 #define MSR_IA32_BBL_CR_CTL3           0x0000011e
index 2e99df202a96912c4ac2049b97c775feee5cae19..ff7310df7437434217b61d5b7ef5285e590df2ad 100644 (file)
@@ -116,7 +116,7 @@ static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE;
 
 void x86_spec_ctrl_set(u64 val)
 {
-       if (val & ~SPEC_CTRL_IBRS)
+       if (val & ~(SPEC_CTRL_IBRS | SPEC_CTRL_RDS))
                WARN_ONCE(1, "SPEC_CTRL MSR value 0x%16llx is unknown.\n", val);
        else
                wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base | val);
@@ -403,8 +403,28 @@ static enum ssb_mitigation_cmd __init __ssb_select_mitigation(void)
                break;
        }
 
-       if (mode != SPEC_STORE_BYPASS_NONE)
+       /*
+        * We have three CPU feature flags that are in play here:
+        *  - X86_BUG_SPEC_STORE_BYPASS - CPU is susceptible.
+        *  - X86_FEATURE_RDS - CPU is able to turn off speculative store bypass
+        *  - X86_FEATURE_SPEC_STORE_BYPASS_DISABLE - engage the mitigation
+        */
+       if (mode != SPEC_STORE_BYPASS_NONE) {
                setup_force_cpu_cap(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE);
+               /*
+                * Intel uses the SPEC CTRL MSR Bit(2) for this, while AMD uses
+                * a completely different MSR and bit dependent on family.
+                */
+               switch (boot_cpu_data.x86_vendor) {
+               case X86_VENDOR_INTEL:
+                       x86_spec_ctrl_base |= SPEC_CTRL_RDS;
+                       x86_spec_ctrl_set(SPEC_CTRL_RDS);
+                       break;
+               case X86_VENDOR_AMD:
+                       break;
+               }
+       }
+
        return mode;
 }
 
@@ -418,6 +438,12 @@ static void ssb_select_mitigation()
 
 #undef pr_fmt
 
+void x86_spec_ctrl_setup_ap(void)
+{
+       if (ibrs_inuse)
+               x86_spec_ctrl_set(x86_spec_ctrl_base & (SPEC_CTRL_IBRS | SPEC_CTRL_RDS));
+}
+
 #ifdef CONFIG_SYSFS
 ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
                        char *buf, unsigned int bug)
index 49e30d6b90f8e1603f9d0368ddc0b11c525b5df6..af6445d0adb6ddf682152f8aec3fb522b4743211 100644 (file)
@@ -896,7 +896,11 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
 {
        u64 ia32_cap = 0;
 
-       if (!x86_match_cpu(cpu_no_spec_store_bypass))
+       if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES))
+               rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap);
+
+       if (!x86_match_cpu(cpu_no_spec_store_bypass) &&
+          !(ia32_cap & ARCH_CAP_RDS_NO))
                setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS);
 
        if (x86_match_cpu(cpu_no_speculation))
@@ -908,9 +912,6 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
        if (x86_match_cpu(cpu_no_meltdown))
                return;
 
-       if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES))
-               rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap);
-
        /* Rogue Data Cache Load? No! */
        if (ia32_cap & ARCH_CAP_RDCL_NO)
                return;
@@ -1316,6 +1317,7 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c)
 #endif
        mtrr_ap_init();
        validate_apic_and_package_id(c);
+       x86_spec_ctrl_setup_ap();
 }
 
 static __init int setup_noclflush(char *arg)
index 6fb25f584c0282b5ac24c15a67e3102285eb2ccb..0f87daa38af5664147d08d5404bf4e0f19c1fb77 100644 (file)
@@ -49,4 +49,6 @@ extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
 
 unsigned int aperfmperf_get_khz(int cpu);
 
+extern void x86_spec_ctrl_setup_ap(void);
+
 #endif /* ARCH_X86_CPU_H */