]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
x86/bugs: Read SPEC_CTRL MSR during boot and re-use reserved bits
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Sat, 12 May 2018 01:11:04 +0000 (21:11 -0400)
committerBrian Maly <brian.maly@oracle.com>
Mon, 21 May 2018 22:02:18 +0000 (18:02 -0400)
The 336996-Speculative-Execution-Side-Channel-Mitigations.pdf refers to all
the other bits as reserved. The Intel SDM glossary defines reserved as
implementation specific - aka unknown.

As such at bootup this must be taken it into account and proper masking for
the bits in use applied.

A copy of this document is available at
https://bugzilla.kernel.org/show_bug.cgi?id=199511

[ tglx: Made x86_spec_ctrl_base __ro_after_init ]

OraBug: 28041771
CVE: CVE-2018-3639

Suggested-by: Jon Masters <jcm@redhat.com>
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>
(cherry picked from commit 1b86883ccb8d5d9506529d42dbe1a5257cb30b18)
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Mihai Carabas <mihai.carabas@oracle.com>
 Conflicts:
arch/x86/include/asm/nospec-branch.h
[As we don't have the firmware_restrict_branch_speculation_start and
 firmware_restrict_branch_speculation_end and end up with a different
 name. See commit 473ad76ea8d76f34555d764a3d5820bc1b33cabf
 "x86/speculation: Use IBRS if available before calling into firmware"]

arch/x86/kernel/cpu/bugs.c
[File is called bugs_64.c in UEK4]

[Also the backport needs nospec-branch.h in different files ,and we can't
 use __ro_after_init]

Signed-off-by: Brian Maly <brian.maly@oracle.com>
arch/x86/include/asm/nospec-branch.h
arch/x86/kernel/cpu/bugs_64.c
arch/x86/kernel/cpu/spec_ctrl.c

index 6ff030a734b859b4852576aa64891db02fd2b461..abc0e887e06466bbbbacfd270224a4fbcefc6250 100644 (file)
@@ -172,6 +172,17 @@ enum spectre_v2_mitigation {
        SPECTRE_V2_IBRS_LFENCE,
 };
 
+/*
+ * The Intel specification for the SPEC_CTRL MSR requires that we
+ * preserve any already set reserved bits at boot time (e.g. for
+ * future additions that this kernel is not currently aware of).
+ * We then set any additional mitigation bits that we want
+ * ourselves and always use this as the base for SPEC_CTRL.
+ * We also use this when handling guest entry/exit as below.
+ */
+extern void x86_spec_ctrl_set(u64);
+extern u64 x86_spec_ctrl_get_default(void);
+
 extern char __indirect_thunk_start[];
 extern char __indirect_thunk_end[];
 
index 8f7aef4fa946e78a3137c2802d1624dfb049fbd4..33c5ca9a98f88c269daa22ec66234ba7131ddd67 100644 (file)
@@ -96,6 +96,12 @@ __setup("spectre_v2_heuristics=", spectre_v2_heuristics_setup);
 
 static void __init spectre_v2_select_mitigation(void);
 
+/*
+ * Our boot-time value of the SPEC_CTRL MSR. We read it once so that any
+ * writes to SPEC_CTRL contain whatever reserved bits have been set.
+ */
+static u64 x86_spec_ctrl_base;
+
 void __init check_bugs(void)
 {
        identify_boot_cpu();
@@ -103,6 +109,12 @@ void __init check_bugs(void)
        printk(KERN_INFO "CPU: ");
        print_cpu_info(&boot_cpu_data);
 #endif
+       /*
+        * Read the SPEC_CTRL MSR to account for reserved bits which may
+        * have unknown values.
+        */
+       if (boot_cpu_has(X86_FEATURE_IBRS))
+               rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
 
        /* Select the proper spectre mitigation before patching alternatives */
        spectre_v2_select_mitigation();
@@ -164,6 +176,21 @@ static const char *spectre_v2_strings[] = {
 
 static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE;
 
+void x86_spec_ctrl_set(u64 val)
+{
+       if (val & ~SPEC_CTRL_IBRS)
+               WARN_ONCE(1, "SPEC_CTRL MSR value 0x%16llx is unknown.\n", val);
+       else
+               wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base | val);
+}
+EXPORT_SYMBOL_GPL(x86_spec_ctrl_set);
+
+u64 x86_spec_ctrl_get_default(void)
+{
+       return x86_spec_ctrl_base;
+}
+EXPORT_SYMBOL_GPL(x86_spec_ctrl_get_default);
+
 /*
  * Disable retpoline and attempt to fall back to another Spectre v2 mitigation.
  * If possible, fall back to IBRS and IBPB.
index 8f664e6387ff4c3d7c375fbab5a6235f11948c40..2b7a872eff9713c12a7d9d9db9a6412e5f55bd84 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/uaccess.h>
 #include <linux/cpu.h>
 #include <asm/spec_ctrl.h>
+#include <asm/nospec-branch.h>
 #include <asm/cpufeature.h>
 #include <asm/microcode.h>
 
@@ -215,7 +216,9 @@ late_initcall(debugfs_spec_ctrl);
 void unprotected_firmware_begin(void)
 {
         if (retpoline_enabled() && ibrs_firmware) {
-                native_wrmsrl(MSR_IA32_SPEC_CTRL, SPEC_CTRL_FEATURE_ENABLE_IBRS);
+               u64 val = x86_spec_ctrl_get_default() | SPEC_CTRL_FEATURE_ENABLE_IBRS;
+
+               native_wrmsrl(MSR_IA32_SPEC_CTRL, val);
         } else {
                 /*
                  * rmb prevents unwanted speculation when we
@@ -229,7 +232,9 @@ EXPORT_SYMBOL_GPL(unprotected_firmware_begin);
 void unprotected_firmware_end(void)
 {
         if (retpoline_enabled() && ibrs_firmware) {
-                native_wrmsrl(MSR_IA32_SPEC_CTRL, SPEC_CTRL_FEATURE_DISABLE_IBRS);
+               u64 val = x86_spec_ctrl_get_default();
+
+               native_wrmsrl(MSR_IA32_SPEC_CTRL, val);
         }
 }
 EXPORT_SYMBOL_GPL(unprotected_firmware_end);