]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.4/x86-speculation-add-prctl-control-for-indirect-branch-speculation.patch
4.4-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.4 / x86-speculation-add-prctl-control-for-indirect-branch-speculation.patch
1 From foo@baz Tue 14 May 2019 08:29:35 PM CEST
2 From: Thomas Gleixner <tglx@linutronix.de>
3 Date: Sun, 25 Nov 2018 19:33:53 +0100
4 Subject: x86/speculation: Add prctl() control for indirect branch speculation
5
6 From: Thomas Gleixner <tglx@linutronix.de>
7
8 commit 9137bb27e60e554dab694eafa4cca241fa3a694f upstream.
9
10 Add the PR_SPEC_INDIRECT_BRANCH option for the PR_GET_SPECULATION_CTRL and
11 PR_SET_SPECULATION_CTRL prctls to allow fine grained per task control of
12 indirect branch speculation via STIBP and IBPB.
13
14 Invocations:
15 Check indirect branch speculation status with
16 - prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, 0, 0, 0);
17
18 Enable indirect branch speculation with
19 - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_ENABLE, 0, 0);
20
21 Disable indirect branch speculation with
22 - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_DISABLE, 0, 0);
23
24 Force disable indirect branch speculation with
25 - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_FORCE_DISABLE, 0, 0);
26
27 See Documentation/userspace-api/spec_ctrl.rst.
28
29 Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
30 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
31 Reviewed-by: Ingo Molnar <mingo@kernel.org>
32 Cc: Peter Zijlstra <peterz@infradead.org>
33 Cc: Andy Lutomirski <luto@kernel.org>
34 Cc: Linus Torvalds <torvalds@linux-foundation.org>
35 Cc: Jiri Kosina <jkosina@suse.cz>
36 Cc: Tom Lendacky <thomas.lendacky@amd.com>
37 Cc: Josh Poimboeuf <jpoimboe@redhat.com>
38 Cc: Andrea Arcangeli <aarcange@redhat.com>
39 Cc: David Woodhouse <dwmw@amazon.co.uk>
40 Cc: Andi Kleen <ak@linux.intel.com>
41 Cc: Dave Hansen <dave.hansen@intel.com>
42 Cc: Casey Schaufler <casey.schaufler@intel.com>
43 Cc: Asit Mallick <asit.k.mallick@intel.com>
44 Cc: Arjan van de Ven <arjan@linux.intel.com>
45 Cc: Jon Masters <jcm@redhat.com>
46 Cc: Waiman Long <longman9394@gmail.com>
47 Cc: Greg KH <gregkh@linuxfoundation.org>
48 Cc: Dave Stewart <david.c.stewart@intel.com>
49 Cc: Kees Cook <keescook@chromium.org>
50 Link: https://lkml.kernel.org/r/20181125185005.866780996@linutronix.de
51 [bwh: Backported to 4.4:
52 - Renumber the PFA flags
53 - Drop changes in tools/include/uapi/linux/prctl.h
54 - Adjust filename]
55 Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
56 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
57 ---
58 Documentation/spec_ctrl.txt | 9 ++++
59 arch/x86/include/asm/nospec-branch.h | 1
60 arch/x86/kernel/cpu/bugs.c | 67 +++++++++++++++++++++++++++++++++++
61 arch/x86/kernel/process.c | 5 ++
62 include/linux/sched.h | 9 ++++
63 include/uapi/linux/prctl.h | 1
64 6 files changed, 92 insertions(+)
65
66 --- a/Documentation/spec_ctrl.txt
67 +++ b/Documentation/spec_ctrl.txt
68 @@ -92,3 +92,12 @@ Speculation misfeature controls
69 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0);
70 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0);
71 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0);
72 +
73 +- PR_SPEC_INDIR_BRANCH: Indirect Branch Speculation in User Processes
74 + (Mitigate Spectre V2 style attacks against user processes)
75 +
76 + Invocations:
77 + * prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, 0, 0, 0);
78 + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_ENABLE, 0, 0);
79 + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_DISABLE, 0, 0);
80 + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_FORCE_DISABLE, 0, 0);
81 --- a/arch/x86/include/asm/nospec-branch.h
82 +++ b/arch/x86/include/asm/nospec-branch.h
83 @@ -178,6 +178,7 @@ enum spectre_v2_mitigation {
84 enum spectre_v2_user_mitigation {
85 SPECTRE_V2_USER_NONE,
86 SPECTRE_V2_USER_STRICT,
87 + SPECTRE_V2_USER_PRCTL,
88 };
89
90 /* The Speculative Store Bypass disable variants */
91 --- a/arch/x86/kernel/cpu/bugs.c
92 +++ b/arch/x86/kernel/cpu/bugs.c
93 @@ -561,6 +561,8 @@ void arch_smt_update(void)
94 case SPECTRE_V2_USER_STRICT:
95 update_stibp_strict();
96 break;
97 + case SPECTRE_V2_USER_PRCTL:
98 + break;
99 }
100
101 mutex_unlock(&spec_ctrl_mutex);
102 @@ -747,12 +749,50 @@ static int ssb_prctl_set(struct task_str
103 return 0;
104 }
105
106 +static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
107 +{
108 + switch (ctrl) {
109 + case PR_SPEC_ENABLE:
110 + if (spectre_v2_user == SPECTRE_V2_USER_NONE)
111 + return 0;
112 + /*
113 + * Indirect branch speculation is always disabled in strict
114 + * mode.
115 + */
116 + if (spectre_v2_user == SPECTRE_V2_USER_STRICT)
117 + return -EPERM;
118 + task_clear_spec_ib_disable(task);
119 + task_update_spec_tif(task);
120 + break;
121 + case PR_SPEC_DISABLE:
122 + case PR_SPEC_FORCE_DISABLE:
123 + /*
124 + * Indirect branch speculation is always allowed when
125 + * mitigation is force disabled.
126 + */
127 + if (spectre_v2_user == SPECTRE_V2_USER_NONE)
128 + return -EPERM;
129 + if (spectre_v2_user == SPECTRE_V2_USER_STRICT)
130 + return 0;
131 + task_set_spec_ib_disable(task);
132 + if (ctrl == PR_SPEC_FORCE_DISABLE)
133 + task_set_spec_ib_force_disable(task);
134 + task_update_spec_tif(task);
135 + break;
136 + default:
137 + return -ERANGE;
138 + }
139 + return 0;
140 +}
141 +
142 int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
143 unsigned long ctrl)
144 {
145 switch (which) {
146 case PR_SPEC_STORE_BYPASS:
147 return ssb_prctl_set(task, ctrl);
148 + case PR_SPEC_INDIRECT_BRANCH:
149 + return ib_prctl_set(task, ctrl);
150 default:
151 return -ENODEV;
152 }
153 @@ -785,11 +825,34 @@ static int ssb_prctl_get(struct task_str
154 }
155 }
156
157 +static int ib_prctl_get(struct task_struct *task)
158 +{
159 + if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
160 + return PR_SPEC_NOT_AFFECTED;
161 +
162 + switch (spectre_v2_user) {
163 + case SPECTRE_V2_USER_NONE:
164 + return PR_SPEC_ENABLE;
165 + case SPECTRE_V2_USER_PRCTL:
166 + if (task_spec_ib_force_disable(task))
167 + return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
168 + if (task_spec_ib_disable(task))
169 + return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
170 + return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
171 + case SPECTRE_V2_USER_STRICT:
172 + return PR_SPEC_DISABLE;
173 + default:
174 + return PR_SPEC_NOT_AFFECTED;
175 + }
176 +}
177 +
178 int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
179 {
180 switch (which) {
181 case PR_SPEC_STORE_BYPASS:
182 return ssb_prctl_get(task);
183 + case PR_SPEC_INDIRECT_BRANCH:
184 + return ib_prctl_get(task);
185 default:
186 return -ENODEV;
187 }
188 @@ -886,6 +949,8 @@ static char *stibp_state(void)
189 return ", STIBP: disabled";
190 case SPECTRE_V2_USER_STRICT:
191 return ", STIBP: forced";
192 + case SPECTRE_V2_USER_PRCTL:
193 + return "";
194 }
195 return "";
196 }
197 @@ -898,6 +963,8 @@ static char *ibpb_state(void)
198 return ", IBPB: disabled";
199 case SPECTRE_V2_USER_STRICT:
200 return ", IBPB: always-on";
201 + case SPECTRE_V2_USER_PRCTL:
202 + return "";
203 }
204 }
205 return "";
206 --- a/arch/x86/kernel/process.c
207 +++ b/arch/x86/kernel/process.c
208 @@ -372,6 +372,11 @@ static unsigned long speculation_ctrl_up
209 set_tsk_thread_flag(tsk, TIF_SSBD);
210 else
211 clear_tsk_thread_flag(tsk, TIF_SSBD);
212 +
213 + if (task_spec_ib_disable(tsk))
214 + set_tsk_thread_flag(tsk, TIF_SPEC_IB);
215 + else
216 + clear_tsk_thread_flag(tsk, TIF_SPEC_IB);
217 }
218 /* Return the updated threadinfo flags*/
219 return task_thread_info(tsk)->flags;
220 --- a/include/linux/sched.h
221 +++ b/include/linux/sched.h
222 @@ -2169,6 +2169,8 @@ static inline void memalloc_noio_restore
223 #define PFA_SPREAD_SLAB 2 /* Spread some slab caches over cpuset */
224 #define PFA_SPEC_SSB_DISABLE 4 /* Speculative Store Bypass disabled */
225 #define PFA_SPEC_SSB_FORCE_DISABLE 5 /* Speculative Store Bypass force disabled*/
226 +#define PFA_SPEC_IB_DISABLE 6 /* Indirect branch speculation restricted */
227 +#define PFA_SPEC_IB_FORCE_DISABLE 7 /* Indirect branch speculation permanently restricted */
228
229
230 #define TASK_PFA_TEST(name, func) \
231 @@ -2199,6 +2201,13 @@ TASK_PFA_CLEAR(SPEC_SSB_DISABLE, spec_ss
232 TASK_PFA_TEST(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable)
233 TASK_PFA_SET(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable)
234
235 +TASK_PFA_TEST(SPEC_IB_DISABLE, spec_ib_disable)
236 +TASK_PFA_SET(SPEC_IB_DISABLE, spec_ib_disable)
237 +TASK_PFA_CLEAR(SPEC_IB_DISABLE, spec_ib_disable)
238 +
239 +TASK_PFA_TEST(SPEC_IB_FORCE_DISABLE, spec_ib_force_disable)
240 +TASK_PFA_SET(SPEC_IB_FORCE_DISABLE, spec_ib_force_disable)
241 +
242 /*
243 * task->jobctl flags
244 */
245 --- a/include/uapi/linux/prctl.h
246 +++ b/include/uapi/linux/prctl.h
247 @@ -202,6 +202,7 @@ struct prctl_mm_map {
248 #define PR_SET_SPECULATION_CTRL 53
249 /* Speculation control variants */
250 # define PR_SPEC_STORE_BYPASS 0
251 +# define PR_SPEC_INDIRECT_BRANCH 1
252 /* Return and control values for PR_SET/GET_SPECULATION_CTRL */
253 # define PR_SPEC_NOT_AFFECTED 0
254 # define PR_SPEC_PRCTL (1UL << 0)