| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
- From: Tim Chen <[email protected]>
- 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 <[email protected]>
- Signed-off-by: Andy Whitcroft <[email protected]>
- Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
- (cherry picked from commit 5521b04afda1d683c1ebad6c25c2529a88e6f061)
- Signed-off-by: Fabian Grünbichler <[email protected]>
- ---
- 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
|