pve-kernel-lowlatency-qoup/patches/kernel/0278-x86-idle-Disable-IBRS-entering-idle-and-enable-it-on.patch
Fabian Grünbichler a0f7ab8a6a fix #1622: i40e memory leak
cherry-pick from upstream 4.14
2018-01-19 12:43:16 +01:00

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 *)&current_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 *)&current_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