]>
Commit | Line | Data |
---|---|---|
035dbe67 FG |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Tim Chen <tim.c.chen@linux.intel.com> | |
3 | Date: Mon, 6 Nov 2017 18:19:14 -0800 | |
4 | Subject: [PATCH] x86/idle: Disable IBRS entering idle and enable it on wakeup | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | CVE-2017-5753 | |
10 | CVE-2017-5715 | |
11 | ||
12 | Clear IBRS on idle entry and set it on idle exit into kernel on mwait. | |
13 | ||
14 | Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com> | |
15 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
16 | Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> | |
17 | (cherry picked from commit 5521b04afda1d683c1ebad6c25c2529a88e6f061) | |
18 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
19 | --- | |
20 | arch/x86/include/asm/mwait.h | 8 ++++++++ | |
21 | arch/x86/kernel/process.c | 12 ++++++++++-- | |
22 | arch/x86/lib/delay.c | 10 ++++++++++ | |
23 | 3 files changed, 28 insertions(+), 2 deletions(-) | |
24 | ||
25 | diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h | |
26 | index bda3c27f0da0..f15120ada161 100644 | |
27 | --- a/arch/x86/include/asm/mwait.h | |
28 | +++ b/arch/x86/include/asm/mwait.h | |
29 | @@ -5,6 +5,8 @@ | |
30 | #include <linux/sched/idle.h> | |
31 | ||
32 | #include <asm/cpufeature.h> | |
33 | +#include <asm/spec_ctrl.h> | |
34 | +#include <asm/microcode.h> | |
35 | ||
36 | #define MWAIT_SUBSTATE_MASK 0xf | |
37 | #define MWAIT_CSTATE_MASK 0xf | |
38 | @@ -105,9 +107,15 @@ static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) | |
39 | mb(); | |
40 | } | |
41 | ||
42 | + if (boot_cpu_has(X86_FEATURE_SPEC_CTRL)) | |
43 | + native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); | |
44 | + | |
45 | __monitor((void *)¤t_thread_info()->flags, 0, 0); | |
46 | if (!need_resched()) | |
47 | __mwait(eax, ecx); | |
48 | + | |
49 | + if (boot_cpu_has(X86_FEATURE_SPEC_CTRL)) | |
50 | + native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS); | |
51 | } | |
52 | current_clr_polling(); | |
53 | } | |
54 | diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c | |
55 | index 07e6218ad7d9..3adb3806a284 100644 | |
56 | --- a/arch/x86/kernel/process.c | |
57 | +++ b/arch/x86/kernel/process.c | |
58 | @@ -447,11 +447,19 @@ static __cpuidle void mwait_idle(void) | |
59 | mb(); /* quirk */ | |
60 | } | |
61 | ||
62 | + if (boot_cpu_has(X86_FEATURE_SPEC_CTRL)) | |
63 | + native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); | |
64 | + | |
65 | __monitor((void *)¤t_thread_info()->flags, 0, 0); | |
66 | - if (!need_resched()) | |
67 | + if (!need_resched()) { | |
68 | __sti_mwait(0, 0); | |
69 | - else | |
70 | + if (boot_cpu_has(X86_FEATURE_SPEC_CTRL)) | |
71 | + native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS); | |
72 | + } else { | |
73 | + if (boot_cpu_has(X86_FEATURE_SPEC_CTRL)) | |
74 | + native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS); | |
75 | local_irq_enable(); | |
76 | + } | |
77 | trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); | |
78 | } else { | |
79 | local_irq_enable(); | |
80 | diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c | |
81 | index cf2ac227c2ac..b088463973e4 100644 | |
82 | --- a/arch/x86/lib/delay.c | |
83 | +++ b/arch/x86/lib/delay.c | |
84 | @@ -26,6 +26,8 @@ | |
85 | # include <asm/smp.h> | |
86 | #endif | |
87 | ||
88 | +#define IBRS_DISABLE_THRESHOLD 1000 | |
89 | + | |
90 | /* simple loop based delay: */ | |
91 | static void delay_loop(unsigned long loops) | |
92 | { | |
93 | @@ -105,6 +107,10 @@ static void delay_mwaitx(unsigned long __loops) | |
94 | for (;;) { | |
95 | delay = min_t(u64, MWAITX_MAX_LOOPS, loops); | |
96 | ||
97 | + if (boot_cpu_has(X86_FEATURE_SPEC_CTRL) && | |
98 | + (delay > IBRS_DISABLE_THRESHOLD)) | |
99 | + native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); | |
100 | + | |
101 | /* | |
102 | * Use cpu_tss_rw as a cacheline-aligned, seldomly | |
103 | * accessed per-cpu variable as the monitor target. | |
104 | @@ -118,6 +124,10 @@ static void delay_mwaitx(unsigned long __loops) | |
105 | */ | |
106 | __mwaitx(MWAITX_DISABLE_CSTATES, delay, MWAITX_ECX_TIMER_ENABLE); | |
107 | ||
108 | + if (boot_cpu_has(X86_FEATURE_SPEC_CTRL) && | |
109 | + (delay > IBRS_DISABLE_THRESHOLD)) | |
110 | + native_wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS); | |
111 | + | |
112 | end = rdtsc_ordered(); | |
113 | ||
114 | if (loops <= end - start) | |
115 | -- | |
116 | 2.14.2 | |
117 |