Commit 0f5bdf22 authored by Tim Chen's avatar Tim Chen Committed by Khalid Elmously

x86/idle: Disable IBRS entering idle and enable it on wakeup

CVE-2017-5715 (Spectre v2 Intel)

Clear IBRS on idle entry and set it on idle exit into kernel on mwait.
Signed-off-by: default avatarTim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: default avatarAndy Whitcroft <apw@canonical.com>
(cherry picked from commit c2a2a232b0553e32a7bfe198a40f377bd1ba016d)
Signed-off-by: default avatarAndy Whitcroft <apw@canonical.com>
Acked-by: default avatarColin Ian King <colin.king@canonical.com>
Acked-by: default avatarKamal Mostafa <kamal@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent 4e4050bd
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/spec_ctrl.h>
#include <asm/microcode.h>
#define MWAIT_SUBSTATE_MASK 0xf #define MWAIT_SUBSTATE_MASK 0xf
#define MWAIT_CSTATE_MASK 0xf #define MWAIT_CSTATE_MASK 0xf
...@@ -104,9 +106,15 @@ static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) ...@@ -104,9 +106,15 @@ static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
mb(); mb();
} }
if (boot_cpu_has(X86_FEATURE_SPEC_CTRL))
native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
__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 (boot_cpu_has(X86_FEATURE_SPEC_CTRL))
native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS);
} }
current_clr_polling(); current_clr_polling();
} }
......
...@@ -424,11 +424,19 @@ static void mwait_idle(void) ...@@ -424,11 +424,19 @@ static void mwait_idle(void)
smp_mb(); /* quirk */ smp_mb(); /* quirk */
} }
if (boot_cpu_has(X86_FEATURE_SPEC_CTRL))
native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
__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);
else if (boot_cpu_has(X86_FEATURE_SPEC_CTRL))
native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS);
} else {
if (boot_cpu_has(X86_FEATURE_SPEC_CTRL))
native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_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());
} else { } else {
local_irq_enable(); local_irq_enable();
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
# include <asm/smp.h> # include <asm/smp.h>
#endif #endif
#define IBRS_DISABLE_THRESHOLD 1000
/* simple loop based delay: */ /* simple loop based delay: */
static void delay_loop(unsigned long loops) static void delay_loop(unsigned long loops)
{ {
...@@ -98,6 +100,10 @@ static void delay_mwaitx(unsigned long __loops) ...@@ -98,6 +100,10 @@ static void delay_mwaitx(unsigned long __loops)
for (;;) { for (;;) {
delay = min_t(u64, MWAITX_MAX_LOOPS, loops); delay = min_t(u64, MWAITX_MAX_LOOPS, loops);
if (boot_cpu_has(X86_FEATURE_SPEC_CTRL) &&
(delay > IBRS_DISABLE_THRESHOLD))
native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
/* /*
* Use cpu_tss as a cacheline-aligned, seldomly * Use cpu_tss as a cacheline-aligned, seldomly
* accessed per-cpu variable as the monitor target. * accessed per-cpu variable as the monitor target.
...@@ -111,6 +117,10 @@ static void delay_mwaitx(unsigned long __loops) ...@@ -111,6 +117,10 @@ 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 (boot_cpu_has(X86_FEATURE_SPEC_CTRL) &&
(delay > IBRS_DISABLE_THRESHOLD))
native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS);
end = rdtsc_ordered(); end = rdtsc_ordered();
if (loops <= end - start) if (loops <= end - start)
......
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