Commit f3b21b13 authored by Stefan Bader's avatar Stefan Bader Committed by Juerg Haefliger

UBUNTU: SAUCE: x86/bugs: Honour SPEC_CTRL default

CVE-2018-3639 (x86)

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.
Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
[juergh: Context adjustments.]
Signed-off-by: default avatarJuerg Haefliger <juergh@canonical.com>
parent 9e7870a1
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/spec_ctrl.h> #include <asm/spec_ctrl.h>
#include <asm/spec-ctrl.h>
#include <asm/microcode.h> #include <asm/microcode.h>
#define MWAIT_SUBSTATE_MASK 0xf #define MWAIT_SUBSTATE_MASK 0xf
...@@ -107,14 +108,14 @@ static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) ...@@ -107,14 +108,14 @@ static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
} }
if (ibrs_inuse) if (ibrs_inuse)
native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default());
__monitor((void *)&current_thread_info()->flags, 0, 0); __monitor((void *)&current_thread_info()->flags, 0, 0);
if (!need_resched()) if (!need_resched())
__mwait(eax, ecx); __mwait(eax, ecx);
if (ibrs_inuse) if (ibrs_inuse)
native_wrmsrl(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS); native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS);
} }
current_clr_polling(); current_clr_polling();
} }
......
...@@ -455,16 +455,16 @@ static void mwait_idle(void) ...@@ -455,16 +455,16 @@ static void mwait_idle(void)
} }
if (ibrs_inuse) if (ibrs_inuse)
native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default());
__monitor((void *)&current_thread_info()->flags, 0, 0); __monitor((void *)&current_thread_info()->flags, 0, 0);
if (!need_resched()) { if (!need_resched()) {
__sti_mwait(0, 0); __sti_mwait(0, 0);
if (ibrs_inuse) if (ibrs_inuse)
native_wrmsrl(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS); native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS);
} else { } else {
if (ibrs_inuse) if (ibrs_inuse)
native_wrmsrl(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS); native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS);
local_irq_enable(); local_irq_enable();
} }
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
......
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
#include <asm/i8259.h> #include <asm/i8259.h>
#include <asm/realmode.h> #include <asm/realmode.h>
#include <asm/misc.h> #include <asm/misc.h>
#include <asm/spec-ctrl.h>
#include <asm/microcode.h> #include <asm/microcode.h>
/* Number of siblings per CPU package */ /* Number of siblings per CPU package */
...@@ -1649,14 +1650,14 @@ void native_play_dead(void) ...@@ -1649,14 +1650,14 @@ void native_play_dead(void)
tboot_shutdown(TB_SHUTDOWN_WFS); tboot_shutdown(TB_SHUTDOWN_WFS);
if (ibrs_inuse) 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 */ mwait_play_dead(); /* Only returns on failure */
if (cpuidle_play_dead()) if (cpuidle_play_dead())
hlt_play_dead(); hlt_play_dead();
if (ibrs_inuse) if (ibrs_inuse)
native_wrmsrl(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS); native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS);
} }
#else /* ... !CONFIG_HOTPLUG_CPU */ #else /* ... !CONFIG_HOTPLUG_CPU */
......
...@@ -108,7 +108,7 @@ static void delay_mwaitx(unsigned long __loops) ...@@ -108,7 +108,7 @@ static void delay_mwaitx(unsigned long __loops)
delay = min_t(u64, MWAITX_MAX_LOOPS, loops); delay = min_t(u64, MWAITX_MAX_LOOPS, loops);
if (ibrs_inuse && (delay > IBRS_DISABLE_THRESHOLD)) 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 as a cacheline-aligned, seldomly * Use cpu_tss as a cacheline-aligned, seldomly
...@@ -124,7 +124,7 @@ static void delay_mwaitx(unsigned long __loops) ...@@ -124,7 +124,7 @@ static void delay_mwaitx(unsigned long __loops)
__mwaitx(MWAITX_DISABLE_CSTATES, delay, MWAITX_ECX_TIMER_ENABLE); __mwaitx(MWAITX_DISABLE_CSTATES, delay, MWAITX_ECX_TIMER_ENABLE);
if (ibrs_inuse && (delay > IBRS_DISABLE_THRESHOLD)) if (ibrs_inuse && (delay > IBRS_DISABLE_THRESHOLD))
native_wrmsrl(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS); native_wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS);
end = rdtsc_ordered(); end = rdtsc_ordered();
......
...@@ -77,6 +77,7 @@ ...@@ -77,6 +77,7 @@
#include <asm/nmi.h> #include <asm/nmi.h>
#include <asm/stacktrace.h> #include <asm/stacktrace.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/spec-ctrl.h>
#endif #endif
#ifdef CONFIG_SPARC #ifdef CONFIG_SPARC
#include <asm/setup.h> #include <asm/setup.h>
...@@ -2425,14 +2426,14 @@ int proc_dointvec_ibrs_ctrl(struct ctl_table *table, int write, ...@@ -2425,14 +2426,14 @@ int proc_dointvec_ibrs_ctrl(struct ctl_table *table, int write,
set_ibrs_disabled(); set_ibrs_disabled();
if (ibrs_supported) { if (ibrs_supported) {
for_each_online_cpu(cpu) 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) { } else if (sysctl_ibrs_enabled == 2) {
/* always set IBRS on, even in user space */ /* always set IBRS on, even in user space */
clear_ibrs_disabled(); clear_ibrs_disabled();
if (ibrs_supported) { if (ibrs_supported) {
for_each_online_cpu(cpu) for_each_online_cpu(cpu)
wrmsrl_on_cpu(cpu, MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS); wrmsrl_on_cpu(cpu, MSR_IA32_SPEC_CTRL, x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS);
} else { } else {
sysctl_ibrs_enabled = 0; sysctl_ibrs_enabled = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment