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>
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[];
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();
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();
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.
#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>
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
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);