From: Stefan Bader Date: Mon, 7 May 2018 14:47:02 +0000 (+0200) Subject: UBUNTU: SAUCE: x86/bugs: Honour SPEC_CTRL default X-Git-Tag: Ubuntu-4.13.0-43.48~31 X-Git-Url: https://git.proxmox.com/?p=mirror_ubuntu-artful-kernel.git;a=commitdiff_plain;h=159e800c5ef2b3cd09df71bba42fe9fe1780e45b UBUNTU: SAUCE: x86/bugs: Honour SPEC_CTRL default Upstream implementation reads the content of the SPEC_CTRL MSR once during boot to record the state of reserved bits. Any access to this MSR (to enable/disable IBRS) needs to preserve those reserved bits. This tries to catch and convert all occurrances of the Intel based IBRS changes we carry. CVE-2018-3639 (x86) Signed-off-by: Stefan Bader --- diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index d665daab3f84..82c66546623a 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -6,6 +6,7 @@ #include #include +#include #include #define MWAIT_SUBSTATE_MASK 0xf @@ -108,14 +109,14 @@ static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) } if (ibrs_inuse) - native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); + native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default()); __monitor((void *)¤t_thread_info()->flags, 0, 0); if (!need_resched()) __mwait(eax, ecx); if (ibrs_inuse) - native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS); + native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS); } current_clr_polling(); } diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index d4dffef4f33d..a49c82cef307 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -470,16 +470,16 @@ static __cpuidle void mwait_idle(void) } if (ibrs_inuse) - native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); + native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default()); __monitor((void *)¤t_thread_info()->flags, 0, 0); if (!need_resched()) { __sti_mwait(0, 0); if (ibrs_inuse) - native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS); + native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS); } else { if (ibrs_inuse) - native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS); + native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS); local_irq_enable(); } trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 9317aa4a7446..9d35b8471fe8 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -77,6 +77,7 @@ #include #include #include +#include #include /* Number of siblings per CPU package */ @@ -1694,14 +1695,14 @@ void native_play_dead(void) tboot_shutdown(TB_SHUTDOWN_WFS); if (ibrs_inuse) - native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); + native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default()); mwait_play_dead(); /* Only returns on failure */ if (cpuidle_play_dead()) hlt_play_dead(); if (ibrs_inuse) - native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS); + native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS); } #else /* ... !CONFIG_HOTPLUG_CPU */ diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c index 72a174642550..c12988c7a267 100644 --- a/arch/x86/lib/delay.c +++ b/arch/x86/lib/delay.c @@ -108,7 +108,7 @@ static void delay_mwaitx(unsigned long __loops) delay = min_t(u64, MWAITX_MAX_LOOPS, loops); if (ibrs_inuse && (delay > IBRS_DISABLE_THRESHOLD)) - native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); + native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default()); /* * Use cpu_tss_rw as a cacheline-aligned, seldomly @@ -124,7 +124,7 @@ static void delay_mwaitx(unsigned long __loops) __mwaitx(MWAITX_DISABLE_CSTATES, delay, MWAITX_ECX_TIMER_ENABLE); if (ibrs_inuse && (delay > IBRS_DISABLE_THRESHOLD)) - native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS); + native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS); end = rdtsc_ordered(); diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 5596940dda98..303532ce1ecc 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -77,6 +77,7 @@ #include #include #include +#include #endif #ifdef CONFIG_SPARC #include @@ -2635,14 +2636,14 @@ int proc_dointvec_ibrs_ctrl(struct ctl_table *table, int write, set_ibrs_disabled(); if (ibrs_supported) { for_each_online_cpu(cpu) - wrmsrl_on_cpu(cpu, MSR_IA32_SPEC_CTRL, 0x0); + wrmsrl_on_cpu(cpu, MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default()); } } else if (sysctl_ibrs_enabled == 2) { /* always set IBRS on, even in user space */ clear_ibrs_disabled(); if (ibrs_supported) { for_each_online_cpu(cpu) - wrmsrl_on_cpu(cpu, MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS); + wrmsrl_on_cpu(cpu, MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS); } else { sysctl_ibrs_enabled = 0; }