Annotation of /trunk/kernel-alx/patches-4.9/0200-4.9.101-all-fixes.patch
Parent Directory | Revision Log
Revision 3177 -
(hide annotations)
(download)
Wed Aug 8 14:17:30 2018 UTC (6 years, 1 month ago) by niro
File size: 66199 byte(s)
Wed Aug 8 14:17:30 2018 UTC (6 years, 1 month ago) by niro
File size: 66199 byte(s)
-linux-4.9.101
1 | niro | 3177 | diff --git a/Makefile b/Makefile |
2 | index 52a41396680c..7d7bda23db8f 100644 | ||
3 | --- a/Makefile | ||
4 | +++ b/Makefile | ||
5 | @@ -1,6 +1,6 @@ | ||
6 | VERSION = 4 | ||
7 | PATCHLEVEL = 9 | ||
8 | -SUBLEVEL = 100 | ||
9 | +SUBLEVEL = 101 | ||
10 | EXTRAVERSION = | ||
11 | NAME = Roaring Lionus | ||
12 | |||
13 | diff --git a/arch/alpha/include/asm/futex.h b/arch/alpha/include/asm/futex.h | ||
14 | index f939794363ac..56474690e685 100644 | ||
15 | --- a/arch/alpha/include/asm/futex.h | ||
16 | +++ b/arch/alpha/include/asm/futex.h | ||
17 | @@ -29,18 +29,10 @@ | ||
18 | : "r" (uaddr), "r"(oparg) \ | ||
19 | : "memory") | ||
20 | |||
21 | -static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
22 | +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, | ||
23 | + u32 __user *uaddr) | ||
24 | { | ||
25 | - int op = (encoded_op >> 28) & 7; | ||
26 | - int cmp = (encoded_op >> 24) & 15; | ||
27 | - int oparg = (encoded_op << 8) >> 20; | ||
28 | - int cmparg = (encoded_op << 20) >> 20; | ||
29 | int oldval = 0, ret; | ||
30 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
31 | - oparg = 1 << oparg; | ||
32 | - | ||
33 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | ||
34 | - return -EFAULT; | ||
35 | |||
36 | pagefault_disable(); | ||
37 | |||
38 | @@ -66,17 +58,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
39 | |||
40 | pagefault_enable(); | ||
41 | |||
42 | - if (!ret) { | ||
43 | - switch (cmp) { | ||
44 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
45 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
46 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
47 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
48 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
49 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
50 | - default: ret = -ENOSYS; | ||
51 | - } | ||
52 | - } | ||
53 | + if (!ret) | ||
54 | + *oval = oldval; | ||
55 | + | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | diff --git a/arch/arc/include/asm/futex.h b/arch/arc/include/asm/futex.h | ||
60 | index 11e1b1f3acda..eb887dd13e74 100644 | ||
61 | --- a/arch/arc/include/asm/futex.h | ||
62 | +++ b/arch/arc/include/asm/futex.h | ||
63 | @@ -73,20 +73,11 @@ | ||
64 | |||
65 | #endif | ||
66 | |||
67 | -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
68 | +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, | ||
69 | + u32 __user *uaddr) | ||
70 | { | ||
71 | - int op = (encoded_op >> 28) & 7; | ||
72 | - int cmp = (encoded_op >> 24) & 15; | ||
73 | - int oparg = (encoded_op << 8) >> 20; | ||
74 | - int cmparg = (encoded_op << 20) >> 20; | ||
75 | int oldval = 0, ret; | ||
76 | |||
77 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
78 | - oparg = 1 << oparg; | ||
79 | - | ||
80 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) | ||
81 | - return -EFAULT; | ||
82 | - | ||
83 | #ifndef CONFIG_ARC_HAS_LLSC | ||
84 | preempt_disable(); /* to guarantee atomic r-m-w of futex op */ | ||
85 | #endif | ||
86 | @@ -118,30 +109,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
87 | preempt_enable(); | ||
88 | #endif | ||
89 | |||
90 | - if (!ret) { | ||
91 | - switch (cmp) { | ||
92 | - case FUTEX_OP_CMP_EQ: | ||
93 | - ret = (oldval == cmparg); | ||
94 | - break; | ||
95 | - case FUTEX_OP_CMP_NE: | ||
96 | - ret = (oldval != cmparg); | ||
97 | - break; | ||
98 | - case FUTEX_OP_CMP_LT: | ||
99 | - ret = (oldval < cmparg); | ||
100 | - break; | ||
101 | - case FUTEX_OP_CMP_GE: | ||
102 | - ret = (oldval >= cmparg); | ||
103 | - break; | ||
104 | - case FUTEX_OP_CMP_LE: | ||
105 | - ret = (oldval <= cmparg); | ||
106 | - break; | ||
107 | - case FUTEX_OP_CMP_GT: | ||
108 | - ret = (oldval > cmparg); | ||
109 | - break; | ||
110 | - default: | ||
111 | - ret = -ENOSYS; | ||
112 | - } | ||
113 | - } | ||
114 | + if (!ret) | ||
115 | + *oval = oldval; | ||
116 | + | ||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi | ||
121 | index 47c955458a77..2b9c2be436f9 100644 | ||
122 | --- a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi | ||
123 | +++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi | ||
124 | @@ -88,7 +88,6 @@ | ||
125 | clocks = <&clks IMX6QDL_CLK_CKO>; | ||
126 | VDDA-supply = <®_2p5v>; | ||
127 | VDDIO-supply = <®_3p3v>; | ||
128 | - lrclk-strength = <3>; | ||
129 | }; | ||
130 | }; | ||
131 | |||
132 | diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h | ||
133 | index 6795368ad023..cc414382dab4 100644 | ||
134 | --- a/arch/arm/include/asm/futex.h | ||
135 | +++ b/arch/arm/include/asm/futex.h | ||
136 | @@ -128,20 +128,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | ||
137 | #endif /* !SMP */ | ||
138 | |||
139 | static inline int | ||
140 | -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
141 | +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) | ||
142 | { | ||
143 | - int op = (encoded_op >> 28) & 7; | ||
144 | - int cmp = (encoded_op >> 24) & 15; | ||
145 | - int oparg = (encoded_op << 8) >> 20; | ||
146 | - int cmparg = (encoded_op << 20) >> 20; | ||
147 | int oldval = 0, ret, tmp; | ||
148 | |||
149 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
150 | - oparg = 1 << oparg; | ||
151 | - | ||
152 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | ||
153 | - return -EFAULT; | ||
154 | - | ||
155 | #ifndef CONFIG_SMP | ||
156 | preempt_disable(); | ||
157 | #endif | ||
158 | @@ -172,17 +162,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
159 | preempt_enable(); | ||
160 | #endif | ||
161 | |||
162 | - if (!ret) { | ||
163 | - switch (cmp) { | ||
164 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
165 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
166 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
167 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
168 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
169 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
170 | - default: ret = -ENOSYS; | ||
171 | - } | ||
172 | - } | ||
173 | + if (!ret) | ||
174 | + *oval = oldval; | ||
175 | + | ||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h | ||
180 | index 4e5f36a804b4..2a5090fb9113 100644 | ||
181 | --- a/arch/arm64/include/asm/futex.h | ||
182 | +++ b/arch/arm64/include/asm/futex.h | ||
183 | @@ -51,20 +51,9 @@ | ||
184 | : "memory") | ||
185 | |||
186 | static inline int | ||
187 | -futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *_uaddr) | ||
188 | +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) | ||
189 | { | ||
190 | - int op = (encoded_op >> 28) & 7; | ||
191 | - int cmp = (encoded_op >> 24) & 15; | ||
192 | - int oparg = (int)(encoded_op << 8) >> 20; | ||
193 | - int cmparg = (int)(encoded_op << 20) >> 20; | ||
194 | int oldval = 0, ret, tmp; | ||
195 | - u32 __user *uaddr = __uaccess_mask_ptr(_uaddr); | ||
196 | - | ||
197 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
198 | - oparg = 1U << (oparg & 0x1f); | ||
199 | - | ||
200 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | ||
201 | - return -EFAULT; | ||
202 | |||
203 | pagefault_disable(); | ||
204 | |||
205 | @@ -95,17 +84,9 @@ futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *_uaddr) | ||
206 | |||
207 | pagefault_enable(); | ||
208 | |||
209 | - if (!ret) { | ||
210 | - switch (cmp) { | ||
211 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
212 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
213 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
214 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
215 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
216 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
217 | - default: ret = -ENOSYS; | ||
218 | - } | ||
219 | - } | ||
220 | + if (!ret) | ||
221 | + *oval = oldval; | ||
222 | + | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | diff --git a/arch/frv/include/asm/futex.h b/arch/frv/include/asm/futex.h | ||
227 | index 4bea27f50a7a..2702bd802d44 100644 | ||
228 | --- a/arch/frv/include/asm/futex.h | ||
229 | +++ b/arch/frv/include/asm/futex.h | ||
230 | @@ -7,7 +7,8 @@ | ||
231 | #include <asm/errno.h> | ||
232 | #include <asm/uaccess.h> | ||
233 | |||
234 | -extern int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr); | ||
235 | +extern int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, | ||
236 | + u32 __user *uaddr); | ||
237 | |||
238 | static inline int | ||
239 | futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | ||
240 | diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c | ||
241 | index d155ca9e5098..37f7b2bf7f73 100644 | ||
242 | --- a/arch/frv/kernel/futex.c | ||
243 | +++ b/arch/frv/kernel/futex.c | ||
244 | @@ -186,20 +186,10 @@ static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr, int *_o | ||
245 | /* | ||
246 | * do the futex operations | ||
247 | */ | ||
248 | -int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
249 | +int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) | ||
250 | { | ||
251 | - int op = (encoded_op >> 28) & 7; | ||
252 | - int cmp = (encoded_op >> 24) & 15; | ||
253 | - int oparg = (encoded_op << 8) >> 20; | ||
254 | - int cmparg = (encoded_op << 20) >> 20; | ||
255 | int oldval = 0, ret; | ||
256 | |||
257 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
258 | - oparg = 1 << oparg; | ||
259 | - | ||
260 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | ||
261 | - return -EFAULT; | ||
262 | - | ||
263 | pagefault_disable(); | ||
264 | |||
265 | switch (op) { | ||
266 | @@ -225,18 +215,9 @@ int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
267 | |||
268 | pagefault_enable(); | ||
269 | |||
270 | - if (!ret) { | ||
271 | - switch (cmp) { | ||
272 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
273 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
274 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
275 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
276 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
277 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
278 | - default: ret = -ENOSYS; break; | ||
279 | - } | ||
280 | - } | ||
281 | + if (!ret) | ||
282 | + *oval = oldval; | ||
283 | |||
284 | return ret; | ||
285 | |||
286 | -} /* end futex_atomic_op_inuser() */ | ||
287 | +} /* end arch_futex_atomic_op_inuser() */ | ||
288 | diff --git a/arch/hexagon/include/asm/futex.h b/arch/hexagon/include/asm/futex.h | ||
289 | index 7e597f8434da..c607b77c8215 100644 | ||
290 | --- a/arch/hexagon/include/asm/futex.h | ||
291 | +++ b/arch/hexagon/include/asm/futex.h | ||
292 | @@ -31,18 +31,9 @@ | ||
293 | |||
294 | |||
295 | static inline int | ||
296 | -futex_atomic_op_inuser(int encoded_op, int __user *uaddr) | ||
297 | +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) | ||
298 | { | ||
299 | - int op = (encoded_op >> 28) & 7; | ||
300 | - int cmp = (encoded_op >> 24) & 15; | ||
301 | - int oparg = (encoded_op << 8) >> 20; | ||
302 | - int cmparg = (encoded_op << 20) >> 20; | ||
303 | int oldval = 0, ret; | ||
304 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
305 | - oparg = 1 << oparg; | ||
306 | - | ||
307 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) | ||
308 | - return -EFAULT; | ||
309 | |||
310 | pagefault_disable(); | ||
311 | |||
312 | @@ -72,30 +63,9 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) | ||
313 | |||
314 | pagefault_enable(); | ||
315 | |||
316 | - if (!ret) { | ||
317 | - switch (cmp) { | ||
318 | - case FUTEX_OP_CMP_EQ: | ||
319 | - ret = (oldval == cmparg); | ||
320 | - break; | ||
321 | - case FUTEX_OP_CMP_NE: | ||
322 | - ret = (oldval != cmparg); | ||
323 | - break; | ||
324 | - case FUTEX_OP_CMP_LT: | ||
325 | - ret = (oldval < cmparg); | ||
326 | - break; | ||
327 | - case FUTEX_OP_CMP_GE: | ||
328 | - ret = (oldval >= cmparg); | ||
329 | - break; | ||
330 | - case FUTEX_OP_CMP_LE: | ||
331 | - ret = (oldval <= cmparg); | ||
332 | - break; | ||
333 | - case FUTEX_OP_CMP_GT: | ||
334 | - ret = (oldval > cmparg); | ||
335 | - break; | ||
336 | - default: | ||
337 | - ret = -ENOSYS; | ||
338 | - } | ||
339 | - } | ||
340 | + if (!ret) | ||
341 | + *oval = oldval; | ||
342 | + | ||
343 | return ret; | ||
344 | } | ||
345 | |||
346 | diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h | ||
347 | index 76acbcd5c060..6d67dc1eaf2b 100644 | ||
348 | --- a/arch/ia64/include/asm/futex.h | ||
349 | +++ b/arch/ia64/include/asm/futex.h | ||
350 | @@ -45,18 +45,9 @@ do { \ | ||
351 | } while (0) | ||
352 | |||
353 | static inline int | ||
354 | -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
355 | +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) | ||
356 | { | ||
357 | - int op = (encoded_op >> 28) & 7; | ||
358 | - int cmp = (encoded_op >> 24) & 15; | ||
359 | - int oparg = (encoded_op << 8) >> 20; | ||
360 | - int cmparg = (encoded_op << 20) >> 20; | ||
361 | int oldval = 0, ret; | ||
362 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
363 | - oparg = 1 << oparg; | ||
364 | - | ||
365 | - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) | ||
366 | - return -EFAULT; | ||
367 | |||
368 | pagefault_disable(); | ||
369 | |||
370 | @@ -84,17 +75,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
371 | |||
372 | pagefault_enable(); | ||
373 | |||
374 | - if (!ret) { | ||
375 | - switch (cmp) { | ||
376 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
377 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
378 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
379 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
380 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
381 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
382 | - default: ret = -ENOSYS; | ||
383 | - } | ||
384 | - } | ||
385 | + if (!ret) | ||
386 | + *oval = oldval; | ||
387 | + | ||
388 | return ret; | ||
389 | } | ||
390 | |||
391 | diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h | ||
392 | index 01848f056f43..a9dad9e5e132 100644 | ||
393 | --- a/arch/microblaze/include/asm/futex.h | ||
394 | +++ b/arch/microblaze/include/asm/futex.h | ||
395 | @@ -29,18 +29,9 @@ | ||
396 | }) | ||
397 | |||
398 | static inline int | ||
399 | -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
400 | +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) | ||
401 | { | ||
402 | - int op = (encoded_op >> 28) & 7; | ||
403 | - int cmp = (encoded_op >> 24) & 15; | ||
404 | - int oparg = (encoded_op << 8) >> 20; | ||
405 | - int cmparg = (encoded_op << 20) >> 20; | ||
406 | int oldval = 0, ret; | ||
407 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
408 | - oparg = 1 << oparg; | ||
409 | - | ||
410 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | ||
411 | - return -EFAULT; | ||
412 | |||
413 | pagefault_disable(); | ||
414 | |||
415 | @@ -66,30 +57,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
416 | |||
417 | pagefault_enable(); | ||
418 | |||
419 | - if (!ret) { | ||
420 | - switch (cmp) { | ||
421 | - case FUTEX_OP_CMP_EQ: | ||
422 | - ret = (oldval == cmparg); | ||
423 | - break; | ||
424 | - case FUTEX_OP_CMP_NE: | ||
425 | - ret = (oldval != cmparg); | ||
426 | - break; | ||
427 | - case FUTEX_OP_CMP_LT: | ||
428 | - ret = (oldval < cmparg); | ||
429 | - break; | ||
430 | - case FUTEX_OP_CMP_GE: | ||
431 | - ret = (oldval >= cmparg); | ||
432 | - break; | ||
433 | - case FUTEX_OP_CMP_LE: | ||
434 | - ret = (oldval <= cmparg); | ||
435 | - break; | ||
436 | - case FUTEX_OP_CMP_GT: | ||
437 | - ret = (oldval > cmparg); | ||
438 | - break; | ||
439 | - default: | ||
440 | - ret = -ENOSYS; | ||
441 | - } | ||
442 | - } | ||
443 | + if (!ret) | ||
444 | + *oval = oldval; | ||
445 | + | ||
446 | return ret; | ||
447 | } | ||
448 | |||
449 | diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h | ||
450 | index 1de190bdfb9c..a9e61ea54ca9 100644 | ||
451 | --- a/arch/mips/include/asm/futex.h | ||
452 | +++ b/arch/mips/include/asm/futex.h | ||
453 | @@ -83,18 +83,9 @@ | ||
454 | } | ||
455 | |||
456 | static inline int | ||
457 | -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
458 | +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) | ||
459 | { | ||
460 | - int op = (encoded_op >> 28) & 7; | ||
461 | - int cmp = (encoded_op >> 24) & 15; | ||
462 | - int oparg = (encoded_op << 8) >> 20; | ||
463 | - int cmparg = (encoded_op << 20) >> 20; | ||
464 | int oldval = 0, ret; | ||
465 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
466 | - oparg = 1 << oparg; | ||
467 | - | ||
468 | - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) | ||
469 | - return -EFAULT; | ||
470 | |||
471 | pagefault_disable(); | ||
472 | |||
473 | @@ -125,17 +116,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
474 | |||
475 | pagefault_enable(); | ||
476 | |||
477 | - if (!ret) { | ||
478 | - switch (cmp) { | ||
479 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
480 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
481 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
482 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
483 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
484 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
485 | - default: ret = -ENOSYS; | ||
486 | - } | ||
487 | - } | ||
488 | + if (!ret) | ||
489 | + *oval = oldval; | ||
490 | + | ||
491 | return ret; | ||
492 | } | ||
493 | |||
494 | diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h | ||
495 | index ac8bd586ace8..06a1a883c72f 100644 | ||
496 | --- a/arch/parisc/include/asm/futex.h | ||
497 | +++ b/arch/parisc/include/asm/futex.h | ||
498 | @@ -32,22 +32,12 @@ _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) | ||
499 | } | ||
500 | |||
501 | static inline int | ||
502 | -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
503 | +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) | ||
504 | { | ||
505 | unsigned long int flags; | ||
506 | - int op = (encoded_op >> 28) & 7; | ||
507 | - int cmp = (encoded_op >> 24) & 15; | ||
508 | - int oparg = (encoded_op << 8) >> 20; | ||
509 | - int cmparg = (encoded_op << 20) >> 20; | ||
510 | int oldval, ret; | ||
511 | u32 tmp; | ||
512 | |||
513 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
514 | - oparg = 1 << oparg; | ||
515 | - | ||
516 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) | ||
517 | - return -EFAULT; | ||
518 | - | ||
519 | _futex_spin_lock_irqsave(uaddr, &flags); | ||
520 | pagefault_disable(); | ||
521 | |||
522 | @@ -85,17 +75,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
523 | pagefault_enable(); | ||
524 | _futex_spin_unlock_irqrestore(uaddr, &flags); | ||
525 | |||
526 | - if (ret == 0) { | ||
527 | - switch (cmp) { | ||
528 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
529 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
530 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
531 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
532 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
533 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
534 | - default: ret = -ENOSYS; | ||
535 | - } | ||
536 | - } | ||
537 | + if (!ret) | ||
538 | + *oval = oldval; | ||
539 | + | ||
540 | return ret; | ||
541 | } | ||
542 | |||
543 | diff --git a/arch/powerpc/include/asm/futex.h b/arch/powerpc/include/asm/futex.h | ||
544 | index 2a9cf845473b..f4c7467f7465 100644 | ||
545 | --- a/arch/powerpc/include/asm/futex.h | ||
546 | +++ b/arch/powerpc/include/asm/futex.h | ||
547 | @@ -31,18 +31,10 @@ | ||
548 | : "b" (uaddr), "i" (-EFAULT), "r" (oparg) \ | ||
549 | : "cr0", "memory") | ||
550 | |||
551 | -static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
552 | +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, | ||
553 | + u32 __user *uaddr) | ||
554 | { | ||
555 | - int op = (encoded_op >> 28) & 7; | ||
556 | - int cmp = (encoded_op >> 24) & 15; | ||
557 | - int oparg = (encoded_op << 8) >> 20; | ||
558 | - int cmparg = (encoded_op << 20) >> 20; | ||
559 | int oldval = 0, ret; | ||
560 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
561 | - oparg = 1 << oparg; | ||
562 | - | ||
563 | - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) | ||
564 | - return -EFAULT; | ||
565 | |||
566 | pagefault_disable(); | ||
567 | |||
568 | @@ -68,17 +60,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
569 | |||
570 | pagefault_enable(); | ||
571 | |||
572 | - if (!ret) { | ||
573 | - switch (cmp) { | ||
574 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
575 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
576 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
577 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
578 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
579 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
580 | - default: ret = -ENOSYS; | ||
581 | - } | ||
582 | - } | ||
583 | + if (!ret) | ||
584 | + *oval = oldval; | ||
585 | + | ||
586 | return ret; | ||
587 | } | ||
588 | |||
589 | diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h | ||
590 | index a4811aa0304d..8f8eec9e1198 100644 | ||
591 | --- a/arch/s390/include/asm/futex.h | ||
592 | +++ b/arch/s390/include/asm/futex.h | ||
593 | @@ -21,17 +21,12 @@ | ||
594 | : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \ | ||
595 | "m" (*uaddr) : "cc"); | ||
596 | |||
597 | -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
598 | +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, | ||
599 | + u32 __user *uaddr) | ||
600 | { | ||
601 | - int op = (encoded_op >> 28) & 7; | ||
602 | - int cmp = (encoded_op >> 24) & 15; | ||
603 | - int oparg = (encoded_op << 8) >> 20; | ||
604 | - int cmparg = (encoded_op << 20) >> 20; | ||
605 | int oldval = 0, newval, ret; | ||
606 | |||
607 | load_kernel_asce(); | ||
608 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
609 | - oparg = 1 << oparg; | ||
610 | |||
611 | pagefault_disable(); | ||
612 | switch (op) { | ||
613 | @@ -60,17 +55,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
614 | } | ||
615 | pagefault_enable(); | ||
616 | |||
617 | - if (!ret) { | ||
618 | - switch (cmp) { | ||
619 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
620 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
621 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
622 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
623 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
624 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
625 | - default: ret = -ENOSYS; | ||
626 | - } | ||
627 | - } | ||
628 | + if (!ret) | ||
629 | + *oval = oldval; | ||
630 | + | ||
631 | return ret; | ||
632 | } | ||
633 | |||
634 | diff --git a/arch/sh/include/asm/futex.h b/arch/sh/include/asm/futex.h | ||
635 | index d0078747d308..8f8cf941a8cd 100644 | ||
636 | --- a/arch/sh/include/asm/futex.h | ||
637 | +++ b/arch/sh/include/asm/futex.h | ||
638 | @@ -27,21 +27,12 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | ||
639 | return atomic_futex_op_cmpxchg_inatomic(uval, uaddr, oldval, newval); | ||
640 | } | ||
641 | |||
642 | -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
643 | +static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, | ||
644 | + u32 __user *uaddr) | ||
645 | { | ||
646 | - int op = (encoded_op >> 28) & 7; | ||
647 | - int cmp = (encoded_op >> 24) & 15; | ||
648 | - u32 oparg = (encoded_op << 8) >> 20; | ||
649 | - u32 cmparg = (encoded_op << 20) >> 20; | ||
650 | u32 oldval, newval, prev; | ||
651 | int ret; | ||
652 | |||
653 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
654 | - oparg = 1 << oparg; | ||
655 | - | ||
656 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | ||
657 | - return -EFAULT; | ||
658 | - | ||
659 | pagefault_disable(); | ||
660 | |||
661 | do { | ||
662 | @@ -80,17 +71,8 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
663 | |||
664 | pagefault_enable(); | ||
665 | |||
666 | - if (!ret) { | ||
667 | - switch (cmp) { | ||
668 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
669 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
670 | - case FUTEX_OP_CMP_LT: ret = ((int)oldval < (int)cmparg); break; | ||
671 | - case FUTEX_OP_CMP_GE: ret = ((int)oldval >= (int)cmparg); break; | ||
672 | - case FUTEX_OP_CMP_LE: ret = ((int)oldval <= (int)cmparg); break; | ||
673 | - case FUTEX_OP_CMP_GT: ret = ((int)oldval > (int)cmparg); break; | ||
674 | - default: ret = -ENOSYS; | ||
675 | - } | ||
676 | - } | ||
677 | + if (!ret) | ||
678 | + *oval = oldval; | ||
679 | |||
680 | return ret; | ||
681 | } | ||
682 | diff --git a/arch/sparc/include/asm/futex_64.h b/arch/sparc/include/asm/futex_64.h | ||
683 | index 4e899b0dabf7..1cfd89d92208 100644 | ||
684 | --- a/arch/sparc/include/asm/futex_64.h | ||
685 | +++ b/arch/sparc/include/asm/futex_64.h | ||
686 | @@ -29,22 +29,14 @@ | ||
687 | : "r" (uaddr), "r" (oparg), "i" (-EFAULT) \ | ||
688 | : "memory") | ||
689 | |||
690 | -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
691 | +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, | ||
692 | + u32 __user *uaddr) | ||
693 | { | ||
694 | - int op = (encoded_op >> 28) & 7; | ||
695 | - int cmp = (encoded_op >> 24) & 15; | ||
696 | - int oparg = (encoded_op << 8) >> 20; | ||
697 | - int cmparg = (encoded_op << 20) >> 20; | ||
698 | int oldval = 0, ret, tem; | ||
699 | |||
700 | - if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))) | ||
701 | - return -EFAULT; | ||
702 | if (unlikely((((unsigned long) uaddr) & 0x3UL))) | ||
703 | return -EINVAL; | ||
704 | |||
705 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
706 | - oparg = 1 << oparg; | ||
707 | - | ||
708 | pagefault_disable(); | ||
709 | |||
710 | switch (op) { | ||
711 | @@ -69,17 +61,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
712 | |||
713 | pagefault_enable(); | ||
714 | |||
715 | - if (!ret) { | ||
716 | - switch (cmp) { | ||
717 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
718 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
719 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
720 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
721 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
722 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
723 | - default: ret = -ENOSYS; | ||
724 | - } | ||
725 | - } | ||
726 | + if (!ret) | ||
727 | + *oval = oldval; | ||
728 | + | ||
729 | return ret; | ||
730 | } | ||
731 | |||
732 | diff --git a/arch/tile/include/asm/futex.h b/arch/tile/include/asm/futex.h | ||
733 | index e64a1b75fc38..83c1e639b411 100644 | ||
734 | --- a/arch/tile/include/asm/futex.h | ||
735 | +++ b/arch/tile/include/asm/futex.h | ||
736 | @@ -106,12 +106,9 @@ | ||
737 | lock = __atomic_hashed_lock((int __force *)uaddr) | ||
738 | #endif | ||
739 | |||
740 | -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
741 | +static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, | ||
742 | + u32 __user *uaddr) | ||
743 | { | ||
744 | - int op = (encoded_op >> 28) & 7; | ||
745 | - int cmp = (encoded_op >> 24) & 15; | ||
746 | - int oparg = (encoded_op << 8) >> 20; | ||
747 | - int cmparg = (encoded_op << 20) >> 20; | ||
748 | int uninitialized_var(val), ret; | ||
749 | |||
750 | __futex_prolog(); | ||
751 | @@ -119,12 +116,6 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
752 | /* The 32-bit futex code makes this assumption, so validate it here. */ | ||
753 | BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int)); | ||
754 | |||
755 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
756 | - oparg = 1 << oparg; | ||
757 | - | ||
758 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | ||
759 | - return -EFAULT; | ||
760 | - | ||
761 | pagefault_disable(); | ||
762 | switch (op) { | ||
763 | case FUTEX_OP_SET: | ||
764 | @@ -148,30 +139,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
765 | } | ||
766 | pagefault_enable(); | ||
767 | |||
768 | - if (!ret) { | ||
769 | - switch (cmp) { | ||
770 | - case FUTEX_OP_CMP_EQ: | ||
771 | - ret = (val == cmparg); | ||
772 | - break; | ||
773 | - case FUTEX_OP_CMP_NE: | ||
774 | - ret = (val != cmparg); | ||
775 | - break; | ||
776 | - case FUTEX_OP_CMP_LT: | ||
777 | - ret = (val < cmparg); | ||
778 | - break; | ||
779 | - case FUTEX_OP_CMP_GE: | ||
780 | - ret = (val >= cmparg); | ||
781 | - break; | ||
782 | - case FUTEX_OP_CMP_LE: | ||
783 | - ret = (val <= cmparg); | ||
784 | - break; | ||
785 | - case FUTEX_OP_CMP_GT: | ||
786 | - ret = (val > cmparg); | ||
787 | - break; | ||
788 | - default: | ||
789 | - ret = -ENOSYS; | ||
790 | - } | ||
791 | - } | ||
792 | + if (!ret) | ||
793 | + *oval = val; | ||
794 | + | ||
795 | return ret; | ||
796 | } | ||
797 | |||
798 | diff --git a/arch/x86/include/asm/futex.h b/arch/x86/include/asm/futex.h | ||
799 | index b4c1f5453436..f4dc9b63bdda 100644 | ||
800 | --- a/arch/x86/include/asm/futex.h | ||
801 | +++ b/arch/x86/include/asm/futex.h | ||
802 | @@ -41,20 +41,11 @@ | ||
803 | "+m" (*uaddr), "=&r" (tem) \ | ||
804 | : "r" (oparg), "i" (-EFAULT), "1" (0)) | ||
805 | |||
806 | -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
807 | +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, | ||
808 | + u32 __user *uaddr) | ||
809 | { | ||
810 | - int op = (encoded_op >> 28) & 7; | ||
811 | - int cmp = (encoded_op >> 24) & 15; | ||
812 | - int oparg = (encoded_op << 8) >> 20; | ||
813 | - int cmparg = (encoded_op << 20) >> 20; | ||
814 | int oldval = 0, ret, tem; | ||
815 | |||
816 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
817 | - oparg = 1 << oparg; | ||
818 | - | ||
819 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | ||
820 | - return -EFAULT; | ||
821 | - | ||
822 | pagefault_disable(); | ||
823 | |||
824 | switch (op) { | ||
825 | @@ -80,30 +71,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
826 | |||
827 | pagefault_enable(); | ||
828 | |||
829 | - if (!ret) { | ||
830 | - switch (cmp) { | ||
831 | - case FUTEX_OP_CMP_EQ: | ||
832 | - ret = (oldval == cmparg); | ||
833 | - break; | ||
834 | - case FUTEX_OP_CMP_NE: | ||
835 | - ret = (oldval != cmparg); | ||
836 | - break; | ||
837 | - case FUTEX_OP_CMP_LT: | ||
838 | - ret = (oldval < cmparg); | ||
839 | - break; | ||
840 | - case FUTEX_OP_CMP_GE: | ||
841 | - ret = (oldval >= cmparg); | ||
842 | - break; | ||
843 | - case FUTEX_OP_CMP_LE: | ||
844 | - ret = (oldval <= cmparg); | ||
845 | - break; | ||
846 | - case FUTEX_OP_CMP_GT: | ||
847 | - ret = (oldval > cmparg); | ||
848 | - break; | ||
849 | - default: | ||
850 | - ret = -ENOSYS; | ||
851 | - } | ||
852 | - } | ||
853 | + if (!ret) | ||
854 | + *oval = oldval; | ||
855 | + | ||
856 | return ret; | ||
857 | } | ||
858 | |||
859 | diff --git a/arch/xtensa/include/asm/futex.h b/arch/xtensa/include/asm/futex.h | ||
860 | index 72bfc1cbc2b5..5bfbc1c401d4 100644 | ||
861 | --- a/arch/xtensa/include/asm/futex.h | ||
862 | +++ b/arch/xtensa/include/asm/futex.h | ||
863 | @@ -44,18 +44,10 @@ | ||
864 | : "r" (uaddr), "I" (-EFAULT), "r" (oparg) \ | ||
865 | : "memory") | ||
866 | |||
867 | -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
868 | +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, | ||
869 | + u32 __user *uaddr) | ||
870 | { | ||
871 | - int op = (encoded_op >> 28) & 7; | ||
872 | - int cmp = (encoded_op >> 24) & 15; | ||
873 | - int oparg = (encoded_op << 8) >> 20; | ||
874 | - int cmparg = (encoded_op << 20) >> 20; | ||
875 | int oldval = 0, ret; | ||
876 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
877 | - oparg = 1 << oparg; | ||
878 | - | ||
879 | - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | ||
880 | - return -EFAULT; | ||
881 | |||
882 | #if !XCHAL_HAVE_S32C1I | ||
883 | return -ENOSYS; | ||
884 | @@ -89,19 +81,10 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
885 | |||
886 | pagefault_enable(); | ||
887 | |||
888 | - if (ret) | ||
889 | - return ret; | ||
890 | + if (!ret) | ||
891 | + *oval = oldval; | ||
892 | |||
893 | - switch (cmp) { | ||
894 | - case FUTEX_OP_CMP_EQ: return (oldval == cmparg); | ||
895 | - case FUTEX_OP_CMP_NE: return (oldval != cmparg); | ||
896 | - case FUTEX_OP_CMP_LT: return (oldval < cmparg); | ||
897 | - case FUTEX_OP_CMP_GE: return (oldval >= cmparg); | ||
898 | - case FUTEX_OP_CMP_LE: return (oldval <= cmparg); | ||
899 | - case FUTEX_OP_CMP_GT: return (oldval > cmparg); | ||
900 | - } | ||
901 | - | ||
902 | - return -ENOSYS; | ||
903 | + return ret; | ||
904 | } | ||
905 | |||
906 | static inline int | ||
907 | diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c | ||
908 | index 551f0f8dead3..91d8a48e53c3 100644 | ||
909 | --- a/drivers/net/bonding/bond_alb.c | ||
910 | +++ b/drivers/net/bonding/bond_alb.c | ||
911 | @@ -450,7 +450,7 @@ static void rlb_update_client(struct rlb_client_info *client_info) | ||
912 | { | ||
913 | int i; | ||
914 | |||
915 | - if (!client_info->slave) | ||
916 | + if (!client_info->slave || !is_valid_ether_addr(client_info->mac_dst)) | ||
917 | return; | ||
918 | |||
919 | for (i = 0; i < RLB_ARP_BURST_SIZE; i++) { | ||
920 | @@ -944,6 +944,10 @@ static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[], | ||
921 | skb->priority = TC_PRIO_CONTROL; | ||
922 | skb->dev = slave->dev; | ||
923 | |||
924 | + netdev_dbg(slave->bond->dev, | ||
925 | + "Send learning packet: dev %s mac %pM vlan %d\n", | ||
926 | + slave->dev->name, mac_addr, vid); | ||
927 | + | ||
928 | if (vid) | ||
929 | __vlan_hwaccel_put_tag(skb, vlan_proto, vid); | ||
930 | |||
931 | @@ -966,14 +970,13 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], | ||
932 | */ | ||
933 | rcu_read_lock(); | ||
934 | netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { | ||
935 | - if (is_vlan_dev(upper) && vlan_get_encap_level(upper) == 0) { | ||
936 | - if (strict_match && | ||
937 | - ether_addr_equal_64bits(mac_addr, | ||
938 | - upper->dev_addr)) { | ||
939 | + if (is_vlan_dev(upper) && | ||
940 | + bond->nest_level == vlan_get_encap_level(upper) - 1) { | ||
941 | + if (upper->addr_assign_type == NET_ADDR_STOLEN) { | ||
942 | alb_send_lp_vid(slave, mac_addr, | ||
943 | vlan_dev_vlan_proto(upper), | ||
944 | vlan_dev_vlan_id(upper)); | ||
945 | - } else if (!strict_match) { | ||
946 | + } else { | ||
947 | alb_send_lp_vid(slave, upper->dev_addr, | ||
948 | vlan_dev_vlan_proto(upper), | ||
949 | vlan_dev_vlan_id(upper)); | ||
950 | diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c | ||
951 | index 13a015b8052b..1a139d0f2232 100644 | ||
952 | --- a/drivers/net/bonding/bond_main.c | ||
953 | +++ b/drivers/net/bonding/bond_main.c | ||
954 | @@ -1732,6 +1732,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | ||
955 | if (bond_mode_uses_xmit_hash(bond)) | ||
956 | bond_update_slave_arr(bond, NULL); | ||
957 | |||
958 | + bond->nest_level = dev_get_nest_level(bond_dev); | ||
959 | + | ||
960 | netdev_info(bond_dev, "Enslaving %s as %s interface with %s link\n", | ||
961 | slave_dev->name, | ||
962 | bond_is_active_slave(new_slave) ? "an active" : "a backup", | ||
963 | diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c | ||
964 | index 795a133fb074..4ffbe850d746 100644 | ||
965 | --- a/drivers/net/ethernet/broadcom/tg3.c | ||
966 | +++ b/drivers/net/ethernet/broadcom/tg3.c | ||
967 | @@ -8720,14 +8720,15 @@ static void tg3_free_consistent(struct tg3 *tp) | ||
968 | tg3_mem_rx_release(tp); | ||
969 | tg3_mem_tx_release(tp); | ||
970 | |||
971 | - /* Protect tg3_get_stats64() from reading freed tp->hw_stats. */ | ||
972 | - tg3_full_lock(tp, 0); | ||
973 | + /* tp->hw_stats can be referenced safely: | ||
974 | + * 1. under rtnl_lock | ||
975 | + * 2. or under tp->lock if TG3_FLAG_INIT_COMPLETE is set. | ||
976 | + */ | ||
977 | if (tp->hw_stats) { | ||
978 | dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), | ||
979 | tp->hw_stats, tp->stats_mapping); | ||
980 | tp->hw_stats = NULL; | ||
981 | } | ||
982 | - tg3_full_unlock(tp); | ||
983 | } | ||
984 | |||
985 | /* | ||
986 | @@ -14161,7 +14162,7 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, | ||
987 | struct tg3 *tp = netdev_priv(dev); | ||
988 | |||
989 | spin_lock_bh(&tp->lock); | ||
990 | - if (!tp->hw_stats) { | ||
991 | + if (!tp->hw_stats || !tg3_flag(tp, INIT_COMPLETE)) { | ||
992 | *stats = tp->net_stats_prev; | ||
993 | spin_unlock_bh(&tp->lock); | ||
994 | return stats; | ||
995 | diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | ||
996 | index 24977cc881d2..9a4c4f8281bd 100644 | ||
997 | --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | ||
998 | +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | ||
999 | @@ -970,6 +970,22 @@ static int mlx4_en_set_coalesce(struct net_device *dev, | ||
1000 | if (!coal->tx_max_coalesced_frames_irq) | ||
1001 | return -EINVAL; | ||
1002 | |||
1003 | + if (coal->tx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME || | ||
1004 | + coal->rx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME || | ||
1005 | + coal->rx_coalesce_usecs_low > MLX4_EN_MAX_COAL_TIME || | ||
1006 | + coal->rx_coalesce_usecs_high > MLX4_EN_MAX_COAL_TIME) { | ||
1007 | + netdev_info(dev, "%s: maximum coalesce time supported is %d usecs\n", | ||
1008 | + __func__, MLX4_EN_MAX_COAL_TIME); | ||
1009 | + return -ERANGE; | ||
1010 | + } | ||
1011 | + | ||
1012 | + if (coal->tx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS || | ||
1013 | + coal->rx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS) { | ||
1014 | + netdev_info(dev, "%s: maximum coalesced frames supported is %d\n", | ||
1015 | + __func__, MLX4_EN_MAX_COAL_PKTS); | ||
1016 | + return -ERANGE; | ||
1017 | + } | ||
1018 | + | ||
1019 | priv->rx_frames = (coal->rx_max_coalesced_frames == | ||
1020 | MLX4_EN_AUTO_CONF) ? | ||
1021 | MLX4_EN_RX_COAL_TARGET : | ||
1022 | diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | ||
1023 | index 18f221d8a04d..247d340be743 100644 | ||
1024 | --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | ||
1025 | +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | ||
1026 | @@ -141,6 +141,9 @@ enum { | ||
1027 | #define MLX4_EN_TX_COAL_PKTS 16 | ||
1028 | #define MLX4_EN_TX_COAL_TIME 0x10 | ||
1029 | |||
1030 | +#define MLX4_EN_MAX_COAL_PKTS U16_MAX | ||
1031 | +#define MLX4_EN_MAX_COAL_TIME U16_MAX | ||
1032 | + | ||
1033 | #define MLX4_EN_RX_RATE_LOW 400000 | ||
1034 | #define MLX4_EN_RX_COAL_TIME_LOW 0 | ||
1035 | #define MLX4_EN_RX_RATE_HIGH 450000 | ||
1036 | @@ -543,8 +546,8 @@ struct mlx4_en_priv { | ||
1037 | u16 rx_usecs_low; | ||
1038 | u32 pkt_rate_high; | ||
1039 | u16 rx_usecs_high; | ||
1040 | - u16 sample_interval; | ||
1041 | - u16 adaptive_rx_coal; | ||
1042 | + u32 sample_interval; | ||
1043 | + u32 adaptive_rx_coal; | ||
1044 | u32 msg_enable; | ||
1045 | u32 loopback_ok; | ||
1046 | u32 validate_loopback; | ||
1047 | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | ||
1048 | index a8966e6dbe1b..5d6eab19a9d8 100644 | ||
1049 | --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | ||
1050 | +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | ||
1051 | @@ -1924,26 +1924,35 @@ int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, | ||
1052 | memset(vf_stats, 0, sizeof(*vf_stats)); | ||
1053 | vf_stats->rx_packets = | ||
1054 | MLX5_GET_CTR(out, received_eth_unicast.packets) + | ||
1055 | + MLX5_GET_CTR(out, received_ib_unicast.packets) + | ||
1056 | MLX5_GET_CTR(out, received_eth_multicast.packets) + | ||
1057 | + MLX5_GET_CTR(out, received_ib_multicast.packets) + | ||
1058 | MLX5_GET_CTR(out, received_eth_broadcast.packets); | ||
1059 | |||
1060 | vf_stats->rx_bytes = | ||
1061 | MLX5_GET_CTR(out, received_eth_unicast.octets) + | ||
1062 | + MLX5_GET_CTR(out, received_ib_unicast.octets) + | ||
1063 | MLX5_GET_CTR(out, received_eth_multicast.octets) + | ||
1064 | + MLX5_GET_CTR(out, received_ib_multicast.octets) + | ||
1065 | MLX5_GET_CTR(out, received_eth_broadcast.octets); | ||
1066 | |||
1067 | vf_stats->tx_packets = | ||
1068 | MLX5_GET_CTR(out, transmitted_eth_unicast.packets) + | ||
1069 | + MLX5_GET_CTR(out, transmitted_ib_unicast.packets) + | ||
1070 | MLX5_GET_CTR(out, transmitted_eth_multicast.packets) + | ||
1071 | + MLX5_GET_CTR(out, transmitted_ib_multicast.packets) + | ||
1072 | MLX5_GET_CTR(out, transmitted_eth_broadcast.packets); | ||
1073 | |||
1074 | vf_stats->tx_bytes = | ||
1075 | MLX5_GET_CTR(out, transmitted_eth_unicast.octets) + | ||
1076 | + MLX5_GET_CTR(out, transmitted_ib_unicast.octets) + | ||
1077 | MLX5_GET_CTR(out, transmitted_eth_multicast.octets) + | ||
1078 | + MLX5_GET_CTR(out, transmitted_ib_multicast.octets) + | ||
1079 | MLX5_GET_CTR(out, transmitted_eth_broadcast.octets); | ||
1080 | |||
1081 | vf_stats->multicast = | ||
1082 | - MLX5_GET_CTR(out, received_eth_multicast.packets); | ||
1083 | + MLX5_GET_CTR(out, received_eth_multicast.packets) + | ||
1084 | + MLX5_GET_CTR(out, received_ib_multicast.packets); | ||
1085 | |||
1086 | vf_stats->broadcast = | ||
1087 | MLX5_GET_CTR(out, received_eth_broadcast.packets); | ||
1088 | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | ||
1089 | index 331a6ca4856d..5f3402ba9916 100644 | ||
1090 | --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | ||
1091 | +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | ||
1092 | @@ -153,6 +153,7 @@ static void del_rule(struct fs_node *node); | ||
1093 | static void del_flow_table(struct fs_node *node); | ||
1094 | static void del_flow_group(struct fs_node *node); | ||
1095 | static void del_fte(struct fs_node *node); | ||
1096 | +static void cleanup_root_ns(struct mlx5_flow_root_namespace *root_ns); | ||
1097 | |||
1098 | static void tree_init_node(struct fs_node *node, | ||
1099 | unsigned int refcount, | ||
1100 | @@ -1690,24 +1691,28 @@ static int create_anchor_flow_table(struct mlx5_flow_steering *steering) | ||
1101 | |||
1102 | static int init_root_ns(struct mlx5_flow_steering *steering) | ||
1103 | { | ||
1104 | + int err; | ||
1105 | |||
1106 | steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX); | ||
1107 | if (!steering->root_ns) | ||
1108 | - goto cleanup; | ||
1109 | + return -ENOMEM; | ||
1110 | |||
1111 | - if (init_root_tree(steering, &root_fs, &steering->root_ns->ns.node)) | ||
1112 | - goto cleanup; | ||
1113 | + err = init_root_tree(steering, &root_fs, &steering->root_ns->ns.node); | ||
1114 | + if (err) | ||
1115 | + goto out_err; | ||
1116 | |||
1117 | set_prio_attrs(steering->root_ns); | ||
1118 | |||
1119 | - if (create_anchor_flow_table(steering)) | ||
1120 | - goto cleanup; | ||
1121 | + err = create_anchor_flow_table(steering); | ||
1122 | + if (err) | ||
1123 | + goto out_err; | ||
1124 | |||
1125 | return 0; | ||
1126 | |||
1127 | -cleanup: | ||
1128 | - mlx5_cleanup_fs(steering->dev); | ||
1129 | - return -ENOMEM; | ||
1130 | +out_err: | ||
1131 | + cleanup_root_ns(steering->root_ns); | ||
1132 | + steering->root_ns = NULL; | ||
1133 | + return err; | ||
1134 | } | ||
1135 | |||
1136 | static void clean_tree(struct fs_node *node) | ||
1137 | diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c | ||
1138 | index 4ca82bd8c4f0..eee6e59e6cf3 100644 | ||
1139 | --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c | ||
1140 | +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c | ||
1141 | @@ -854,6 +854,8 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev) | ||
1142 | |||
1143 | netdev_tx_sent_queue(nd_q, txbuf->real_len); | ||
1144 | |||
1145 | + skb_tx_timestamp(skb); | ||
1146 | + | ||
1147 | tx_ring->wr_p += nr_frags + 1; | ||
1148 | if (nfp_net_tx_ring_should_stop(tx_ring)) | ||
1149 | nfp_net_tx_ring_stop(nd_q, tx_ring); | ||
1150 | @@ -866,8 +868,6 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev) | ||
1151 | tx_ring->wr_ptr_add = 0; | ||
1152 | } | ||
1153 | |||
1154 | - skb_tx_timestamp(skb); | ||
1155 | - | ||
1156 | return NETDEV_TX_OK; | ||
1157 | |||
1158 | err_unmap: | ||
1159 | diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c | ||
1160 | index da4c2d8a4173..1420dfb56bac 100644 | ||
1161 | --- a/drivers/net/ethernet/realtek/8139too.c | ||
1162 | +++ b/drivers/net/ethernet/realtek/8139too.c | ||
1163 | @@ -2233,7 +2233,7 @@ static void rtl8139_poll_controller(struct net_device *dev) | ||
1164 | struct rtl8139_private *tp = netdev_priv(dev); | ||
1165 | const int irq = tp->pci_dev->irq; | ||
1166 | |||
1167 | - disable_irq(irq); | ||
1168 | + disable_irq_nosync(irq); | ||
1169 | rtl8139_interrupt(irq, dev); | ||
1170 | enable_irq(irq); | ||
1171 | } | ||
1172 | diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c | ||
1173 | index dbb63640bc6e..59b932db0d42 100644 | ||
1174 | --- a/drivers/net/ethernet/realtek/r8169.c | ||
1175 | +++ b/drivers/net/ethernet/realtek/r8169.c | ||
1176 | @@ -4861,6 +4861,9 @@ static void rtl_pll_power_down(struct rtl8169_private *tp) | ||
1177 | static void rtl_pll_power_up(struct rtl8169_private *tp) | ||
1178 | { | ||
1179 | rtl_generic_op(tp, tp->pll_power_ops.up); | ||
1180 | + | ||
1181 | + /* give MAC/PHY some time to resume */ | ||
1182 | + msleep(20); | ||
1183 | } | ||
1184 | |||
1185 | static void rtl_init_pll_power_ops(struct rtl8169_private *tp) | ||
1186 | diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c | ||
1187 | index a2371aa14a49..e45e2f14fb94 100644 | ||
1188 | --- a/drivers/net/ethernet/sun/niu.c | ||
1189 | +++ b/drivers/net/ethernet/sun/niu.c | ||
1190 | @@ -3442,7 +3442,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, | ||
1191 | |||
1192 | len = (val & RCR_ENTRY_L2_LEN) >> | ||
1193 | RCR_ENTRY_L2_LEN_SHIFT; | ||
1194 | - len -= ETH_FCS_LEN; | ||
1195 | + append_size = len + ETH_HLEN + ETH_FCS_LEN; | ||
1196 | |||
1197 | addr = (val & RCR_ENTRY_PKT_BUF_ADDR) << | ||
1198 | RCR_ENTRY_PKT_BUF_ADDR_SHIFT; | ||
1199 | @@ -3452,7 +3452,6 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, | ||
1200 | RCR_ENTRY_PKTBUFSZ_SHIFT]; | ||
1201 | |||
1202 | off = addr & ~PAGE_MASK; | ||
1203 | - append_size = rcr_size; | ||
1204 | if (num_rcr == 1) { | ||
1205 | int ptype; | ||
1206 | |||
1207 | @@ -3465,7 +3464,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, | ||
1208 | else | ||
1209 | skb_checksum_none_assert(skb); | ||
1210 | } else if (!(val & RCR_ENTRY_MULTI)) | ||
1211 | - append_size = len - skb->len; | ||
1212 | + append_size = append_size - skb->len; | ||
1213 | |||
1214 | niu_rx_skb_append(skb, page, off, append_size, rcr_size); | ||
1215 | if ((page->index + rp->rbr_block_size) - rcr_size == addr) { | ||
1216 | diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c | ||
1217 | index de336897a28a..d7cb205fe7e2 100644 | ||
1218 | --- a/drivers/net/ethernet/ti/cpsw.c | ||
1219 | +++ b/drivers/net/ethernet/ti/cpsw.c | ||
1220 | @@ -1141,6 +1141,8 @@ static inline void cpsw_add_dual_emac_def_ale_entries( | ||
1221 | cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, | ||
1222 | HOST_PORT_NUM, ALE_VLAN | | ||
1223 | ALE_SECURE, slave->port_vlan); | ||
1224 | + cpsw_ale_control_set(cpsw->ale, slave_port, | ||
1225 | + ALE_PORT_DROP_UNKNOWN_VLAN, 1); | ||
1226 | } | ||
1227 | |||
1228 | static void soft_reset_slave(struct cpsw_slave *slave) | ||
1229 | diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c | ||
1230 | index 1029bd234c22..3e893fe890a0 100644 | ||
1231 | --- a/drivers/net/usb/qmi_wwan.c | ||
1232 | +++ b/drivers/net/usb/qmi_wwan.c | ||
1233 | @@ -1039,6 +1039,18 @@ static int qmi_wwan_probe(struct usb_interface *intf, | ||
1234 | id->driver_info = (unsigned long)&qmi_wwan_info; | ||
1235 | } | ||
1236 | |||
1237 | + /* There are devices where the same interface number can be | ||
1238 | + * configured as different functions. We should only bind to | ||
1239 | + * vendor specific functions when matching on interface number | ||
1240 | + */ | ||
1241 | + if (id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER && | ||
1242 | + desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) { | ||
1243 | + dev_dbg(&intf->dev, | ||
1244 | + "Rejecting interface number match for class %02x\n", | ||
1245 | + desc->bInterfaceClass); | ||
1246 | + return -ENODEV; | ||
1247 | + } | ||
1248 | + | ||
1249 | /* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */ | ||
1250 | if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) { | ||
1251 | dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n"); | ||
1252 | diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c | ||
1253 | index cdd2f942317c..b9c7a904c1ea 100644 | ||
1254 | --- a/drivers/tty/serial/sccnxp.c | ||
1255 | +++ b/drivers/tty/serial/sccnxp.c | ||
1256 | @@ -889,7 +889,16 @@ static int sccnxp_probe(struct platform_device *pdev) | ||
1257 | goto err_out; | ||
1258 | uartclk = 0; | ||
1259 | } else { | ||
1260 | - clk_prepare_enable(clk); | ||
1261 | + ret = clk_prepare_enable(clk); | ||
1262 | + if (ret) | ||
1263 | + goto err_out; | ||
1264 | + | ||
1265 | + ret = devm_add_action_or_reset(&pdev->dev, | ||
1266 | + (void(*)(void *))clk_disable_unprepare, | ||
1267 | + clk); | ||
1268 | + if (ret) | ||
1269 | + goto err_out; | ||
1270 | + | ||
1271 | uartclk = clk_get_rate(clk); | ||
1272 | } | ||
1273 | |||
1274 | @@ -988,7 +997,7 @@ static int sccnxp_probe(struct platform_device *pdev) | ||
1275 | uart_unregister_driver(&s->uart); | ||
1276 | err_out: | ||
1277 | if (!IS_ERR(s->regulator)) | ||
1278 | - return regulator_disable(s->regulator); | ||
1279 | + regulator_disable(s->regulator); | ||
1280 | |||
1281 | return ret; | ||
1282 | } | ||
1283 | diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c | ||
1284 | index 85135df0eb34..c19123dcd1a4 100644 | ||
1285 | --- a/fs/lockd/svc.c | ||
1286 | +++ b/fs/lockd/svc.c | ||
1287 | @@ -274,6 +274,8 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net) | ||
1288 | if (ln->nlmsvc_users) { | ||
1289 | if (--ln->nlmsvc_users == 0) { | ||
1290 | nlm_shutdown_hosts_net(net); | ||
1291 | + cancel_delayed_work_sync(&ln->grace_period_end); | ||
1292 | + locks_end_grace(&ln->lockd_manager); | ||
1293 | svc_shutdown_net(serv, net); | ||
1294 | dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net); | ||
1295 | } | ||
1296 | diff --git a/fs/proc/base.c b/fs/proc/base.c | ||
1297 | index e67fec3c9856..3fec83ba75fa 100644 | ||
1298 | --- a/fs/proc/base.c | ||
1299 | +++ b/fs/proc/base.c | ||
1300 | @@ -252,7 +252,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, | ||
1301 | * Inherently racy -- command line shares address space | ||
1302 | * with code and data. | ||
1303 | */ | ||
1304 | - rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0); | ||
1305 | + rv = access_remote_vm(mm, arg_end - 1, &c, 1, FOLL_ANON); | ||
1306 | if (rv <= 0) | ||
1307 | goto out_free_page; | ||
1308 | |||
1309 | @@ -270,7 +270,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, | ||
1310 | int nr_read; | ||
1311 | |||
1312 | _count = min3(count, len, PAGE_SIZE); | ||
1313 | - nr_read = access_remote_vm(mm, p, page, _count, 0); | ||
1314 | + nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON); | ||
1315 | if (nr_read < 0) | ||
1316 | rv = nr_read; | ||
1317 | if (nr_read <= 0) | ||
1318 | @@ -305,7 +305,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, | ||
1319 | bool final; | ||
1320 | |||
1321 | _count = min3(count, len, PAGE_SIZE); | ||
1322 | - nr_read = access_remote_vm(mm, p, page, _count, 0); | ||
1323 | + nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON); | ||
1324 | if (nr_read < 0) | ||
1325 | rv = nr_read; | ||
1326 | if (nr_read <= 0) | ||
1327 | @@ -354,7 +354,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, | ||
1328 | bool final; | ||
1329 | |||
1330 | _count = min3(count, len, PAGE_SIZE); | ||
1331 | - nr_read = access_remote_vm(mm, p, page, _count, 0); | ||
1332 | + nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON); | ||
1333 | if (nr_read < 0) | ||
1334 | rv = nr_read; | ||
1335 | if (nr_read <= 0) | ||
1336 | @@ -970,7 +970,7 @@ static ssize_t environ_read(struct file *file, char __user *buf, | ||
1337 | max_len = min_t(size_t, PAGE_SIZE, count); | ||
1338 | this_len = min(max_len, this_len); | ||
1339 | |||
1340 | - retval = access_remote_vm(mm, (env_start + src), page, this_len, 0); | ||
1341 | + retval = access_remote_vm(mm, (env_start + src), page, this_len, FOLL_ANON); | ||
1342 | |||
1343 | if (retval <= 0) { | ||
1344 | ret = retval; | ||
1345 | diff --git a/include/asm-generic/futex.h b/include/asm-generic/futex.h | ||
1346 | index bf2d34c9d804..f0d8b1c51343 100644 | ||
1347 | --- a/include/asm-generic/futex.h | ||
1348 | +++ b/include/asm-generic/futex.h | ||
1349 | @@ -13,7 +13,7 @@ | ||
1350 | */ | ||
1351 | |||
1352 | /** | ||
1353 | - * futex_atomic_op_inuser() - Atomic arithmetic operation with constant | ||
1354 | + * arch_futex_atomic_op_inuser() - Atomic arithmetic operation with constant | ||
1355 | * argument and comparison of the previous | ||
1356 | * futex value with another constant. | ||
1357 | * | ||
1358 | @@ -25,18 +25,11 @@ | ||
1359 | * <0 - On error | ||
1360 | */ | ||
1361 | static inline int | ||
1362 | -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
1363 | +arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) | ||
1364 | { | ||
1365 | - int op = (encoded_op >> 28) & 7; | ||
1366 | - int cmp = (encoded_op >> 24) & 15; | ||
1367 | - int oparg = (encoded_op << 8) >> 20; | ||
1368 | - int cmparg = (encoded_op << 20) >> 20; | ||
1369 | int oldval, ret; | ||
1370 | u32 tmp; | ||
1371 | |||
1372 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
1373 | - oparg = 1 << oparg; | ||
1374 | - | ||
1375 | preempt_disable(); | ||
1376 | pagefault_disable(); | ||
1377 | |||
1378 | @@ -74,17 +67,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) | ||
1379 | pagefault_enable(); | ||
1380 | preempt_enable(); | ||
1381 | |||
1382 | - if (ret == 0) { | ||
1383 | - switch (cmp) { | ||
1384 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
1385 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
1386 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
1387 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
1388 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
1389 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
1390 | - default: ret = -ENOSYS; | ||
1391 | - } | ||
1392 | - } | ||
1393 | + if (ret == 0) | ||
1394 | + *oval = oldval; | ||
1395 | + | ||
1396 | return ret; | ||
1397 | } | ||
1398 | |||
1399 | @@ -126,18 +111,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | ||
1400 | |||
1401 | #else | ||
1402 | static inline int | ||
1403 | -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
1404 | +arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) | ||
1405 | { | ||
1406 | - int op = (encoded_op >> 28) & 7; | ||
1407 | - int cmp = (encoded_op >> 24) & 15; | ||
1408 | - int oparg = (encoded_op << 8) >> 20; | ||
1409 | - int cmparg = (encoded_op << 20) >> 20; | ||
1410 | int oldval = 0, ret; | ||
1411 | - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
1412 | - oparg = 1 << oparg; | ||
1413 | - | ||
1414 | - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) | ||
1415 | - return -EFAULT; | ||
1416 | |||
1417 | pagefault_disable(); | ||
1418 | |||
1419 | @@ -153,17 +129,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | ||
1420 | |||
1421 | pagefault_enable(); | ||
1422 | |||
1423 | - if (!ret) { | ||
1424 | - switch (cmp) { | ||
1425 | - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
1426 | - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
1427 | - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
1428 | - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
1429 | - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
1430 | - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
1431 | - default: ret = -ENOSYS; | ||
1432 | - } | ||
1433 | - } | ||
1434 | + if (!ret) | ||
1435 | + *oval = oldval; | ||
1436 | + | ||
1437 | return ret; | ||
1438 | } | ||
1439 | |||
1440 | diff --git a/include/linux/mm.h b/include/linux/mm.h | ||
1441 | index 4a07ff4f38e1..493d07931ea5 100644 | ||
1442 | --- a/include/linux/mm.h | ||
1443 | +++ b/include/linux/mm.h | ||
1444 | @@ -2246,6 +2246,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma, | ||
1445 | #define FOLL_MLOCK 0x1000 /* lock present pages */ | ||
1446 | #define FOLL_REMOTE 0x2000 /* we are working on non-current tsk/mm */ | ||
1447 | #define FOLL_COW 0x4000 /* internal GUP flag */ | ||
1448 | +#define FOLL_ANON 0x8000 /* don't do file mappings */ | ||
1449 | |||
1450 | typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, | ||
1451 | void *data); | ||
1452 | diff --git a/include/net/bonding.h b/include/net/bonding.h | ||
1453 | index f32f7ef8a23a..7734cc9c7d29 100644 | ||
1454 | --- a/include/net/bonding.h | ||
1455 | +++ b/include/net/bonding.h | ||
1456 | @@ -197,6 +197,7 @@ struct bonding { | ||
1457 | struct slave __rcu *primary_slave; | ||
1458 | struct bond_up_slave __rcu *slave_arr; /* Array of usable slaves */ | ||
1459 | bool force_primary; | ||
1460 | + u32 nest_level; | ||
1461 | s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ | ||
1462 | int (*recv_probe)(const struct sk_buff *, struct bonding *, | ||
1463 | struct slave *); | ||
1464 | diff --git a/kernel/exit.c b/kernel/exit.c | ||
1465 | index 3076f3089919..6dd7ff4b337a 100644 | ||
1466 | --- a/kernel/exit.c | ||
1467 | +++ b/kernel/exit.c | ||
1468 | @@ -1662,6 +1662,10 @@ SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr, | ||
1469 | __WNOTHREAD|__WCLONE|__WALL)) | ||
1470 | return -EINVAL; | ||
1471 | |||
1472 | + /* -INT_MIN is not defined */ | ||
1473 | + if (upid == INT_MIN) | ||
1474 | + return -ESRCH; | ||
1475 | + | ||
1476 | if (upid == -1) | ||
1477 | type = PIDTYPE_MAX; | ||
1478 | else if (upid < 0) { | ||
1479 | diff --git a/kernel/futex.c b/kernel/futex.c | ||
1480 | index bb2265ae5cbc..c3ea6f2a6997 100644 | ||
1481 | --- a/kernel/futex.c | ||
1482 | +++ b/kernel/futex.c | ||
1483 | @@ -1458,6 +1458,45 @@ futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) | ||
1484 | return ret; | ||
1485 | } | ||
1486 | |||
1487 | +static int futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr) | ||
1488 | +{ | ||
1489 | + unsigned int op = (encoded_op & 0x70000000) >> 28; | ||
1490 | + unsigned int cmp = (encoded_op & 0x0f000000) >> 24; | ||
1491 | + int oparg = sign_extend32((encoded_op & 0x00fff000) >> 12, 11); | ||
1492 | + int cmparg = sign_extend32(encoded_op & 0x00000fff, 11); | ||
1493 | + int oldval, ret; | ||
1494 | + | ||
1495 | + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) { | ||
1496 | + if (oparg < 0 || oparg > 31) | ||
1497 | + return -EINVAL; | ||
1498 | + oparg = 1 << oparg; | ||
1499 | + } | ||
1500 | + | ||
1501 | + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | ||
1502 | + return -EFAULT; | ||
1503 | + | ||
1504 | + ret = arch_futex_atomic_op_inuser(op, oparg, &oldval, uaddr); | ||
1505 | + if (ret) | ||
1506 | + return ret; | ||
1507 | + | ||
1508 | + switch (cmp) { | ||
1509 | + case FUTEX_OP_CMP_EQ: | ||
1510 | + return oldval == cmparg; | ||
1511 | + case FUTEX_OP_CMP_NE: | ||
1512 | + return oldval != cmparg; | ||
1513 | + case FUTEX_OP_CMP_LT: | ||
1514 | + return oldval < cmparg; | ||
1515 | + case FUTEX_OP_CMP_GE: | ||
1516 | + return oldval >= cmparg; | ||
1517 | + case FUTEX_OP_CMP_LE: | ||
1518 | + return oldval <= cmparg; | ||
1519 | + case FUTEX_OP_CMP_GT: | ||
1520 | + return oldval > cmparg; | ||
1521 | + default: | ||
1522 | + return -ENOSYS; | ||
1523 | + } | ||
1524 | +} | ||
1525 | + | ||
1526 | /* | ||
1527 | * Wake up all waiters hashed on the physical page that is mapped | ||
1528 | * to this virtual address: | ||
1529 | diff --git a/mm/gup.c b/mm/gup.c | ||
1530 | index 6c3b4e822946..be4ccddac26f 100644 | ||
1531 | --- a/mm/gup.c | ||
1532 | +++ b/mm/gup.c | ||
1533 | @@ -430,6 +430,9 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) | ||
1534 | if (vm_flags & (VM_IO | VM_PFNMAP)) | ||
1535 | return -EFAULT; | ||
1536 | |||
1537 | + if (gup_flags & FOLL_ANON && !vma_is_anonymous(vma)) | ||
1538 | + return -EFAULT; | ||
1539 | + | ||
1540 | if (write) { | ||
1541 | if (!(vm_flags & VM_WRITE)) { | ||
1542 | if (!(gup_flags & FOLL_FORCE)) | ||
1543 | diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c | ||
1544 | index ed0dd3340084..8e173324693d 100644 | ||
1545 | --- a/net/bridge/br_if.c | ||
1546 | +++ b/net/bridge/br_if.c | ||
1547 | @@ -504,8 +504,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | ||
1548 | if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit) | ||
1549 | return -ELOOP; | ||
1550 | |||
1551 | - /* Device is already being bridged */ | ||
1552 | - if (br_port_exists(dev)) | ||
1553 | + /* Device has master upper dev */ | ||
1554 | + if (netdev_master_upper_dev_get(dev)) | ||
1555 | return -EBUSY; | ||
1556 | |||
1557 | /* No bridging devices that dislike that (e.g. wireless) */ | ||
1558 | diff --git a/net/compat.c b/net/compat.c | ||
1559 | index a96fd2f3507b..73671e6ec6eb 100644 | ||
1560 | --- a/net/compat.c | ||
1561 | +++ b/net/compat.c | ||
1562 | @@ -372,7 +372,8 @@ static int compat_sock_setsockopt(struct socket *sock, int level, int optname, | ||
1563 | optname == SO_ATTACH_REUSEPORT_CBPF) | ||
1564 | return do_set_attach_filter(sock, level, optname, | ||
1565 | optval, optlen); | ||
1566 | - if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) | ||
1567 | + if (!COMPAT_USE_64BIT_TIME && | ||
1568 | + (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) | ||
1569 | return do_set_sock_timeout(sock, level, optname, optval, optlen); | ||
1570 | |||
1571 | return sock_setsockopt(sock, level, optname, optval, optlen); | ||
1572 | @@ -437,7 +438,8 @@ static int do_get_sock_timeout(struct socket *sock, int level, int optname, | ||
1573 | static int compat_sock_getsockopt(struct socket *sock, int level, int optname, | ||
1574 | char __user *optval, int __user *optlen) | ||
1575 | { | ||
1576 | - if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) | ||
1577 | + if (!COMPAT_USE_64BIT_TIME && | ||
1578 | + (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) | ||
1579 | return do_get_sock_timeout(sock, level, optname, optval, optlen); | ||
1580 | return sock_getsockopt(sock, level, optname, optval, optlen); | ||
1581 | } | ||
1582 | diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c | ||
1583 | index 7753681195c1..86a2ed0fb219 100644 | ||
1584 | --- a/net/dccp/ccids/ccid2.c | ||
1585 | +++ b/net/dccp/ccids/ccid2.c | ||
1586 | @@ -126,6 +126,16 @@ static void ccid2_change_l_seq_window(struct sock *sk, u64 val) | ||
1587 | DCCPF_SEQ_WMAX)); | ||
1588 | } | ||
1589 | |||
1590 | +static void dccp_tasklet_schedule(struct sock *sk) | ||
1591 | +{ | ||
1592 | + struct tasklet_struct *t = &dccp_sk(sk)->dccps_xmitlet; | ||
1593 | + | ||
1594 | + if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { | ||
1595 | + sock_hold(sk); | ||
1596 | + __tasklet_schedule(t); | ||
1597 | + } | ||
1598 | +} | ||
1599 | + | ||
1600 | static void ccid2_hc_tx_rto_expire(unsigned long data) | ||
1601 | { | ||
1602 | struct sock *sk = (struct sock *)data; | ||
1603 | @@ -166,7 +176,7 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) | ||
1604 | |||
1605 | /* if we were blocked before, we may now send cwnd=1 packet */ | ||
1606 | if (sender_was_blocked) | ||
1607 | - tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); | ||
1608 | + dccp_tasklet_schedule(sk); | ||
1609 | /* restart backed-off timer */ | ||
1610 | sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); | ||
1611 | out: | ||
1612 | @@ -706,7 +716,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | ||
1613 | done: | ||
1614 | /* check if incoming Acks allow pending packets to be sent */ | ||
1615 | if (sender_was_blocked && !ccid2_cwnd_network_limited(hc)) | ||
1616 | - tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); | ||
1617 | + dccp_tasklet_schedule(sk); | ||
1618 | dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks); | ||
1619 | } | ||
1620 | |||
1621 | diff --git a/net/dccp/timer.c b/net/dccp/timer.c | ||
1622 | index 3a2c34027758..2a952cbd6efa 100644 | ||
1623 | --- a/net/dccp/timer.c | ||
1624 | +++ b/net/dccp/timer.c | ||
1625 | @@ -230,12 +230,12 @@ static void dccp_write_xmitlet(unsigned long data) | ||
1626 | else | ||
1627 | dccp_write_xmit(sk); | ||
1628 | bh_unlock_sock(sk); | ||
1629 | + sock_put(sk); | ||
1630 | } | ||
1631 | |||
1632 | static void dccp_write_xmit_timer(unsigned long data) | ||
1633 | { | ||
1634 | dccp_write_xmitlet(data); | ||
1635 | - sock_put((struct sock *)data); | ||
1636 | } | ||
1637 | |||
1638 | void dccp_init_xmit_timers(struct sock *sk) | ||
1639 | diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c | ||
1640 | index e612991c9185..9adcd4b1b3fd 100644 | ||
1641 | --- a/net/ipv4/ping.c | ||
1642 | +++ b/net/ipv4/ping.c | ||
1643 | @@ -775,8 +775,10 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | ||
1644 | ipc.addr = faddr = daddr; | ||
1645 | |||
1646 | if (ipc.opt && ipc.opt->opt.srr) { | ||
1647 | - if (!daddr) | ||
1648 | - return -EINVAL; | ||
1649 | + if (!daddr) { | ||
1650 | + err = -EINVAL; | ||
1651 | + goto out_free; | ||
1652 | + } | ||
1653 | faddr = ipc.opt->opt.faddr; | ||
1654 | } | ||
1655 | tos = get_rttos(&ipc, inet); | ||
1656 | @@ -841,6 +843,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | ||
1657 | |||
1658 | out: | ||
1659 | ip_rt_put(rt); | ||
1660 | +out_free: | ||
1661 | if (free) | ||
1662 | kfree(ipc.opt); | ||
1663 | if (!err) { | ||
1664 | diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c | ||
1665 | index 6f501c9deaae..84ffebf0192d 100644 | ||
1666 | --- a/net/ipv4/tcp.c | ||
1667 | +++ b/net/ipv4/tcp.c | ||
1668 | @@ -1118,7 +1118,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) | ||
1669 | lock_sock(sk); | ||
1670 | |||
1671 | flags = msg->msg_flags; | ||
1672 | - if (flags & MSG_FASTOPEN) { | ||
1673 | + if ((flags & MSG_FASTOPEN) && !tp->repair) { | ||
1674 | err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size); | ||
1675 | if (err == -EINPROGRESS && copied_syn > 0) | ||
1676 | goto out; | ||
1677 | diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c | ||
1678 | index 8ec60532be2b..9169859506b7 100644 | ||
1679 | --- a/net/ipv4/tcp_bbr.c | ||
1680 | +++ b/net/ipv4/tcp_bbr.c | ||
1681 | @@ -773,7 +773,9 @@ static void bbr_update_min_rtt(struct sock *sk, const struct rate_sample *rs) | ||
1682 | } | ||
1683 | } | ||
1684 | } | ||
1685 | - bbr->idle_restart = 0; | ||
1686 | + /* Restart after idle ends only once we process a new S/ACK for data */ | ||
1687 | + if (rs->delivered > 0) | ||
1688 | + bbr->idle_restart = 0; | ||
1689 | } | ||
1690 | |||
1691 | static void bbr_update_model(struct sock *sk, const struct rate_sample *rs) | ||
1692 | diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c | ||
1693 | index 4cd943096afa..aa2a20e918fd 100644 | ||
1694 | --- a/net/ipv4/udp.c | ||
1695 | +++ b/net/ipv4/udp.c | ||
1696 | @@ -982,8 +982,10 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | ||
1697 | sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags); | ||
1698 | |||
1699 | if (ipc.opt && ipc.opt->opt.srr) { | ||
1700 | - if (!daddr) | ||
1701 | - return -EINVAL; | ||
1702 | + if (!daddr) { | ||
1703 | + err = -EINVAL; | ||
1704 | + goto out_free; | ||
1705 | + } | ||
1706 | faddr = ipc.opt->opt.faddr; | ||
1707 | connected = 0; | ||
1708 | } | ||
1709 | @@ -1090,6 +1092,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | ||
1710 | |||
1711 | out: | ||
1712 | ip_rt_put(rt); | ||
1713 | +out_free: | ||
1714 | if (free) | ||
1715 | kfree(ipc.opt); | ||
1716 | if (!err) | ||
1717 | diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c | ||
1718 | index ce1238492c0f..ee03bc866d1b 100644 | ||
1719 | --- a/net/l2tp/l2tp_netlink.c | ||
1720 | +++ b/net/l2tp/l2tp_netlink.c | ||
1721 | @@ -750,8 +750,6 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl | ||
1722 | |||
1723 | if ((session->ifname[0] && | ||
1724 | nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) || | ||
1725 | - (session->offset && | ||
1726 | - nla_put_u16(skb, L2TP_ATTR_OFFSET, session->offset)) || | ||
1727 | (session->cookie_len && | ||
1728 | nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len, | ||
1729 | &session->cookie[0])) || | ||
1730 | diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c | ||
1731 | index d6bc5f2a1175..85aae8c84aeb 100644 | ||
1732 | --- a/net/llc/af_llc.c | ||
1733 | +++ b/net/llc/af_llc.c | ||
1734 | @@ -926,6 +926,9 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) | ||
1735 | if (size > llc->dev->mtu) | ||
1736 | size = llc->dev->mtu; | ||
1737 | copied = size - hdrlen; | ||
1738 | + rc = -EINVAL; | ||
1739 | + if (copied < 0) | ||
1740 | + goto release; | ||
1741 | release_sock(sk); | ||
1742 | skb = sock_alloc_send_skb(sk, size, noblock, &rc); | ||
1743 | lock_sock(sk); | ||
1744 | diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c | ||
1745 | index 1668916bdbde..326945d9be5f 100644 | ||
1746 | --- a/net/openvswitch/flow_netlink.c | ||
1747 | +++ b/net/openvswitch/flow_netlink.c | ||
1748 | @@ -1296,13 +1296,10 @@ static void nlattr_set(struct nlattr *attr, u8 val, | ||
1749 | |||
1750 | /* The nlattr stream should already have been validated */ | ||
1751 | nla_for_each_nested(nla, attr, rem) { | ||
1752 | - if (tbl[nla_type(nla)].len == OVS_ATTR_NESTED) { | ||
1753 | - if (tbl[nla_type(nla)].next) | ||
1754 | - tbl = tbl[nla_type(nla)].next; | ||
1755 | - nlattr_set(nla, val, tbl); | ||
1756 | - } else { | ||
1757 | + if (tbl[nla_type(nla)].len == OVS_ATTR_NESTED) | ||
1758 | + nlattr_set(nla, val, tbl[nla_type(nla)].next ? : tbl); | ||
1759 | + else | ||
1760 | memset(nla_data(nla), val, nla_len(nla)); | ||
1761 | - } | ||
1762 | |||
1763 | if (nla_type(nla) == OVS_KEY_ATTR_CT_STATE) | ||
1764 | *(u32 *)nla_data(nla) &= CT_SUPPORTED_MASK; | ||
1765 | diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c | ||
1766 | index 18e752439f6f..b57b4de73038 100644 | ||
1767 | --- a/net/sched/sch_fq.c | ||
1768 | +++ b/net/sched/sch_fq.c | ||
1769 | @@ -128,6 +128,28 @@ static bool fq_flow_is_detached(const struct fq_flow *f) | ||
1770 | return f->next == &detached; | ||
1771 | } | ||
1772 | |||
1773 | +static bool fq_flow_is_throttled(const struct fq_flow *f) | ||
1774 | +{ | ||
1775 | + return f->next == &throttled; | ||
1776 | +} | ||
1777 | + | ||
1778 | +static void fq_flow_add_tail(struct fq_flow_head *head, struct fq_flow *flow) | ||
1779 | +{ | ||
1780 | + if (head->first) | ||
1781 | + head->last->next = flow; | ||
1782 | + else | ||
1783 | + head->first = flow; | ||
1784 | + head->last = flow; | ||
1785 | + flow->next = NULL; | ||
1786 | +} | ||
1787 | + | ||
1788 | +static void fq_flow_unset_throttled(struct fq_sched_data *q, struct fq_flow *f) | ||
1789 | +{ | ||
1790 | + rb_erase(&f->rate_node, &q->delayed); | ||
1791 | + q->throttled_flows--; | ||
1792 | + fq_flow_add_tail(&q->old_flows, f); | ||
1793 | +} | ||
1794 | + | ||
1795 | static void fq_flow_set_throttled(struct fq_sched_data *q, struct fq_flow *f) | ||
1796 | { | ||
1797 | struct rb_node **p = &q->delayed.rb_node, *parent = NULL; | ||
1798 | @@ -155,15 +177,6 @@ static void fq_flow_set_throttled(struct fq_sched_data *q, struct fq_flow *f) | ||
1799 | |||
1800 | static struct kmem_cache *fq_flow_cachep __read_mostly; | ||
1801 | |||
1802 | -static void fq_flow_add_tail(struct fq_flow_head *head, struct fq_flow *flow) | ||
1803 | -{ | ||
1804 | - if (head->first) | ||
1805 | - head->last->next = flow; | ||
1806 | - else | ||
1807 | - head->first = flow; | ||
1808 | - head->last = flow; | ||
1809 | - flow->next = NULL; | ||
1810 | -} | ||
1811 | |||
1812 | /* limit number of collected flows per round */ | ||
1813 | #define FQ_GC_MAX 8 | ||
1814 | @@ -267,6 +280,8 @@ static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q) | ||
1815 | f->socket_hash != sk->sk_hash)) { | ||
1816 | f->credit = q->initial_quantum; | ||
1817 | f->socket_hash = sk->sk_hash; | ||
1818 | + if (fq_flow_is_throttled(f)) | ||
1819 | + fq_flow_unset_throttled(q, f); | ||
1820 | f->time_next_packet = 0ULL; | ||
1821 | } | ||
1822 | return f; | ||
1823 | @@ -430,9 +445,7 @@ static void fq_check_throttled(struct fq_sched_data *q, u64 now) | ||
1824 | q->time_next_delayed_flow = f->time_next_packet; | ||
1825 | break; | ||
1826 | } | ||
1827 | - rb_erase(p, &q->delayed); | ||
1828 | - q->throttled_flows--; | ||
1829 | - fq_flow_add_tail(&q->old_flows, f); | ||
1830 | + fq_flow_unset_throttled(q, f); | ||
1831 | } | ||
1832 | } | ||
1833 | |||
1834 | diff --git a/net/sctp/associola.c b/net/sctp/associola.c | ||
1835 | index f10d3397f917..738c55e994c4 100644 | ||
1836 | --- a/net/sctp/associola.c | ||
1837 | +++ b/net/sctp/associola.c | ||
1838 | @@ -1006,9 +1006,10 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) | ||
1839 | struct sctp_endpoint *ep; | ||
1840 | struct sctp_chunk *chunk; | ||
1841 | struct sctp_inq *inqueue; | ||
1842 | - int state; | ||
1843 | sctp_subtype_t subtype; | ||
1844 | + int first_time = 1; /* is this the first time through the loop */ | ||
1845 | int error = 0; | ||
1846 | + int state; | ||
1847 | |||
1848 | /* The association should be held so we should be safe. */ | ||
1849 | ep = asoc->ep; | ||
1850 | @@ -1019,6 +1020,30 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) | ||
1851 | state = asoc->state; | ||
1852 | subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type); | ||
1853 | |||
1854 | + /* If the first chunk in the packet is AUTH, do special | ||
1855 | + * processing specified in Section 6.3 of SCTP-AUTH spec | ||
1856 | + */ | ||
1857 | + if (first_time && subtype.chunk == SCTP_CID_AUTH) { | ||
1858 | + struct sctp_chunkhdr *next_hdr; | ||
1859 | + | ||
1860 | + next_hdr = sctp_inq_peek(inqueue); | ||
1861 | + if (!next_hdr) | ||
1862 | + goto normal; | ||
1863 | + | ||
1864 | + /* If the next chunk is COOKIE-ECHO, skip the AUTH | ||
1865 | + * chunk while saving a pointer to it so we can do | ||
1866 | + * Authentication later (during cookie-echo | ||
1867 | + * processing). | ||
1868 | + */ | ||
1869 | + if (next_hdr->type == SCTP_CID_COOKIE_ECHO) { | ||
1870 | + chunk->auth_chunk = skb_clone(chunk->skb, | ||
1871 | + GFP_ATOMIC); | ||
1872 | + chunk->auth = 1; | ||
1873 | + continue; | ||
1874 | + } | ||
1875 | + } | ||
1876 | + | ||
1877 | +normal: | ||
1878 | /* SCTP-AUTH, Section 6.3: | ||
1879 | * The receiver has a list of chunk types which it expects | ||
1880 | * to be received only after an AUTH-chunk. This list has | ||
1881 | @@ -1057,6 +1082,9 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) | ||
1882 | /* If there is an error on chunk, discard this packet. */ | ||
1883 | if (error && chunk) | ||
1884 | chunk->pdiscard = 1; | ||
1885 | + | ||
1886 | + if (first_time) | ||
1887 | + first_time = 0; | ||
1888 | } | ||
1889 | sctp_association_put(asoc); | ||
1890 | } | ||
1891 | diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c | ||
1892 | index f731de3e8428..e06083c53f57 100644 | ||
1893 | --- a/net/sctp/inqueue.c | ||
1894 | +++ b/net/sctp/inqueue.c | ||
1895 | @@ -217,7 +217,7 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) | ||
1896 | skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t)); | ||
1897 | chunk->subh.v = NULL; /* Subheader is no longer valid. */ | ||
1898 | |||
1899 | - if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) < | ||
1900 | + if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) <= | ||
1901 | skb_tail_pointer(chunk->skb)) { | ||
1902 | /* This is not a singleton */ | ||
1903 | chunk->singleton = 0; | ||
1904 | diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c | ||
1905 | index e031797ad311..f4d5efb1d231 100644 | ||
1906 | --- a/net/sctp/ipv6.c | ||
1907 | +++ b/net/sctp/ipv6.c | ||
1908 | @@ -864,6 +864,9 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1, | ||
1909 | if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2)) | ||
1910 | return 1; | ||
1911 | |||
1912 | + if (addr1->sa.sa_family == AF_INET && addr2->sa.sa_family == AF_INET) | ||
1913 | + return addr1->v4.sin_addr.s_addr == addr2->v4.sin_addr.s_addr; | ||
1914 | + | ||
1915 | return __sctp_v6_cmp_addr(addr1, addr2); | ||
1916 | } | ||
1917 | |||
1918 | diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c | ||
1919 | index 8ec20a64a3f8..bfd068679710 100644 | ||
1920 | --- a/net/sctp/sm_statefuns.c | ||
1921 | +++ b/net/sctp/sm_statefuns.c | ||
1922 | @@ -144,10 +144,8 @@ static sctp_disposition_t sctp_sf_violation_chunk( | ||
1923 | void *arg, | ||
1924 | sctp_cmd_seq_t *commands); | ||
1925 | |||
1926 | -static sctp_ierror_t sctp_sf_authenticate(struct net *net, | ||
1927 | - const struct sctp_endpoint *ep, | ||
1928 | +static sctp_ierror_t sctp_sf_authenticate( | ||
1929 | const struct sctp_association *asoc, | ||
1930 | - const sctp_subtype_t type, | ||
1931 | struct sctp_chunk *chunk); | ||
1932 | |||
1933 | static sctp_disposition_t __sctp_sf_do_9_1_abort(struct net *net, | ||
1934 | @@ -615,6 +613,38 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net, | ||
1935 | return SCTP_DISPOSITION_CONSUME; | ||
1936 | } | ||
1937 | |||
1938 | +static bool sctp_auth_chunk_verify(struct net *net, struct sctp_chunk *chunk, | ||
1939 | + const struct sctp_association *asoc) | ||
1940 | +{ | ||
1941 | + struct sctp_chunk auth; | ||
1942 | + | ||
1943 | + if (!chunk->auth_chunk) | ||
1944 | + return true; | ||
1945 | + | ||
1946 | + /* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo | ||
1947 | + * is supposed to be authenticated and we have to do delayed | ||
1948 | + * authentication. We've just recreated the association using | ||
1949 | + * the information in the cookie and now it's much easier to | ||
1950 | + * do the authentication. | ||
1951 | + */ | ||
1952 | + | ||
1953 | + /* Make sure that we and the peer are AUTH capable */ | ||
1954 | + if (!net->sctp.auth_enable || !asoc->peer.auth_capable) | ||
1955 | + return false; | ||
1956 | + | ||
1957 | + /* set-up our fake chunk so that we can process it */ | ||
1958 | + auth.skb = chunk->auth_chunk; | ||
1959 | + auth.asoc = chunk->asoc; | ||
1960 | + auth.sctp_hdr = chunk->sctp_hdr; | ||
1961 | + auth.chunk_hdr = (struct sctp_chunkhdr *) | ||
1962 | + skb_push(chunk->auth_chunk, | ||
1963 | + sizeof(struct sctp_chunkhdr)); | ||
1964 | + skb_pull(chunk->auth_chunk, sizeof(struct sctp_chunkhdr)); | ||
1965 | + auth.transport = chunk->transport; | ||
1966 | + | ||
1967 | + return sctp_sf_authenticate(asoc, &auth) == SCTP_IERROR_NO_ERROR; | ||
1968 | +} | ||
1969 | + | ||
1970 | /* | ||
1971 | * Respond to a normal COOKIE ECHO chunk. | ||
1972 | * We are the side that is being asked for an association. | ||
1973 | @@ -751,36 +781,9 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, | ||
1974 | if (error) | ||
1975 | goto nomem_init; | ||
1976 | |||
1977 | - /* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo | ||
1978 | - * is supposed to be authenticated and we have to do delayed | ||
1979 | - * authentication. We've just recreated the association using | ||
1980 | - * the information in the cookie and now it's much easier to | ||
1981 | - * do the authentication. | ||
1982 | - */ | ||
1983 | - if (chunk->auth_chunk) { | ||
1984 | - struct sctp_chunk auth; | ||
1985 | - sctp_ierror_t ret; | ||
1986 | - | ||
1987 | - /* Make sure that we and the peer are AUTH capable */ | ||
1988 | - if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) { | ||
1989 | - sctp_association_free(new_asoc); | ||
1990 | - return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); | ||
1991 | - } | ||
1992 | - | ||
1993 | - /* set-up our fake chunk so that we can process it */ | ||
1994 | - auth.skb = chunk->auth_chunk; | ||
1995 | - auth.asoc = chunk->asoc; | ||
1996 | - auth.sctp_hdr = chunk->sctp_hdr; | ||
1997 | - auth.chunk_hdr = (sctp_chunkhdr_t *)skb_push(chunk->auth_chunk, | ||
1998 | - sizeof(sctp_chunkhdr_t)); | ||
1999 | - skb_pull(chunk->auth_chunk, sizeof(sctp_chunkhdr_t)); | ||
2000 | - auth.transport = chunk->transport; | ||
2001 | - | ||
2002 | - ret = sctp_sf_authenticate(net, ep, new_asoc, type, &auth); | ||
2003 | - if (ret != SCTP_IERROR_NO_ERROR) { | ||
2004 | - sctp_association_free(new_asoc); | ||
2005 | - return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); | ||
2006 | - } | ||
2007 | + if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) { | ||
2008 | + sctp_association_free(new_asoc); | ||
2009 | + return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); | ||
2010 | } | ||
2011 | |||
2012 | repl = sctp_make_cookie_ack(new_asoc, chunk); | ||
2013 | @@ -1717,13 +1720,15 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net, | ||
2014 | GFP_ATOMIC)) | ||
2015 | goto nomem; | ||
2016 | |||
2017 | + if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) | ||
2018 | + return SCTP_DISPOSITION_DISCARD; | ||
2019 | + | ||
2020 | /* Make sure no new addresses are being added during the | ||
2021 | * restart. Though this is a pretty complicated attack | ||
2022 | * since you'd have to get inside the cookie. | ||
2023 | */ | ||
2024 | - if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands)) { | ||
2025 | + if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands)) | ||
2026 | return SCTP_DISPOSITION_CONSUME; | ||
2027 | - } | ||
2028 | |||
2029 | /* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes | ||
2030 | * the peer has restarted (Action A), it MUST NOT setup a new | ||
2031 | @@ -1828,6 +1833,9 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(struct net *net, | ||
2032 | GFP_ATOMIC)) | ||
2033 | goto nomem; | ||
2034 | |||
2035 | + if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) | ||
2036 | + return SCTP_DISPOSITION_DISCARD; | ||
2037 | + | ||
2038 | /* Update the content of current association. */ | ||
2039 | sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); | ||
2040 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | ||
2041 | @@ -1920,6 +1928,9 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(struct net *net, | ||
2042 | * a COOKIE ACK. | ||
2043 | */ | ||
2044 | |||
2045 | + if (!sctp_auth_chunk_verify(net, chunk, asoc)) | ||
2046 | + return SCTP_DISPOSITION_DISCARD; | ||
2047 | + | ||
2048 | /* Don't accidentally move back into established state. */ | ||
2049 | if (asoc->state < SCTP_STATE_ESTABLISHED) { | ||
2050 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | ||
2051 | @@ -1959,7 +1970,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(struct net *net, | ||
2052 | } | ||
2053 | } | ||
2054 | |||
2055 | - repl = sctp_make_cookie_ack(new_asoc, chunk); | ||
2056 | + repl = sctp_make_cookie_ack(asoc, chunk); | ||
2057 | if (!repl) | ||
2058 | goto nomem; | ||
2059 | |||
2060 | @@ -3981,10 +3992,8 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast( | ||
2061 | * | ||
2062 | * The return value is the disposition of the chunk. | ||
2063 | */ | ||
2064 | -static sctp_ierror_t sctp_sf_authenticate(struct net *net, | ||
2065 | - const struct sctp_endpoint *ep, | ||
2066 | +static sctp_ierror_t sctp_sf_authenticate( | ||
2067 | const struct sctp_association *asoc, | ||
2068 | - const sctp_subtype_t type, | ||
2069 | struct sctp_chunk *chunk) | ||
2070 | { | ||
2071 | struct sctp_authhdr *auth_hdr; | ||
2072 | @@ -4083,7 +4092,7 @@ sctp_disposition_t sctp_sf_eat_auth(struct net *net, | ||
2073 | commands); | ||
2074 | |||
2075 | auth_hdr = (struct sctp_authhdr *)chunk->skb->data; | ||
2076 | - error = sctp_sf_authenticate(net, ep, asoc, type, chunk); | ||
2077 | + error = sctp_sf_authenticate(asoc, chunk); | ||
2078 | switch (error) { | ||
2079 | case SCTP_IERROR_AUTH_BAD_HMAC: | ||
2080 | /* Generate the ERROR chunk and discard the rest | ||
2081 | diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c | ||
2082 | index bea00058ce35..6825e05a68b2 100644 | ||
2083 | --- a/net/sctp/ulpevent.c | ||
2084 | +++ b/net/sctp/ulpevent.c | ||
2085 | @@ -723,7 +723,6 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, | ||
2086 | return event; | ||
2087 | |||
2088 | fail_mark: | ||
2089 | - sctp_chunk_put(chunk); | ||
2090 | kfree_skb(skb); | ||
2091 | fail: | ||
2092 | return NULL; | ||
2093 | diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c | ||
2094 | index 6f5635770d6a..71a94e549301 100644 | ||
2095 | --- a/net/xfrm/xfrm_state.c | ||
2096 | +++ b/net/xfrm/xfrm_state.c | ||
2097 | @@ -1197,6 +1197,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig) | ||
2098 | |||
2099 | if (orig->aead) { | ||
2100 | x->aead = xfrm_algo_aead_clone(orig->aead); | ||
2101 | + x->geniv = orig->geniv; | ||
2102 | if (!x->aead) | ||
2103 | goto error; | ||
2104 | } |