a0f7ab8a6a
cherry-pick from upstream 4.14
118 lines
3.6 KiB
Diff
118 lines
3.6 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Tim Chen <tim.c.chen@linux.intel.com>
|
|
Date: Mon, 6 Nov 2017 18:19:14 -0800
|
|
Subject: [PATCH] x86/idle: Disable IBRS entering idle and enable it on wakeup
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
CVE-2017-5753
|
|
CVE-2017-5715
|
|
|
|
Clear IBRS on idle entry and set it on idle exit into kernel on mwait.
|
|
|
|
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
|
|
Signed-off-by: Andy Whitcroft <apw@canonical.com>
|
|
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
|
|
(cherry picked from commit 5521b04afda1d683c1ebad6c25c2529a88e6f061)
|
|
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
|
---
|
|
arch/x86/include/asm/mwait.h | 8 ++++++++
|
|
arch/x86/kernel/process.c | 12 ++++++++++--
|
|
arch/x86/lib/delay.c | 10 ++++++++++
|
|
3 files changed, 28 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h
|
|
index bda3c27f0da0..f15120ada161 100644
|
|
--- a/arch/x86/include/asm/mwait.h
|
|
+++ b/arch/x86/include/asm/mwait.h
|
|
@@ -5,6 +5,8 @@
|
|
#include <linux/sched/idle.h>
|
|
|
|
#include <asm/cpufeature.h>
|
|
+#include <asm/spec_ctrl.h>
|
|
+#include <asm/microcode.h>
|
|
|
|
#define MWAIT_SUBSTATE_MASK 0xf
|
|
#define MWAIT_CSTATE_MASK 0xf
|
|
@@ -105,9 +107,15 @@ static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
|
|
mb();
|
|
}
|
|
|
|
+ if (boot_cpu_has(X86_FEATURE_SPEC_CTRL))
|
|
+ native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
|
|
+
|
|
__monitor((void *)¤t_thread_info()->flags, 0, 0);
|
|
if (!need_resched())
|
|
__mwait(eax, ecx);
|
|
+
|
|
+ if (boot_cpu_has(X86_FEATURE_SPEC_CTRL))
|
|
+ native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS);
|
|
}
|
|
current_clr_polling();
|
|
}
|
|
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
|
|
index 07e6218ad7d9..3adb3806a284 100644
|
|
--- a/arch/x86/kernel/process.c
|
|
+++ b/arch/x86/kernel/process.c
|
|
@@ -447,11 +447,19 @@ static __cpuidle void mwait_idle(void)
|
|
mb(); /* quirk */
|
|
}
|
|
|
|
+ if (boot_cpu_has(X86_FEATURE_SPEC_CTRL))
|
|
+ native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
|
|
+
|
|
__monitor((void *)¤t_thread_info()->flags, 0, 0);
|
|
- if (!need_resched())
|
|
+ if (!need_resched()) {
|
|
__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();
|
|
+ }
|
|
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
|
|
} else {
|
|
local_irq_enable();
|
|
diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c
|
|
index cf2ac227c2ac..b088463973e4 100644
|
|
--- a/arch/x86/lib/delay.c
|
|
+++ b/arch/x86/lib/delay.c
|
|
@@ -26,6 +26,8 @@
|
|
# include <asm/smp.h>
|
|
#endif
|
|
|
|
+#define IBRS_DISABLE_THRESHOLD 1000
|
|
+
|
|
/* simple loop based delay: */
|
|
static void delay_loop(unsigned long loops)
|
|
{
|
|
@@ -105,6 +107,10 @@ static void delay_mwaitx(unsigned long __loops)
|
|
for (;;) {
|
|
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_rw as a cacheline-aligned, seldomly
|
|
* accessed per-cpu variable as the monitor target.
|
|
@@ -118,6 +124,10 @@ static void delay_mwaitx(unsigned long __loops)
|
|
*/
|
|
__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();
|
|
|
|
if (loops <= end - start)
|
|
--
|
|
2.14.2
|
|
|