From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from localhost ([127.0.0.1] helo=nanos.tec.linutronix.de) by Galois.linutronix.de with esmtp (Exim 4.80) (envelope-from ) id 1fCsWw-0002XO-7G for speck@linutronix.de; Sun, 29 Apr 2018 22:02:42 +0200 Message-Id: <20180429193937.704474597@linutronix.de> Date: Sun, 29 Apr 2018 21:30:48 +0200 From: Thomas Gleixner References: <20180429193045.711908246@linutronix.de> MIME-Version: 1.0 Subject: [patch V7 03/15] SBB 3 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit To: speck@linutronix.de List-ID: 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 ] Suggested-by: Jon Masters Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Thomas Gleixner Reviewed-by: Borislav Petkov --- arch/x86/include/asm/nospec-branch.h | 25 +++++++++++++++++++++---- arch/x86/kernel/cpu/bugs.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -217,6 +217,17 @@ enum spectre_v2_mitigation { SPECTRE_V2_IBRS, }; +/* + * 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_set_spec_ctrl(u64); +extern u64 x86_get_default_spec_ctrl(void); + extern char __indirect_thunk_start[]; extern char __indirect_thunk_end[]; @@ -248,12 +259,14 @@ static inline void vmexit_fill_RSB(void) "movl $0, %%edx\n\t" \ "wrmsr", \ _feature) \ - : : [msr] "i" (_msr), [val] "i" (_val) \ + : : [msr] "i" (_msr), [val] "m" (_val) \ : "eax", "ecx", "edx", "memory") static inline void indirect_branch_prediction_barrier(void) { - alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB, + u64 val = PRED_CMD_IBPB; + + alternative_msr_write(MSR_IA32_PRED_CMD, val, X86_FEATURE_USE_IBPB); } @@ -265,14 +278,18 @@ static inline void indirect_branch_predi */ #define firmware_restrict_branch_speculation_start() \ do { \ + u64 val = x86_get_default_spec_ctrl() | SPEC_CTRL_IBRS; \ + \ preempt_disable(); \ - alternative_msr_write(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS, \ + alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \ X86_FEATURE_USE_IBRS_FW); \ } while (0) #define firmware_restrict_branch_speculation_end() \ do { \ - alternative_msr_write(MSR_IA32_SPEC_CTRL, 0, \ + u64 val = x86_get_default_spec_ctrl(); \ + \ + alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \ X86_FEATURE_USE_IBRS_FW); \ preempt_enable(); \ } while (0) --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -28,6 +28,12 @@ static void __init spectre_v2_select_mitigation(void); +/* + * Our boot-time value of SPEC_CTRL MSR. We read it once so that any + * writes to SPEC_CTRL contain whatever reserved bits have been set. + */ +static u64 __ro_after_init x86_spec_ctrl_base; + void __init check_bugs(void) { identify_boot_cpu(); @@ -37,6 +43,13 @@ void __init check_bugs(void) print_cpu_info(&boot_cpu_data); } + /* + * 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(); @@ -95,6 +108,21 @@ static const char *spectre_v2_strings[] static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE; +void x86_set_spec_ctrl(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_set_spec_ctrl); + +u64 x86_get_default_spec_ctrl(void) +{ + return x86_spec_ctrl_base; +} +EXPORT_SYMBOL_GPL(x86_get_default_spec_ctrl); + #ifdef RETPOLINE static bool spectre_v2_bad_module;