Contents of /trunk/kernel-alx/patches-4.9/0213-4.9.114-all-fixes.patch
Parent Directory | Revision Log
Revision 3190 -
(show annotations)
(download)
Wed Aug 8 14:17:40 2018 UTC (6 years, 1 month ago) by niro
File size: 100718 byte(s)
Wed Aug 8 14:17:40 2018 UTC (6 years, 1 month ago) by niro
File size: 100718 byte(s)
-linux-4.9.114
1 | diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt |
2 | index 52240a63132e..a16f87e4dd10 100644 |
3 | --- a/Documentation/kernel-parameters.txt |
4 | +++ b/Documentation/kernel-parameters.txt |
5 | @@ -4023,6 +4023,23 @@ bytes respectively. Such letter suffixes can also be entirely omitted. |
6 | spia_pedr= |
7 | spia_peddr= |
8 | |
9 | + ssbd= [ARM64,HW] |
10 | + Speculative Store Bypass Disable control |
11 | + |
12 | + On CPUs that are vulnerable to the Speculative |
13 | + Store Bypass vulnerability and offer a |
14 | + firmware based mitigation, this parameter |
15 | + indicates how the mitigation should be used: |
16 | + |
17 | + force-on: Unconditionally enable mitigation for |
18 | + for both kernel and userspace |
19 | + force-off: Unconditionally disable mitigation for |
20 | + for both kernel and userspace |
21 | + kernel: Always enable mitigation in the |
22 | + kernel, and offer a prctl interface |
23 | + to allow userspace to register its |
24 | + interest in being mitigated too. |
25 | + |
26 | stack_guard_gap= [MM] |
27 | override the default stack gap protection. The value |
28 | is in page units and it defines how many pages prior |
29 | diff --git a/Makefile b/Makefile |
30 | index 3884afb2850f..f4cd42c9b940 100644 |
31 | --- a/Makefile |
32 | +++ b/Makefile |
33 | @@ -1,6 +1,6 @@ |
34 | VERSION = 4 |
35 | PATCHLEVEL = 9 |
36 | -SUBLEVEL = 113 |
37 | +SUBLEVEL = 114 |
38 | EXTRAVERSION = |
39 | NAME = Roaring Lionus |
40 | |
41 | diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h |
42 | index f4dab20ac9f3..0833d8a1dbbb 100644 |
43 | --- a/arch/arm/include/asm/kvm_host.h |
44 | +++ b/arch/arm/include/asm/kvm_host.h |
45 | @@ -327,4 +327,16 @@ static inline bool kvm_arm_harden_branch_predictor(void) |
46 | return false; |
47 | } |
48 | |
49 | +#define KVM_SSBD_UNKNOWN -1 |
50 | +#define KVM_SSBD_FORCE_DISABLE 0 |
51 | +#define KVM_SSBD_KERNEL 1 |
52 | +#define KVM_SSBD_FORCE_ENABLE 2 |
53 | +#define KVM_SSBD_MITIGATED 3 |
54 | + |
55 | +static inline int kvm_arm_have_ssbd(void) |
56 | +{ |
57 | + /* No way to detect it yet, pretend it is not there. */ |
58 | + return KVM_SSBD_UNKNOWN; |
59 | +} |
60 | + |
61 | #endif /* __ARM_KVM_HOST_H__ */ |
62 | diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h |
63 | index 7f66b1b3aca1..e2f05cedaf97 100644 |
64 | --- a/arch/arm/include/asm/kvm_mmu.h |
65 | +++ b/arch/arm/include/asm/kvm_mmu.h |
66 | @@ -28,6 +28,13 @@ |
67 | */ |
68 | #define kern_hyp_va(kva) (kva) |
69 | |
70 | +/* Contrary to arm64, there is no need to generate a PC-relative address */ |
71 | +#define hyp_symbol_addr(s) \ |
72 | + ({ \ |
73 | + typeof(s) *addr = &(s); \ |
74 | + addr; \ |
75 | + }) |
76 | + |
77 | /* |
78 | * KVM_MMU_CACHE_MIN_PAGES is the number of stage2 page table translation levels. |
79 | */ |
80 | @@ -249,6 +256,11 @@ static inline int kvm_map_vectors(void) |
81 | return 0; |
82 | } |
83 | |
84 | +static inline int hyp_map_aux_data(void) |
85 | +{ |
86 | + return 0; |
87 | +} |
88 | + |
89 | #endif /* !__ASSEMBLY__ */ |
90 | |
91 | #endif /* __ARM_KVM_MMU_H__ */ |
92 | diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c |
93 | index ef6595c7d697..20436972537f 100644 |
94 | --- a/arch/arm/kvm/arm.c |
95 | +++ b/arch/arm/kvm/arm.c |
96 | @@ -51,8 +51,8 @@ |
97 | __asm__(".arch_extension virt"); |
98 | #endif |
99 | |
100 | +DEFINE_PER_CPU(kvm_cpu_context_t, kvm_host_cpu_state); |
101 | static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page); |
102 | -static kvm_cpu_context_t __percpu *kvm_host_cpu_state; |
103 | static unsigned long hyp_default_vectors; |
104 | |
105 | /* Per-CPU variable containing the currently running vcpu. */ |
106 | @@ -338,7 +338,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
107 | } |
108 | |
109 | vcpu->cpu = cpu; |
110 | - vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state); |
111 | + vcpu->arch.host_cpu_context = this_cpu_ptr(&kvm_host_cpu_state); |
112 | |
113 | kvm_arm_set_running_vcpu(vcpu); |
114 | } |
115 | @@ -1199,19 +1199,8 @@ static inline void hyp_cpu_pm_exit(void) |
116 | } |
117 | #endif |
118 | |
119 | -static void teardown_common_resources(void) |
120 | -{ |
121 | - free_percpu(kvm_host_cpu_state); |
122 | -} |
123 | - |
124 | static int init_common_resources(void) |
125 | { |
126 | - kvm_host_cpu_state = alloc_percpu(kvm_cpu_context_t); |
127 | - if (!kvm_host_cpu_state) { |
128 | - kvm_err("Cannot allocate host CPU state\n"); |
129 | - return -ENOMEM; |
130 | - } |
131 | - |
132 | /* set size of VMID supported by CPU */ |
133 | kvm_vmid_bits = kvm_get_vmid_bits(); |
134 | kvm_info("%d-bit VMID\n", kvm_vmid_bits); |
135 | @@ -1369,7 +1358,7 @@ static int init_hyp_mode(void) |
136 | for_each_possible_cpu(cpu) { |
137 | kvm_cpu_context_t *cpu_ctxt; |
138 | |
139 | - cpu_ctxt = per_cpu_ptr(kvm_host_cpu_state, cpu); |
140 | + cpu_ctxt = per_cpu_ptr(&kvm_host_cpu_state, cpu); |
141 | err = create_hyp_mappings(cpu_ctxt, cpu_ctxt + 1, PAGE_HYP); |
142 | |
143 | if (err) { |
144 | @@ -1378,6 +1367,12 @@ static int init_hyp_mode(void) |
145 | } |
146 | } |
147 | |
148 | + err = hyp_map_aux_data(); |
149 | + if (err) { |
150 | + kvm_err("Cannot map host auxilary data: %d\n", err); |
151 | + goto out_err; |
152 | + } |
153 | + |
154 | kvm_info("Hyp mode initialized successfully\n"); |
155 | |
156 | return 0; |
157 | @@ -1447,7 +1442,6 @@ int kvm_arch_init(void *opaque) |
158 | out_hyp: |
159 | teardown_hyp_mode(); |
160 | out_err: |
161 | - teardown_common_resources(); |
162 | return err; |
163 | } |
164 | |
165 | diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c |
166 | index 8a9c654f4f87..83365bec04b6 100644 |
167 | --- a/arch/arm/kvm/psci.c |
168 | +++ b/arch/arm/kvm/psci.c |
169 | @@ -403,7 +403,7 @@ static int kvm_psci_call(struct kvm_vcpu *vcpu) |
170 | int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) |
171 | { |
172 | u32 func_id = smccc_get_function(vcpu); |
173 | - u32 val = PSCI_RET_NOT_SUPPORTED; |
174 | + u32 val = SMCCC_RET_NOT_SUPPORTED; |
175 | u32 feature; |
176 | |
177 | switch (func_id) { |
178 | @@ -415,7 +415,21 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) |
179 | switch(feature) { |
180 | case ARM_SMCCC_ARCH_WORKAROUND_1: |
181 | if (kvm_arm_harden_branch_predictor()) |
182 | - val = 0; |
183 | + val = SMCCC_RET_SUCCESS; |
184 | + break; |
185 | + case ARM_SMCCC_ARCH_WORKAROUND_2: |
186 | + switch (kvm_arm_have_ssbd()) { |
187 | + case KVM_SSBD_FORCE_DISABLE: |
188 | + case KVM_SSBD_UNKNOWN: |
189 | + break; |
190 | + case KVM_SSBD_KERNEL: |
191 | + val = SMCCC_RET_SUCCESS; |
192 | + break; |
193 | + case KVM_SSBD_FORCE_ENABLE: |
194 | + case KVM_SSBD_MITIGATED: |
195 | + val = SMCCC_RET_NOT_REQUIRED; |
196 | + break; |
197 | + } |
198 | break; |
199 | } |
200 | break; |
201 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig |
202 | index d0df3611d1e2..3e43874568f9 100644 |
203 | --- a/arch/arm64/Kconfig |
204 | +++ b/arch/arm64/Kconfig |
205 | @@ -776,6 +776,15 @@ config HARDEN_BRANCH_PREDICTOR |
206 | |
207 | If unsure, say Y. |
208 | |
209 | +config ARM64_SSBD |
210 | + bool "Speculative Store Bypass Disable" if EXPERT |
211 | + default y |
212 | + help |
213 | + This enables mitigation of the bypassing of previous stores |
214 | + by speculative loads. |
215 | + |
216 | + If unsure, say Y. |
217 | + |
218 | menuconfig ARMV8_DEPRECATED |
219 | bool "Emulate deprecated/obsolete ARMv8 instructions" |
220 | depends on COMPAT |
221 | diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h |
222 | index 6e1cb8c5af4d..7e842dcae450 100644 |
223 | --- a/arch/arm64/include/asm/alternative.h |
224 | +++ b/arch/arm64/include/asm/alternative.h |
225 | @@ -4,6 +4,8 @@ |
226 | #include <asm/cpucaps.h> |
227 | #include <asm/insn.h> |
228 | |
229 | +#define ARM64_CB_PATCH ARM64_NCAPS |
230 | + |
231 | #ifndef __ASSEMBLY__ |
232 | |
233 | #include <linux/init.h> |
234 | @@ -11,6 +13,8 @@ |
235 | #include <linux/stddef.h> |
236 | #include <linux/stringify.h> |
237 | |
238 | +extern int alternatives_applied; |
239 | + |
240 | struct alt_instr { |
241 | s32 orig_offset; /* offset to original instruction */ |
242 | s32 alt_offset; /* offset to replacement instruction */ |
243 | @@ -19,12 +23,19 @@ struct alt_instr { |
244 | u8 alt_len; /* size of new instruction(s), <= orig_len */ |
245 | }; |
246 | |
247 | +typedef void (*alternative_cb_t)(struct alt_instr *alt, |
248 | + __le32 *origptr, __le32 *updptr, int nr_inst); |
249 | + |
250 | void __init apply_alternatives_all(void); |
251 | void apply_alternatives(void *start, size_t length); |
252 | |
253 | -#define ALTINSTR_ENTRY(feature) \ |
254 | +#define ALTINSTR_ENTRY(feature,cb) \ |
255 | " .word 661b - .\n" /* label */ \ |
256 | + " .if " __stringify(cb) " == 0\n" \ |
257 | " .word 663f - .\n" /* new instruction */ \ |
258 | + " .else\n" \ |
259 | + " .word " __stringify(cb) "- .\n" /* callback */ \ |
260 | + " .endif\n" \ |
261 | " .hword " __stringify(feature) "\n" /* feature bit */ \ |
262 | " .byte 662b-661b\n" /* source len */ \ |
263 | " .byte 664f-663f\n" /* replacement len */ |
264 | @@ -42,15 +53,18 @@ void apply_alternatives(void *start, size_t length); |
265 | * but most assemblers die if insn1 or insn2 have a .inst. This should |
266 | * be fixed in a binutils release posterior to 2.25.51.0.2 (anything |
267 | * containing commit 4e4d08cf7399b606 or c1baaddf8861). |
268 | + * |
269 | + * Alternatives with callbacks do not generate replacement instructions. |
270 | */ |
271 | -#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled) \ |
272 | +#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled, cb) \ |
273 | ".if "__stringify(cfg_enabled)" == 1\n" \ |
274 | "661:\n\t" \ |
275 | oldinstr "\n" \ |
276 | "662:\n" \ |
277 | ".pushsection .altinstructions,\"a\"\n" \ |
278 | - ALTINSTR_ENTRY(feature) \ |
279 | + ALTINSTR_ENTRY(feature,cb) \ |
280 | ".popsection\n" \ |
281 | + " .if " __stringify(cb) " == 0\n" \ |
282 | ".pushsection .altinstr_replacement, \"a\"\n" \ |
283 | "663:\n\t" \ |
284 | newinstr "\n" \ |
285 | @@ -58,11 +72,17 @@ void apply_alternatives(void *start, size_t length); |
286 | ".popsection\n\t" \ |
287 | ".org . - (664b-663b) + (662b-661b)\n\t" \ |
288 | ".org . - (662b-661b) + (664b-663b)\n" \ |
289 | + ".else\n\t" \ |
290 | + "663:\n\t" \ |
291 | + "664:\n\t" \ |
292 | + ".endif\n" \ |
293 | ".endif\n" |
294 | |
295 | #define _ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg, ...) \ |
296 | - __ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg)) |
297 | + __ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg), 0) |
298 | |
299 | +#define ALTERNATIVE_CB(oldinstr, cb) \ |
300 | + __ALTERNATIVE_CFG(oldinstr, "NOT_AN_INSTRUCTION", ARM64_CB_PATCH, 1, cb) |
301 | #else |
302 | |
303 | #include <asm/assembler.h> |
304 | @@ -129,6 +149,14 @@ void apply_alternatives(void *start, size_t length); |
305 | 661: |
306 | .endm |
307 | |
308 | +.macro alternative_cb cb |
309 | + .set .Lasm_alt_mode, 0 |
310 | + .pushsection .altinstructions, "a" |
311 | + altinstruction_entry 661f, \cb, ARM64_CB_PATCH, 662f-661f, 0 |
312 | + .popsection |
313 | +661: |
314 | +.endm |
315 | + |
316 | /* |
317 | * Provide the other half of the alternative code sequence. |
318 | */ |
319 | @@ -154,6 +182,13 @@ void apply_alternatives(void *start, size_t length); |
320 | .org . - (662b-661b) + (664b-663b) |
321 | .endm |
322 | |
323 | +/* |
324 | + * Callback-based alternative epilogue |
325 | + */ |
326 | +.macro alternative_cb_end |
327 | +662: |
328 | +.endm |
329 | + |
330 | /* |
331 | * Provides a trivial alternative or default sequence consisting solely |
332 | * of NOPs. The number of NOPs is chosen automatically to match the |
333 | diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h |
334 | index bfcfec3590f6..3f85bbcd7e40 100644 |
335 | --- a/arch/arm64/include/asm/assembler.h |
336 | +++ b/arch/arm64/include/asm/assembler.h |
337 | @@ -239,14 +239,33 @@ lr .req x30 // link register |
338 | .endm |
339 | |
340 | /* |
341 | + * @dst: Result of per_cpu(sym, smp_processor_id()) |
342 | * @sym: The name of the per-cpu variable |
343 | - * @reg: Result of per_cpu(sym, smp_processor_id()) |
344 | * @tmp: scratch register |
345 | */ |
346 | - .macro this_cpu_ptr, sym, reg, tmp |
347 | - adr_l \reg, \sym |
348 | + .macro adr_this_cpu, dst, sym, tmp |
349 | + adr_l \dst, \sym |
350 | +alternative_if_not ARM64_HAS_VIRT_HOST_EXTN |
351 | mrs \tmp, tpidr_el1 |
352 | - add \reg, \reg, \tmp |
353 | +alternative_else |
354 | + mrs \tmp, tpidr_el2 |
355 | +alternative_endif |
356 | + add \dst, \dst, \tmp |
357 | + .endm |
358 | + |
359 | + /* |
360 | + * @dst: Result of READ_ONCE(per_cpu(sym, smp_processor_id())) |
361 | + * @sym: The name of the per-cpu variable |
362 | + * @tmp: scratch register |
363 | + */ |
364 | + .macro ldr_this_cpu dst, sym, tmp |
365 | + adr_l \dst, \sym |
366 | +alternative_if_not ARM64_HAS_VIRT_HOST_EXTN |
367 | + mrs \tmp, tpidr_el1 |
368 | +alternative_else |
369 | + mrs \tmp, tpidr_el2 |
370 | +alternative_endif |
371 | + ldr \dst, [\dst, \tmp] |
372 | .endm |
373 | |
374 | /* |
375 | diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h |
376 | index ce67bf6a0886..7010779a1429 100644 |
377 | --- a/arch/arm64/include/asm/cpucaps.h |
378 | +++ b/arch/arm64/include/asm/cpucaps.h |
379 | @@ -36,7 +36,8 @@ |
380 | #define ARM64_MISMATCHED_CACHE_LINE_SIZE 15 |
381 | #define ARM64_UNMAP_KERNEL_AT_EL0 16 |
382 | #define ARM64_HARDEN_BRANCH_PREDICTOR 17 |
383 | +#define ARM64_SSBD 18 |
384 | |
385 | -#define ARM64_NCAPS 18 |
386 | +#define ARM64_NCAPS 19 |
387 | |
388 | #endif /* __ASM_CPUCAPS_H */ |
389 | diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h |
390 | index 4ea85ebdf4df..15868eca58de 100644 |
391 | --- a/arch/arm64/include/asm/cpufeature.h |
392 | +++ b/arch/arm64/include/asm/cpufeature.h |
393 | @@ -221,6 +221,28 @@ static inline bool system_supports_mixed_endian_el0(void) |
394 | return id_aa64mmfr0_mixed_endian_el0(read_system_reg(SYS_ID_AA64MMFR0_EL1)); |
395 | } |
396 | |
397 | +#define ARM64_SSBD_UNKNOWN -1 |
398 | +#define ARM64_SSBD_FORCE_DISABLE 0 |
399 | +#define ARM64_SSBD_KERNEL 1 |
400 | +#define ARM64_SSBD_FORCE_ENABLE 2 |
401 | +#define ARM64_SSBD_MITIGATED 3 |
402 | + |
403 | +static inline int arm64_get_ssbd_state(void) |
404 | +{ |
405 | +#ifdef CONFIG_ARM64_SSBD |
406 | + extern int ssbd_state; |
407 | + return ssbd_state; |
408 | +#else |
409 | + return ARM64_SSBD_UNKNOWN; |
410 | +#endif |
411 | +} |
412 | + |
413 | +#ifdef CONFIG_ARM64_SSBD |
414 | +void arm64_set_ssbd_mitigation(bool state); |
415 | +#else |
416 | +static inline void arm64_set_ssbd_mitigation(bool state) {} |
417 | +#endif |
418 | + |
419 | #endif /* __ASSEMBLY__ */ |
420 | |
421 | #endif |
422 | diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h |
423 | index ec3553eb9349..8f5cf83b2339 100644 |
424 | --- a/arch/arm64/include/asm/kvm_asm.h |
425 | +++ b/arch/arm64/include/asm/kvm_asm.h |
426 | @@ -33,6 +33,10 @@ |
427 | #define KVM_ARM64_DEBUG_DIRTY_SHIFT 0 |
428 | #define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT) |
429 | |
430 | +#define VCPU_WORKAROUND_2_FLAG_SHIFT 0 |
431 | +#define VCPU_WORKAROUND_2_FLAG (_AC(1, UL) << VCPU_WORKAROUND_2_FLAG_SHIFT) |
432 | + |
433 | +/* Translate a kernel address of @sym into its equivalent linear mapping */ |
434 | #define kvm_ksym_ref(sym) \ |
435 | ({ \ |
436 | void *val = &sym; \ |
437 | @@ -65,6 +69,43 @@ extern u32 __kvm_get_mdcr_el2(void); |
438 | |
439 | extern u32 __init_stage2_translation(void); |
440 | |
441 | +/* Home-grown __this_cpu_{ptr,read} variants that always work at HYP */ |
442 | +#define __hyp_this_cpu_ptr(sym) \ |
443 | + ({ \ |
444 | + void *__ptr = hyp_symbol_addr(sym); \ |
445 | + __ptr += read_sysreg(tpidr_el2); \ |
446 | + (typeof(&sym))__ptr; \ |
447 | + }) |
448 | + |
449 | +#define __hyp_this_cpu_read(sym) \ |
450 | + ({ \ |
451 | + *__hyp_this_cpu_ptr(sym); \ |
452 | + }) |
453 | + |
454 | +#else /* __ASSEMBLY__ */ |
455 | + |
456 | +.macro hyp_adr_this_cpu reg, sym, tmp |
457 | + adr_l \reg, \sym |
458 | + mrs \tmp, tpidr_el2 |
459 | + add \reg, \reg, \tmp |
460 | +.endm |
461 | + |
462 | +.macro hyp_ldr_this_cpu reg, sym, tmp |
463 | + adr_l \reg, \sym |
464 | + mrs \tmp, tpidr_el2 |
465 | + ldr \reg, [\reg, \tmp] |
466 | +.endm |
467 | + |
468 | +.macro get_host_ctxt reg, tmp |
469 | + hyp_adr_this_cpu \reg, kvm_host_cpu_state, \tmp |
470 | +.endm |
471 | + |
472 | +.macro get_vcpu_ptr vcpu, ctxt |
473 | + get_host_ctxt \ctxt, \vcpu |
474 | + ldr \vcpu, [\ctxt, #HOST_CONTEXT_VCPU] |
475 | + kern_hyp_va \vcpu |
476 | +.endm |
477 | + |
478 | #endif |
479 | |
480 | #endif /* __ARM_KVM_ASM_H__ */ |
481 | diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h |
482 | index 2abb4493f4f6..4cdfbd01b2de 100644 |
483 | --- a/arch/arm64/include/asm/kvm_host.h |
484 | +++ b/arch/arm64/include/asm/kvm_host.h |
485 | @@ -197,6 +197,8 @@ struct kvm_cpu_context { |
486 | u64 sys_regs[NR_SYS_REGS]; |
487 | u32 copro[NR_COPRO_REGS]; |
488 | }; |
489 | + |
490 | + struct kvm_vcpu *__hyp_running_vcpu; |
491 | }; |
492 | |
493 | typedef struct kvm_cpu_context kvm_cpu_context_t; |
494 | @@ -211,6 +213,9 @@ struct kvm_vcpu_arch { |
495 | /* Exception Information */ |
496 | struct kvm_vcpu_fault_info fault; |
497 | |
498 | + /* State of various workarounds, see kvm_asm.h for bit assignment */ |
499 | + u64 workaround_flags; |
500 | + |
501 | /* Guest debug state */ |
502 | u64 debug_flags; |
503 | |
504 | @@ -354,10 +359,15 @@ int kvm_perf_teardown(void); |
505 | |
506 | struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr); |
507 | |
508 | +void __kvm_set_tpidr_el2(u64 tpidr_el2); |
509 | +DECLARE_PER_CPU(kvm_cpu_context_t, kvm_host_cpu_state); |
510 | + |
511 | static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr, |
512 | unsigned long hyp_stack_ptr, |
513 | unsigned long vector_ptr) |
514 | { |
515 | + u64 tpidr_el2; |
516 | + |
517 | /* |
518 | * Call initialization code, and switch to the full blown HYP code. |
519 | * If the cpucaps haven't been finalized yet, something has gone very |
520 | @@ -366,6 +376,16 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr, |
521 | */ |
522 | BUG_ON(!static_branch_likely(&arm64_const_caps_ready)); |
523 | __kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr); |
524 | + |
525 | + /* |
526 | + * Calculate the raw per-cpu offset without a translation from the |
527 | + * kernel's mapping to the linear mapping, and store it in tpidr_el2 |
528 | + * so that we can use adr_l to access per-cpu variables in EL2. |
529 | + */ |
530 | + tpidr_el2 = (u64)this_cpu_ptr(&kvm_host_cpu_state) |
531 | + - (u64)kvm_ksym_ref(kvm_host_cpu_state); |
532 | + |
533 | + kvm_call_hyp(__kvm_set_tpidr_el2, tpidr_el2); |
534 | } |
535 | |
536 | void __kvm_hyp_teardown(void); |
537 | @@ -405,4 +425,27 @@ static inline bool kvm_arm_harden_branch_predictor(void) |
538 | return cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR); |
539 | } |
540 | |
541 | +#define KVM_SSBD_UNKNOWN -1 |
542 | +#define KVM_SSBD_FORCE_DISABLE 0 |
543 | +#define KVM_SSBD_KERNEL 1 |
544 | +#define KVM_SSBD_FORCE_ENABLE 2 |
545 | +#define KVM_SSBD_MITIGATED 3 |
546 | + |
547 | +static inline int kvm_arm_have_ssbd(void) |
548 | +{ |
549 | + switch (arm64_get_ssbd_state()) { |
550 | + case ARM64_SSBD_FORCE_DISABLE: |
551 | + return KVM_SSBD_FORCE_DISABLE; |
552 | + case ARM64_SSBD_KERNEL: |
553 | + return KVM_SSBD_KERNEL; |
554 | + case ARM64_SSBD_FORCE_ENABLE: |
555 | + return KVM_SSBD_FORCE_ENABLE; |
556 | + case ARM64_SSBD_MITIGATED: |
557 | + return KVM_SSBD_MITIGATED; |
558 | + case ARM64_SSBD_UNKNOWN: |
559 | + default: |
560 | + return KVM_SSBD_UNKNOWN; |
561 | + } |
562 | +} |
563 | + |
564 | #endif /* __ARM64_KVM_HOST_H__ */ |
565 | diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h |
566 | index 824c83db9b47..547519abc751 100644 |
567 | --- a/arch/arm64/include/asm/kvm_mmu.h |
568 | +++ b/arch/arm64/include/asm/kvm_mmu.h |
569 | @@ -130,6 +130,26 @@ static inline unsigned long __kern_hyp_va(unsigned long v) |
570 | |
571 | #define kern_hyp_va(v) ((typeof(v))(__kern_hyp_va((unsigned long)(v)))) |
572 | |
573 | +/* |
574 | + * Obtain the PC-relative address of a kernel symbol |
575 | + * s: symbol |
576 | + * |
577 | + * The goal of this macro is to return a symbol's address based on a |
578 | + * PC-relative computation, as opposed to a loading the VA from a |
579 | + * constant pool or something similar. This works well for HYP, as an |
580 | + * absolute VA is guaranteed to be wrong. Only use this if trying to |
581 | + * obtain the address of a symbol (i.e. not something you obtained by |
582 | + * following a pointer). |
583 | + */ |
584 | +#define hyp_symbol_addr(s) \ |
585 | + ({ \ |
586 | + typeof(s) *addr; \ |
587 | + asm("adrp %0, %1\n" \ |
588 | + "add %0, %0, :lo12:%1\n" \ |
589 | + : "=r" (addr) : "S" (&s)); \ |
590 | + addr; \ |
591 | + }) |
592 | + |
593 | /* |
594 | * We currently only support a 40bit IPA. |
595 | */ |
596 | @@ -367,5 +387,29 @@ static inline int kvm_map_vectors(void) |
597 | } |
598 | #endif |
599 | |
600 | +#ifdef CONFIG_ARM64_SSBD |
601 | +DECLARE_PER_CPU_READ_MOSTLY(u64, arm64_ssbd_callback_required); |
602 | + |
603 | +static inline int hyp_map_aux_data(void) |
604 | +{ |
605 | + int cpu, err; |
606 | + |
607 | + for_each_possible_cpu(cpu) { |
608 | + u64 *ptr; |
609 | + |
610 | + ptr = per_cpu_ptr(&arm64_ssbd_callback_required, cpu); |
611 | + err = create_hyp_mappings(ptr, ptr + 1, PAGE_HYP); |
612 | + if (err) |
613 | + return err; |
614 | + } |
615 | + return 0; |
616 | +} |
617 | +#else |
618 | +static inline int hyp_map_aux_data(void) |
619 | +{ |
620 | + return 0; |
621 | +} |
622 | +#endif |
623 | + |
624 | #endif /* __ASSEMBLY__ */ |
625 | #endif /* __ARM64_KVM_MMU_H__ */ |
626 | diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h |
627 | index 5394c8405e66..0d551576eb57 100644 |
628 | --- a/arch/arm64/include/asm/percpu.h |
629 | +++ b/arch/arm64/include/asm/percpu.h |
630 | @@ -16,9 +16,14 @@ |
631 | #ifndef __ASM_PERCPU_H |
632 | #define __ASM_PERCPU_H |
633 | |
634 | +#include <asm/alternative.h> |
635 | + |
636 | static inline void set_my_cpu_offset(unsigned long off) |
637 | { |
638 | - asm volatile("msr tpidr_el1, %0" :: "r" (off) : "memory"); |
639 | + asm volatile(ALTERNATIVE("msr tpidr_el1, %0", |
640 | + "msr tpidr_el2, %0", |
641 | + ARM64_HAS_VIRT_HOST_EXTN) |
642 | + :: "r" (off) : "memory"); |
643 | } |
644 | |
645 | static inline unsigned long __my_cpu_offset(void) |
646 | @@ -29,7 +34,10 @@ static inline unsigned long __my_cpu_offset(void) |
647 | * We want to allow caching the value, so avoid using volatile and |
648 | * instead use a fake stack read to hazard against barrier(). |
649 | */ |
650 | - asm("mrs %0, tpidr_el1" : "=r" (off) : |
651 | + asm(ALTERNATIVE("mrs %0, tpidr_el1", |
652 | + "mrs %0, tpidr_el2", |
653 | + ARM64_HAS_VIRT_HOST_EXTN) |
654 | + : "=r" (off) : |
655 | "Q" (*(const unsigned long *)current_stack_pointer)); |
656 | |
657 | return off; |
658 | diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h |
659 | index e9ea5a6bd449..0dd1bc13f942 100644 |
660 | --- a/arch/arm64/include/asm/thread_info.h |
661 | +++ b/arch/arm64/include/asm/thread_info.h |
662 | @@ -122,6 +122,7 @@ static inline struct thread_info *current_thread_info(void) |
663 | #define TIF_RESTORE_SIGMASK 20 |
664 | #define TIF_SINGLESTEP 21 |
665 | #define TIF_32BIT 22 /* 32bit process */ |
666 | +#define TIF_SSBD 23 /* Wants SSB mitigation */ |
667 | |
668 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) |
669 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) |
670 | diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile |
671 | index 74b8fd860714..6dadaaee796d 100644 |
672 | --- a/arch/arm64/kernel/Makefile |
673 | +++ b/arch/arm64/kernel/Makefile |
674 | @@ -50,6 +50,7 @@ arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o |
675 | arm64-obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o |
676 | arm64-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o \ |
677 | cpu-reset.o |
678 | +arm64-obj-$(CONFIG_ARM64_SSBD) += ssbd.o |
679 | |
680 | ifeq ($(CONFIG_KVM),y) |
681 | arm64-obj-$(CONFIG_HARDEN_BRANCH_PREDICTOR) += bpi.o |
682 | diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c |
683 | index 06d650f61da7..091748095140 100644 |
684 | --- a/arch/arm64/kernel/alternative.c |
685 | +++ b/arch/arm64/kernel/alternative.c |
686 | @@ -28,10 +28,12 @@ |
687 | #include <asm/sections.h> |
688 | #include <linux/stop_machine.h> |
689 | |
690 | -#define __ALT_PTR(a,f) (u32 *)((void *)&(a)->f + (a)->f) |
691 | +#define __ALT_PTR(a,f) ((void *)&(a)->f + (a)->f) |
692 | #define ALT_ORIG_PTR(a) __ALT_PTR(a, orig_offset) |
693 | #define ALT_REPL_PTR(a) __ALT_PTR(a, alt_offset) |
694 | |
695 | +int alternatives_applied; |
696 | + |
697 | struct alt_region { |
698 | struct alt_instr *begin; |
699 | struct alt_instr *end; |
700 | @@ -105,31 +107,52 @@ static u32 get_alt_insn(struct alt_instr *alt, u32 *insnptr, u32 *altinsnptr) |
701 | return insn; |
702 | } |
703 | |
704 | +static void patch_alternative(struct alt_instr *alt, |
705 | + __le32 *origptr, __le32 *updptr, int nr_inst) |
706 | +{ |
707 | + __le32 *replptr; |
708 | + int i; |
709 | + |
710 | + replptr = ALT_REPL_PTR(alt); |
711 | + for (i = 0; i < nr_inst; i++) { |
712 | + u32 insn; |
713 | + |
714 | + insn = get_alt_insn(alt, origptr + i, replptr + i); |
715 | + updptr[i] = cpu_to_le32(insn); |
716 | + } |
717 | +} |
718 | + |
719 | static void __apply_alternatives(void *alt_region) |
720 | { |
721 | struct alt_instr *alt; |
722 | struct alt_region *region = alt_region; |
723 | - u32 *origptr, *replptr; |
724 | + __le32 *origptr; |
725 | + alternative_cb_t alt_cb; |
726 | |
727 | for (alt = region->begin; alt < region->end; alt++) { |
728 | - u32 insn; |
729 | - int i, nr_inst; |
730 | + int nr_inst; |
731 | |
732 | - if (!cpus_have_cap(alt->cpufeature)) |
733 | + /* Use ARM64_CB_PATCH as an unconditional patch */ |
734 | + if (alt->cpufeature < ARM64_CB_PATCH && |
735 | + !cpus_have_cap(alt->cpufeature)) |
736 | continue; |
737 | |
738 | - BUG_ON(alt->alt_len != alt->orig_len); |
739 | + if (alt->cpufeature == ARM64_CB_PATCH) |
740 | + BUG_ON(alt->alt_len != 0); |
741 | + else |
742 | + BUG_ON(alt->alt_len != alt->orig_len); |
743 | |
744 | pr_info_once("patching kernel code\n"); |
745 | |
746 | origptr = ALT_ORIG_PTR(alt); |
747 | - replptr = ALT_REPL_PTR(alt); |
748 | - nr_inst = alt->alt_len / sizeof(insn); |
749 | + nr_inst = alt->orig_len / AARCH64_INSN_SIZE; |
750 | |
751 | - for (i = 0; i < nr_inst; i++) { |
752 | - insn = get_alt_insn(alt, origptr + i, replptr + i); |
753 | - *(origptr + i) = cpu_to_le32(insn); |
754 | - } |
755 | + if (alt->cpufeature < ARM64_CB_PATCH) |
756 | + alt_cb = patch_alternative; |
757 | + else |
758 | + alt_cb = ALT_REPL_PTR(alt); |
759 | + |
760 | + alt_cb(alt, origptr, origptr, nr_inst); |
761 | |
762 | flush_icache_range((uintptr_t)origptr, |
763 | (uintptr_t)(origptr + nr_inst)); |
764 | @@ -142,7 +165,6 @@ static void __apply_alternatives(void *alt_region) |
765 | */ |
766 | static int __apply_alternatives_multi_stop(void *unused) |
767 | { |
768 | - static int patched = 0; |
769 | struct alt_region region = { |
770 | .begin = (struct alt_instr *)__alt_instructions, |
771 | .end = (struct alt_instr *)__alt_instructions_end, |
772 | @@ -150,14 +172,14 @@ static int __apply_alternatives_multi_stop(void *unused) |
773 | |
774 | /* We always have a CPU 0 at this point (__init) */ |
775 | if (smp_processor_id()) { |
776 | - while (!READ_ONCE(patched)) |
777 | + while (!READ_ONCE(alternatives_applied)) |
778 | cpu_relax(); |
779 | isb(); |
780 | } else { |
781 | - BUG_ON(patched); |
782 | + BUG_ON(alternatives_applied); |
783 | __apply_alternatives(®ion); |
784 | /* Barriers provided by the cache flushing */ |
785 | - WRITE_ONCE(patched, 1); |
786 | + WRITE_ONCE(alternatives_applied, 1); |
787 | } |
788 | |
789 | return 0; |
790 | diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c |
791 | index 5f4bf3c6f016..bd239b1b7a68 100644 |
792 | --- a/arch/arm64/kernel/asm-offsets.c |
793 | +++ b/arch/arm64/kernel/asm-offsets.c |
794 | @@ -127,11 +127,13 @@ int main(void) |
795 | BLANK(); |
796 | #ifdef CONFIG_KVM_ARM_HOST |
797 | DEFINE(VCPU_CONTEXT, offsetof(struct kvm_vcpu, arch.ctxt)); |
798 | + DEFINE(VCPU_WORKAROUND_FLAGS, offsetof(struct kvm_vcpu, arch.workaround_flags)); |
799 | DEFINE(CPU_GP_REGS, offsetof(struct kvm_cpu_context, gp_regs)); |
800 | DEFINE(CPU_USER_PT_REGS, offsetof(struct kvm_regs, regs)); |
801 | DEFINE(CPU_FP_REGS, offsetof(struct kvm_regs, fp_regs)); |
802 | DEFINE(VCPU_FPEXC32_EL2, offsetof(struct kvm_vcpu, arch.ctxt.sys_regs[FPEXC32_EL2])); |
803 | DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context)); |
804 | + DEFINE(HOST_CONTEXT_VCPU, offsetof(struct kvm_cpu_context, __hyp_running_vcpu)); |
805 | #endif |
806 | #ifdef CONFIG_CPU_PM |
807 | DEFINE(CPU_SUSPEND_SZ, sizeof(struct cpu_suspend_ctx)); |
808 | diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c |
809 | index 2de62aa91303..1db97ad7b58b 100644 |
810 | --- a/arch/arm64/kernel/cpu_errata.c |
811 | +++ b/arch/arm64/kernel/cpu_errata.c |
812 | @@ -187,6 +187,178 @@ static int enable_smccc_arch_workaround_1(void *data) |
813 | } |
814 | #endif /* CONFIG_HARDEN_BRANCH_PREDICTOR */ |
815 | |
816 | +#ifdef CONFIG_ARM64_SSBD |
817 | +DEFINE_PER_CPU_READ_MOSTLY(u64, arm64_ssbd_callback_required); |
818 | + |
819 | +int ssbd_state __read_mostly = ARM64_SSBD_KERNEL; |
820 | + |
821 | +static const struct ssbd_options { |
822 | + const char *str; |
823 | + int state; |
824 | +} ssbd_options[] = { |
825 | + { "force-on", ARM64_SSBD_FORCE_ENABLE, }, |
826 | + { "force-off", ARM64_SSBD_FORCE_DISABLE, }, |
827 | + { "kernel", ARM64_SSBD_KERNEL, }, |
828 | +}; |
829 | + |
830 | +static int __init ssbd_cfg(char *buf) |
831 | +{ |
832 | + int i; |
833 | + |
834 | + if (!buf || !buf[0]) |
835 | + return -EINVAL; |
836 | + |
837 | + for (i = 0; i < ARRAY_SIZE(ssbd_options); i++) { |
838 | + int len = strlen(ssbd_options[i].str); |
839 | + |
840 | + if (strncmp(buf, ssbd_options[i].str, len)) |
841 | + continue; |
842 | + |
843 | + ssbd_state = ssbd_options[i].state; |
844 | + return 0; |
845 | + } |
846 | + |
847 | + return -EINVAL; |
848 | +} |
849 | +early_param("ssbd", ssbd_cfg); |
850 | + |
851 | +void __init arm64_update_smccc_conduit(struct alt_instr *alt, |
852 | + __le32 *origptr, __le32 *updptr, |
853 | + int nr_inst) |
854 | +{ |
855 | + u32 insn; |
856 | + |
857 | + BUG_ON(nr_inst != 1); |
858 | + |
859 | + switch (psci_ops.conduit) { |
860 | + case PSCI_CONDUIT_HVC: |
861 | + insn = aarch64_insn_get_hvc_value(); |
862 | + break; |
863 | + case PSCI_CONDUIT_SMC: |
864 | + insn = aarch64_insn_get_smc_value(); |
865 | + break; |
866 | + default: |
867 | + return; |
868 | + } |
869 | + |
870 | + *updptr = cpu_to_le32(insn); |
871 | +} |
872 | + |
873 | +void __init arm64_enable_wa2_handling(struct alt_instr *alt, |
874 | + __le32 *origptr, __le32 *updptr, |
875 | + int nr_inst) |
876 | +{ |
877 | + BUG_ON(nr_inst != 1); |
878 | + /* |
879 | + * Only allow mitigation on EL1 entry/exit and guest |
880 | + * ARCH_WORKAROUND_2 handling if the SSBD state allows it to |
881 | + * be flipped. |
882 | + */ |
883 | + if (arm64_get_ssbd_state() == ARM64_SSBD_KERNEL) |
884 | + *updptr = cpu_to_le32(aarch64_insn_gen_nop()); |
885 | +} |
886 | + |
887 | +void arm64_set_ssbd_mitigation(bool state) |
888 | +{ |
889 | + switch (psci_ops.conduit) { |
890 | + case PSCI_CONDUIT_HVC: |
891 | + arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL); |
892 | + break; |
893 | + |
894 | + case PSCI_CONDUIT_SMC: |
895 | + arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL); |
896 | + break; |
897 | + |
898 | + default: |
899 | + WARN_ON_ONCE(1); |
900 | + break; |
901 | + } |
902 | +} |
903 | + |
904 | +static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry, |
905 | + int scope) |
906 | +{ |
907 | + struct arm_smccc_res res; |
908 | + bool required = true; |
909 | + s32 val; |
910 | + |
911 | + WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); |
912 | + |
913 | + if (psci_ops.smccc_version == SMCCC_VERSION_1_0) { |
914 | + ssbd_state = ARM64_SSBD_UNKNOWN; |
915 | + return false; |
916 | + } |
917 | + |
918 | + switch (psci_ops.conduit) { |
919 | + case PSCI_CONDUIT_HVC: |
920 | + arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, |
921 | + ARM_SMCCC_ARCH_WORKAROUND_2, &res); |
922 | + break; |
923 | + |
924 | + case PSCI_CONDUIT_SMC: |
925 | + arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, |
926 | + ARM_SMCCC_ARCH_WORKAROUND_2, &res); |
927 | + break; |
928 | + |
929 | + default: |
930 | + ssbd_state = ARM64_SSBD_UNKNOWN; |
931 | + return false; |
932 | + } |
933 | + |
934 | + val = (s32)res.a0; |
935 | + |
936 | + switch (val) { |
937 | + case SMCCC_RET_NOT_SUPPORTED: |
938 | + ssbd_state = ARM64_SSBD_UNKNOWN; |
939 | + return false; |
940 | + |
941 | + case SMCCC_RET_NOT_REQUIRED: |
942 | + pr_info_once("%s mitigation not required\n", entry->desc); |
943 | + ssbd_state = ARM64_SSBD_MITIGATED; |
944 | + return false; |
945 | + |
946 | + case SMCCC_RET_SUCCESS: |
947 | + required = true; |
948 | + break; |
949 | + |
950 | + case 1: /* Mitigation not required on this CPU */ |
951 | + required = false; |
952 | + break; |
953 | + |
954 | + default: |
955 | + WARN_ON(1); |
956 | + return false; |
957 | + } |
958 | + |
959 | + switch (ssbd_state) { |
960 | + case ARM64_SSBD_FORCE_DISABLE: |
961 | + pr_info_once("%s disabled from command-line\n", entry->desc); |
962 | + arm64_set_ssbd_mitigation(false); |
963 | + required = false; |
964 | + break; |
965 | + |
966 | + case ARM64_SSBD_KERNEL: |
967 | + if (required) { |
968 | + __this_cpu_write(arm64_ssbd_callback_required, 1); |
969 | + arm64_set_ssbd_mitigation(true); |
970 | + } |
971 | + break; |
972 | + |
973 | + case ARM64_SSBD_FORCE_ENABLE: |
974 | + pr_info_once("%s forced from command-line\n", entry->desc); |
975 | + arm64_set_ssbd_mitigation(true); |
976 | + required = true; |
977 | + break; |
978 | + |
979 | + default: |
980 | + WARN_ON(1); |
981 | + break; |
982 | + } |
983 | + |
984 | + return required; |
985 | +} |
986 | +#endif /* CONFIG_ARM64_SSBD */ |
987 | + |
988 | #define MIDR_RANGE(model, min, max) \ |
989 | .def_scope = SCOPE_LOCAL_CPU, \ |
990 | .matches = is_affected_midr_range, \ |
991 | @@ -309,6 +481,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { |
992 | MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), |
993 | .enable = enable_smccc_arch_workaround_1, |
994 | }, |
995 | +#endif |
996 | +#ifdef CONFIG_ARM64_SSBD |
997 | + { |
998 | + .desc = "Speculative Store Bypass Disable", |
999 | + .def_scope = SCOPE_LOCAL_CPU, |
1000 | + .capability = ARM64_SSBD, |
1001 | + .matches = has_ssbd_mitigation, |
1002 | + }, |
1003 | #endif |
1004 | { |
1005 | } |
1006 | diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c |
1007 | index 625c2b240ffb..ab15747a49d4 100644 |
1008 | --- a/arch/arm64/kernel/cpufeature.c |
1009 | +++ b/arch/arm64/kernel/cpufeature.c |
1010 | @@ -829,6 +829,22 @@ static int __init parse_kpti(char *str) |
1011 | early_param("kpti", parse_kpti); |
1012 | #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */ |
1013 | |
1014 | +static int cpu_copy_el2regs(void *__unused) |
1015 | +{ |
1016 | + /* |
1017 | + * Copy register values that aren't redirected by hardware. |
1018 | + * |
1019 | + * Before code patching, we only set tpidr_el1, all CPUs need to copy |
1020 | + * this value to tpidr_el2 before we patch the code. Once we've done |
1021 | + * that, freshly-onlined CPUs will set tpidr_el2, so we don't need to |
1022 | + * do anything here. |
1023 | + */ |
1024 | + if (!alternatives_applied) |
1025 | + write_sysreg(read_sysreg(tpidr_el1), tpidr_el2); |
1026 | + |
1027 | + return 0; |
1028 | +} |
1029 | + |
1030 | static const struct arm64_cpu_capabilities arm64_features[] = { |
1031 | { |
1032 | .desc = "GIC system register CPU interface", |
1033 | @@ -895,6 +911,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { |
1034 | .capability = ARM64_HAS_VIRT_HOST_EXTN, |
1035 | .def_scope = SCOPE_SYSTEM, |
1036 | .matches = runs_at_el2, |
1037 | + .enable = cpu_copy_el2regs, |
1038 | }, |
1039 | { |
1040 | .desc = "32-bit EL0 Support", |
1041 | diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S |
1042 | index b79e302d2a3e..ca978d7d98eb 100644 |
1043 | --- a/arch/arm64/kernel/entry.S |
1044 | +++ b/arch/arm64/kernel/entry.S |
1045 | @@ -18,6 +18,7 @@ |
1046 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1047 | */ |
1048 | |
1049 | +#include <linux/arm-smccc.h> |
1050 | #include <linux/init.h> |
1051 | #include <linux/linkage.h> |
1052 | |
1053 | @@ -95,6 +96,25 @@ alternative_else_nop_endif |
1054 | add \dst, \dst, #(\sym - .entry.tramp.text) |
1055 | .endm |
1056 | |
1057 | + // This macro corrupts x0-x3. It is the caller's duty |
1058 | + // to save/restore them if required. |
1059 | + .macro apply_ssbd, state, targ, tmp1, tmp2 |
1060 | +#ifdef CONFIG_ARM64_SSBD |
1061 | +alternative_cb arm64_enable_wa2_handling |
1062 | + b \targ |
1063 | +alternative_cb_end |
1064 | + ldr_this_cpu \tmp2, arm64_ssbd_callback_required, \tmp1 |
1065 | + cbz \tmp2, \targ |
1066 | + ldr \tmp2, [tsk, #TI_FLAGS] |
1067 | + tbnz \tmp2, #TIF_SSBD, \targ |
1068 | + mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2 |
1069 | + mov w1, #\state |
1070 | +alternative_cb arm64_update_smccc_conduit |
1071 | + nop // Patched to SMC/HVC #0 |
1072 | +alternative_cb_end |
1073 | +#endif |
1074 | + .endm |
1075 | + |
1076 | .macro kernel_entry, el, regsize = 64 |
1077 | .if \regsize == 32 |
1078 | mov w0, w0 // zero upper 32 bits of x0 |
1079 | @@ -122,6 +142,14 @@ alternative_else_nop_endif |
1080 | ldr x19, [tsk, #TI_FLAGS] // since we can unmask debug |
1081 | disable_step_tsk x19, x20 // exceptions when scheduling. |
1082 | |
1083 | + apply_ssbd 1, 1f, x22, x23 |
1084 | + |
1085 | +#ifdef CONFIG_ARM64_SSBD |
1086 | + ldp x0, x1, [sp, #16 * 0] |
1087 | + ldp x2, x3, [sp, #16 * 1] |
1088 | +#endif |
1089 | +1: |
1090 | + |
1091 | mov x29, xzr // fp pointed to user-space |
1092 | .else |
1093 | add x21, sp, #S_FRAME_SIZE |
1094 | @@ -190,6 +218,8 @@ alternative_if ARM64_WORKAROUND_845719 |
1095 | alternative_else_nop_endif |
1096 | #endif |
1097 | 3: |
1098 | + apply_ssbd 0, 5f, x0, x1 |
1099 | +5: |
1100 | .endif |
1101 | msr elr_el1, x21 // set up the return data |
1102 | msr spsr_el1, x22 |
1103 | @@ -243,7 +273,7 @@ alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 |
1104 | cmp x25, tsk |
1105 | b.ne 9998f |
1106 | |
1107 | - this_cpu_ptr irq_stack, x25, x26 |
1108 | + adr_this_cpu x25, irq_stack, x26 |
1109 | mov x26, #IRQ_STACK_START_SP |
1110 | add x26, x25, x26 |
1111 | |
1112 | diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c |
1113 | index d55a7b09959b..f6e71c73cceb 100644 |
1114 | --- a/arch/arm64/kernel/hibernate.c |
1115 | +++ b/arch/arm64/kernel/hibernate.c |
1116 | @@ -308,6 +308,17 @@ int swsusp_arch_suspend(void) |
1117 | |
1118 | sleep_cpu = -EINVAL; |
1119 | __cpu_suspend_exit(); |
1120 | + |
1121 | + /* |
1122 | + * Just in case the boot kernel did turn the SSBD |
1123 | + * mitigation off behind our back, let's set the state |
1124 | + * to what we expect it to be. |
1125 | + */ |
1126 | + switch (arm64_get_ssbd_state()) { |
1127 | + case ARM64_SSBD_FORCE_ENABLE: |
1128 | + case ARM64_SSBD_KERNEL: |
1129 | + arm64_set_ssbd_mitigation(true); |
1130 | + } |
1131 | } |
1132 | |
1133 | local_dbg_restore(flags); |
1134 | diff --git a/arch/arm64/kernel/ssbd.c b/arch/arm64/kernel/ssbd.c |
1135 | new file mode 100644 |
1136 | index 000000000000..0560738c1d5c |
1137 | --- /dev/null |
1138 | +++ b/arch/arm64/kernel/ssbd.c |
1139 | @@ -0,0 +1,108 @@ |
1140 | +// SPDX-License-Identifier: GPL-2.0 |
1141 | +/* |
1142 | + * Copyright (C) 2018 ARM Ltd, All Rights Reserved. |
1143 | + */ |
1144 | + |
1145 | +#include <linux/errno.h> |
1146 | +#include <linux/prctl.h> |
1147 | +#include <linux/sched.h> |
1148 | +#include <linux/thread_info.h> |
1149 | + |
1150 | +#include <asm/cpufeature.h> |
1151 | + |
1152 | +/* |
1153 | + * prctl interface for SSBD |
1154 | + */ |
1155 | +static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl) |
1156 | +{ |
1157 | + int state = arm64_get_ssbd_state(); |
1158 | + |
1159 | + /* Unsupported */ |
1160 | + if (state == ARM64_SSBD_UNKNOWN) |
1161 | + return -EINVAL; |
1162 | + |
1163 | + /* Treat the unaffected/mitigated state separately */ |
1164 | + if (state == ARM64_SSBD_MITIGATED) { |
1165 | + switch (ctrl) { |
1166 | + case PR_SPEC_ENABLE: |
1167 | + return -EPERM; |
1168 | + case PR_SPEC_DISABLE: |
1169 | + case PR_SPEC_FORCE_DISABLE: |
1170 | + return 0; |
1171 | + } |
1172 | + } |
1173 | + |
1174 | + /* |
1175 | + * Things are a bit backward here: the arm64 internal API |
1176 | + * *enables the mitigation* when the userspace API *disables |
1177 | + * speculation*. So much fun. |
1178 | + */ |
1179 | + switch (ctrl) { |
1180 | + case PR_SPEC_ENABLE: |
1181 | + /* If speculation is force disabled, enable is not allowed */ |
1182 | + if (state == ARM64_SSBD_FORCE_ENABLE || |
1183 | + task_spec_ssb_force_disable(task)) |
1184 | + return -EPERM; |
1185 | + task_clear_spec_ssb_disable(task); |
1186 | + clear_tsk_thread_flag(task, TIF_SSBD); |
1187 | + break; |
1188 | + case PR_SPEC_DISABLE: |
1189 | + if (state == ARM64_SSBD_FORCE_DISABLE) |
1190 | + return -EPERM; |
1191 | + task_set_spec_ssb_disable(task); |
1192 | + set_tsk_thread_flag(task, TIF_SSBD); |
1193 | + break; |
1194 | + case PR_SPEC_FORCE_DISABLE: |
1195 | + if (state == ARM64_SSBD_FORCE_DISABLE) |
1196 | + return -EPERM; |
1197 | + task_set_spec_ssb_disable(task); |
1198 | + task_set_spec_ssb_force_disable(task); |
1199 | + set_tsk_thread_flag(task, TIF_SSBD); |
1200 | + break; |
1201 | + default: |
1202 | + return -ERANGE; |
1203 | + } |
1204 | + |
1205 | + return 0; |
1206 | +} |
1207 | + |
1208 | +int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which, |
1209 | + unsigned long ctrl) |
1210 | +{ |
1211 | + switch (which) { |
1212 | + case PR_SPEC_STORE_BYPASS: |
1213 | + return ssbd_prctl_set(task, ctrl); |
1214 | + default: |
1215 | + return -ENODEV; |
1216 | + } |
1217 | +} |
1218 | + |
1219 | +static int ssbd_prctl_get(struct task_struct *task) |
1220 | +{ |
1221 | + switch (arm64_get_ssbd_state()) { |
1222 | + case ARM64_SSBD_UNKNOWN: |
1223 | + return -EINVAL; |
1224 | + case ARM64_SSBD_FORCE_ENABLE: |
1225 | + return PR_SPEC_DISABLE; |
1226 | + case ARM64_SSBD_KERNEL: |
1227 | + if (task_spec_ssb_force_disable(task)) |
1228 | + return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; |
1229 | + if (task_spec_ssb_disable(task)) |
1230 | + return PR_SPEC_PRCTL | PR_SPEC_DISABLE; |
1231 | + return PR_SPEC_PRCTL | PR_SPEC_ENABLE; |
1232 | + case ARM64_SSBD_FORCE_DISABLE: |
1233 | + return PR_SPEC_ENABLE; |
1234 | + default: |
1235 | + return PR_SPEC_NOT_AFFECTED; |
1236 | + } |
1237 | +} |
1238 | + |
1239 | +int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) |
1240 | +{ |
1241 | + switch (which) { |
1242 | + case PR_SPEC_STORE_BYPASS: |
1243 | + return ssbd_prctl_get(task); |
1244 | + default: |
1245 | + return -ENODEV; |
1246 | + } |
1247 | +} |
1248 | diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c |
1249 | index bb0cd787a9d3..1dbf6099e2a5 100644 |
1250 | --- a/arch/arm64/kernel/suspend.c |
1251 | +++ b/arch/arm64/kernel/suspend.c |
1252 | @@ -67,6 +67,14 @@ void notrace __cpu_suspend_exit(void) |
1253 | */ |
1254 | if (hw_breakpoint_restore) |
1255 | hw_breakpoint_restore(cpu); |
1256 | + |
1257 | + /* |
1258 | + * On resume, firmware implementing dynamic mitigation will |
1259 | + * have turned the mitigation on. If the user has forcefully |
1260 | + * disabled it, make sure their wishes are obeyed. |
1261 | + */ |
1262 | + if (arm64_get_ssbd_state() == ARM64_SSBD_FORCE_DISABLE) |
1263 | + arm64_set_ssbd_mitigation(false); |
1264 | } |
1265 | |
1266 | /* |
1267 | diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S |
1268 | index 4bbff904169d..db5efaf2a985 100644 |
1269 | --- a/arch/arm64/kvm/hyp-init.S |
1270 | +++ b/arch/arm64/kvm/hyp-init.S |
1271 | @@ -118,6 +118,10 @@ CPU_BE( orr x4, x4, #SCTLR_ELx_EE) |
1272 | kern_hyp_va x2 |
1273 | msr vbar_el2, x2 |
1274 | |
1275 | + /* copy tpidr_el1 into tpidr_el2 for use by HYP */ |
1276 | + mrs x1, tpidr_el1 |
1277 | + msr tpidr_el2, x1 |
1278 | + |
1279 | /* Hello, World! */ |
1280 | eret |
1281 | ENDPROC(__kvm_hyp_init) |
1282 | diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S |
1283 | index 12ee62d6d410..a360ac6e89e9 100644 |
1284 | --- a/arch/arm64/kvm/hyp/entry.S |
1285 | +++ b/arch/arm64/kvm/hyp/entry.S |
1286 | @@ -62,9 +62,6 @@ ENTRY(__guest_enter) |
1287 | // Store the host regs |
1288 | save_callee_saved_regs x1 |
1289 | |
1290 | - // Store the host_ctxt for use at exit time |
1291 | - str x1, [sp, #-16]! |
1292 | - |
1293 | add x18, x0, #VCPU_CONTEXT |
1294 | |
1295 | // Restore guest regs x0-x17 |
1296 | @@ -118,8 +115,7 @@ ENTRY(__guest_exit) |
1297 | // Store the guest regs x19-x29, lr |
1298 | save_callee_saved_regs x1 |
1299 | |
1300 | - // Restore the host_ctxt from the stack |
1301 | - ldr x2, [sp], #16 |
1302 | + get_host_ctxt x2, x3 |
1303 | |
1304 | // Now restore the host regs |
1305 | restore_callee_saved_regs x2 |
1306 | @@ -159,6 +155,10 @@ abort_guest_exit_end: |
1307 | ENDPROC(__guest_exit) |
1308 | |
1309 | ENTRY(__fpsimd_guest_restore) |
1310 | + // x0: esr |
1311 | + // x1: vcpu |
1312 | + // x2-x29,lr: vcpu regs |
1313 | + // vcpu x0-x1 on the stack |
1314 | stp x2, x3, [sp, #-16]! |
1315 | stp x4, lr, [sp, #-16]! |
1316 | |
1317 | @@ -173,7 +173,7 @@ alternative_else |
1318 | alternative_endif |
1319 | isb |
1320 | |
1321 | - mrs x3, tpidr_el2 |
1322 | + mov x3, x1 |
1323 | |
1324 | ldr x0, [x3, #VCPU_HOST_CONTEXT] |
1325 | kern_hyp_va x0 |
1326 | diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S |
1327 | index 4e9d50c3e658..bf4988f9dae8 100644 |
1328 | --- a/arch/arm64/kvm/hyp/hyp-entry.S |
1329 | +++ b/arch/arm64/kvm/hyp/hyp-entry.S |
1330 | @@ -72,13 +72,8 @@ ENDPROC(__kvm_hyp_teardown) |
1331 | el1_sync: // Guest trapped into EL2 |
1332 | stp x0, x1, [sp, #-16]! |
1333 | |
1334 | -alternative_if_not ARM64_HAS_VIRT_HOST_EXTN |
1335 | - mrs x1, esr_el2 |
1336 | -alternative_else |
1337 | - mrs x1, esr_el1 |
1338 | -alternative_endif |
1339 | - lsr x0, x1, #ESR_ELx_EC_SHIFT |
1340 | - |
1341 | + mrs x0, esr_el2 |
1342 | + lsr x0, x0, #ESR_ELx_EC_SHIFT |
1343 | cmp x0, #ESR_ELx_EC_HVC64 |
1344 | ccmp x0, #ESR_ELx_EC_HVC32, #4, ne |
1345 | b.ne el1_trap |
1346 | @@ -112,33 +107,73 @@ el1_hvc_guest: |
1347 | */ |
1348 | ldr x1, [sp] // Guest's x0 |
1349 | eor w1, w1, #ARM_SMCCC_ARCH_WORKAROUND_1 |
1350 | + cbz w1, wa_epilogue |
1351 | + |
1352 | + /* ARM_SMCCC_ARCH_WORKAROUND_2 handling */ |
1353 | + eor w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_1 ^ \ |
1354 | + ARM_SMCCC_ARCH_WORKAROUND_2) |
1355 | cbnz w1, el1_trap |
1356 | - mov x0, x1 |
1357 | + |
1358 | +#ifdef CONFIG_ARM64_SSBD |
1359 | +alternative_cb arm64_enable_wa2_handling |
1360 | + b wa2_end |
1361 | +alternative_cb_end |
1362 | + get_vcpu_ptr x2, x0 |
1363 | + ldr x0, [x2, #VCPU_WORKAROUND_FLAGS] |
1364 | + |
1365 | + // Sanitize the argument and update the guest flags |
1366 | + ldr x1, [sp, #8] // Guest's x1 |
1367 | + clz w1, w1 // Murphy's device: |
1368 | + lsr w1, w1, #5 // w1 = !!w1 without using |
1369 | + eor w1, w1, #1 // the flags... |
1370 | + bfi x0, x1, #VCPU_WORKAROUND_2_FLAG_SHIFT, #1 |
1371 | + str x0, [x2, #VCPU_WORKAROUND_FLAGS] |
1372 | + |
1373 | + /* Check that we actually need to perform the call */ |
1374 | + hyp_ldr_this_cpu x0, arm64_ssbd_callback_required, x2 |
1375 | + cbz x0, wa2_end |
1376 | + |
1377 | + mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2 |
1378 | + smc #0 |
1379 | + |
1380 | + /* Don't leak data from the SMC call */ |
1381 | + mov x3, xzr |
1382 | +wa2_end: |
1383 | + mov x2, xzr |
1384 | + mov x1, xzr |
1385 | +#endif |
1386 | + |
1387 | +wa_epilogue: |
1388 | + mov x0, xzr |
1389 | add sp, sp, #16 |
1390 | eret |
1391 | |
1392 | el1_trap: |
1393 | + get_vcpu_ptr x1, x0 |
1394 | + |
1395 | + mrs x0, esr_el2 |
1396 | + lsr x0, x0, #ESR_ELx_EC_SHIFT |
1397 | /* |
1398 | * x0: ESR_EC |
1399 | + * x1: vcpu pointer |
1400 | */ |
1401 | |
1402 | /* Guest accessed VFP/SIMD registers, save host, restore Guest */ |
1403 | cmp x0, #ESR_ELx_EC_FP_ASIMD |
1404 | b.eq __fpsimd_guest_restore |
1405 | |
1406 | - mrs x1, tpidr_el2 |
1407 | mov x0, #ARM_EXCEPTION_TRAP |
1408 | b __guest_exit |
1409 | |
1410 | el1_irq: |
1411 | stp x0, x1, [sp, #-16]! |
1412 | - mrs x1, tpidr_el2 |
1413 | + get_vcpu_ptr x1, x0 |
1414 | mov x0, #ARM_EXCEPTION_IRQ |
1415 | b __guest_exit |
1416 | |
1417 | el1_error: |
1418 | stp x0, x1, [sp, #-16]! |
1419 | - mrs x1, tpidr_el2 |
1420 | + get_vcpu_ptr x1, x0 |
1421 | mov x0, #ARM_EXCEPTION_EL1_SERROR |
1422 | b __guest_exit |
1423 | |
1424 | @@ -173,6 +208,11 @@ ENTRY(__hyp_do_panic) |
1425 | eret |
1426 | ENDPROC(__hyp_do_panic) |
1427 | |
1428 | +ENTRY(__hyp_panic) |
1429 | + get_host_ctxt x0, x1 |
1430 | + b hyp_panic |
1431 | +ENDPROC(__hyp_panic) |
1432 | + |
1433 | .macro invalid_vector label, target = __hyp_panic |
1434 | .align 2 |
1435 | \label: |
1436 | diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c |
1437 | index c49d09387192..12f9d1ecdf4c 100644 |
1438 | --- a/arch/arm64/kvm/hyp/switch.c |
1439 | +++ b/arch/arm64/kvm/hyp/switch.c |
1440 | @@ -15,6 +15,7 @@ |
1441 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1442 | */ |
1443 | |
1444 | +#include <linux/arm-smccc.h> |
1445 | #include <linux/types.h> |
1446 | #include <linux/jump_label.h> |
1447 | #include <uapi/linux/psci.h> |
1448 | @@ -267,6 +268,39 @@ static void __hyp_text __skip_instr(struct kvm_vcpu *vcpu) |
1449 | write_sysreg_el2(*vcpu_pc(vcpu), elr); |
1450 | } |
1451 | |
1452 | +static inline bool __hyp_text __needs_ssbd_off(struct kvm_vcpu *vcpu) |
1453 | +{ |
1454 | + if (!cpus_have_cap(ARM64_SSBD)) |
1455 | + return false; |
1456 | + |
1457 | + return !(vcpu->arch.workaround_flags & VCPU_WORKAROUND_2_FLAG); |
1458 | +} |
1459 | + |
1460 | +static void __hyp_text __set_guest_arch_workaround_state(struct kvm_vcpu *vcpu) |
1461 | +{ |
1462 | +#ifdef CONFIG_ARM64_SSBD |
1463 | + /* |
1464 | + * The host runs with the workaround always present. If the |
1465 | + * guest wants it disabled, so be it... |
1466 | + */ |
1467 | + if (__needs_ssbd_off(vcpu) && |
1468 | + __hyp_this_cpu_read(arm64_ssbd_callback_required)) |
1469 | + arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, 0, NULL); |
1470 | +#endif |
1471 | +} |
1472 | + |
1473 | +static void __hyp_text __set_host_arch_workaround_state(struct kvm_vcpu *vcpu) |
1474 | +{ |
1475 | +#ifdef CONFIG_ARM64_SSBD |
1476 | + /* |
1477 | + * If the guest has disabled the workaround, bring it back on. |
1478 | + */ |
1479 | + if (__needs_ssbd_off(vcpu) && |
1480 | + __hyp_this_cpu_read(arm64_ssbd_callback_required)) |
1481 | + arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, 1, NULL); |
1482 | +#endif |
1483 | +} |
1484 | + |
1485 | int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) |
1486 | { |
1487 | struct kvm_cpu_context *host_ctxt; |
1488 | @@ -275,9 +309,9 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) |
1489 | u64 exit_code; |
1490 | |
1491 | vcpu = kern_hyp_va(vcpu); |
1492 | - write_sysreg(vcpu, tpidr_el2); |
1493 | |
1494 | host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context); |
1495 | + host_ctxt->__hyp_running_vcpu = vcpu; |
1496 | guest_ctxt = &vcpu->arch.ctxt; |
1497 | |
1498 | __sysreg_save_host_state(host_ctxt); |
1499 | @@ -297,6 +331,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) |
1500 | __sysreg_restore_guest_state(guest_ctxt); |
1501 | __debug_restore_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt); |
1502 | |
1503 | + __set_guest_arch_workaround_state(vcpu); |
1504 | + |
1505 | /* Jump in the fire! */ |
1506 | again: |
1507 | exit_code = __guest_enter(vcpu, host_ctxt); |
1508 | @@ -339,6 +375,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) |
1509 | } |
1510 | } |
1511 | |
1512 | + __set_host_arch_workaround_state(vcpu); |
1513 | + |
1514 | fp_enabled = __fpsimd_enabled(); |
1515 | |
1516 | __sysreg_save_guest_state(guest_ctxt); |
1517 | @@ -364,7 +402,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) |
1518 | |
1519 | static const char __hyp_panic_string[] = "HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n"; |
1520 | |
1521 | -static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par) |
1522 | +static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par, |
1523 | + struct kvm_vcpu *vcpu) |
1524 | { |
1525 | unsigned long str_va; |
1526 | |
1527 | @@ -378,35 +417,32 @@ static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par) |
1528 | __hyp_do_panic(str_va, |
1529 | spsr, elr, |
1530 | read_sysreg(esr_el2), read_sysreg_el2(far), |
1531 | - read_sysreg(hpfar_el2), par, |
1532 | - (void *)read_sysreg(tpidr_el2)); |
1533 | + read_sysreg(hpfar_el2), par, vcpu); |
1534 | } |
1535 | |
1536 | -static void __hyp_text __hyp_call_panic_vhe(u64 spsr, u64 elr, u64 par) |
1537 | +static void __hyp_text __hyp_call_panic_vhe(u64 spsr, u64 elr, u64 par, |
1538 | + struct kvm_vcpu *vcpu) |
1539 | { |
1540 | panic(__hyp_panic_string, |
1541 | spsr, elr, |
1542 | read_sysreg_el2(esr), read_sysreg_el2(far), |
1543 | - read_sysreg(hpfar_el2), par, |
1544 | - (void *)read_sysreg(tpidr_el2)); |
1545 | + read_sysreg(hpfar_el2), par, vcpu); |
1546 | } |
1547 | |
1548 | static hyp_alternate_select(__hyp_call_panic, |
1549 | __hyp_call_panic_nvhe, __hyp_call_panic_vhe, |
1550 | ARM64_HAS_VIRT_HOST_EXTN); |
1551 | |
1552 | -void __hyp_text __noreturn __hyp_panic(void) |
1553 | +void __hyp_text __noreturn hyp_panic(struct kvm_cpu_context *host_ctxt) |
1554 | { |
1555 | + struct kvm_vcpu *vcpu = NULL; |
1556 | + |
1557 | u64 spsr = read_sysreg_el2(spsr); |
1558 | u64 elr = read_sysreg_el2(elr); |
1559 | u64 par = read_sysreg(par_el1); |
1560 | |
1561 | if (read_sysreg(vttbr_el2)) { |
1562 | - struct kvm_vcpu *vcpu; |
1563 | - struct kvm_cpu_context *host_ctxt; |
1564 | - |
1565 | - vcpu = (struct kvm_vcpu *)read_sysreg(tpidr_el2); |
1566 | - host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context); |
1567 | + vcpu = host_ctxt->__hyp_running_vcpu; |
1568 | __timer_save_state(vcpu); |
1569 | __deactivate_traps(vcpu); |
1570 | __deactivate_vm(vcpu); |
1571 | @@ -414,7 +450,7 @@ void __hyp_text __noreturn __hyp_panic(void) |
1572 | } |
1573 | |
1574 | /* Call panic for real */ |
1575 | - __hyp_call_panic()(spsr, elr, par); |
1576 | + __hyp_call_panic()(spsr, elr, par, vcpu); |
1577 | |
1578 | unreachable(); |
1579 | } |
1580 | diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c |
1581 | index 934137647837..e19d89cabf2a 100644 |
1582 | --- a/arch/arm64/kvm/hyp/sysreg-sr.c |
1583 | +++ b/arch/arm64/kvm/hyp/sysreg-sr.c |
1584 | @@ -27,8 +27,8 @@ static void __hyp_text __sysreg_do_nothing(struct kvm_cpu_context *ctxt) { } |
1585 | /* |
1586 | * Non-VHE: Both host and guest must save everything. |
1587 | * |
1588 | - * VHE: Host must save tpidr*_el[01], actlr_el1, mdscr_el1, sp0, pc, |
1589 | - * pstate, and guest must save everything. |
1590 | + * VHE: Host must save tpidr*_el0, actlr_el1, mdscr_el1, sp_el0, |
1591 | + * and guest must save everything. |
1592 | */ |
1593 | |
1594 | static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) |
1595 | @@ -36,11 +36,8 @@ static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) |
1596 | ctxt->sys_regs[ACTLR_EL1] = read_sysreg(actlr_el1); |
1597 | ctxt->sys_regs[TPIDR_EL0] = read_sysreg(tpidr_el0); |
1598 | ctxt->sys_regs[TPIDRRO_EL0] = read_sysreg(tpidrro_el0); |
1599 | - ctxt->sys_regs[TPIDR_EL1] = read_sysreg(tpidr_el1); |
1600 | ctxt->sys_regs[MDSCR_EL1] = read_sysreg(mdscr_el1); |
1601 | ctxt->gp_regs.regs.sp = read_sysreg(sp_el0); |
1602 | - ctxt->gp_regs.regs.pc = read_sysreg_el2(elr); |
1603 | - ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr); |
1604 | } |
1605 | |
1606 | static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt) |
1607 | @@ -62,10 +59,13 @@ static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt) |
1608 | ctxt->sys_regs[AMAIR_EL1] = read_sysreg_el1(amair); |
1609 | ctxt->sys_regs[CNTKCTL_EL1] = read_sysreg_el1(cntkctl); |
1610 | ctxt->sys_regs[PAR_EL1] = read_sysreg(par_el1); |
1611 | + ctxt->sys_regs[TPIDR_EL1] = read_sysreg(tpidr_el1); |
1612 | |
1613 | ctxt->gp_regs.sp_el1 = read_sysreg(sp_el1); |
1614 | ctxt->gp_regs.elr_el1 = read_sysreg_el1(elr); |
1615 | ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg_el1(spsr); |
1616 | + ctxt->gp_regs.regs.pc = read_sysreg_el2(elr); |
1617 | + ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr); |
1618 | } |
1619 | |
1620 | static hyp_alternate_select(__sysreg_call_save_host_state, |
1621 | @@ -89,11 +89,8 @@ static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctx |
1622 | write_sysreg(ctxt->sys_regs[ACTLR_EL1], actlr_el1); |
1623 | write_sysreg(ctxt->sys_regs[TPIDR_EL0], tpidr_el0); |
1624 | write_sysreg(ctxt->sys_regs[TPIDRRO_EL0], tpidrro_el0); |
1625 | - write_sysreg(ctxt->sys_regs[TPIDR_EL1], tpidr_el1); |
1626 | write_sysreg(ctxt->sys_regs[MDSCR_EL1], mdscr_el1); |
1627 | write_sysreg(ctxt->gp_regs.regs.sp, sp_el0); |
1628 | - write_sysreg_el2(ctxt->gp_regs.regs.pc, elr); |
1629 | - write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr); |
1630 | } |
1631 | |
1632 | static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt) |
1633 | @@ -115,10 +112,13 @@ static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt) |
1634 | write_sysreg_el1(ctxt->sys_regs[AMAIR_EL1], amair); |
1635 | write_sysreg_el1(ctxt->sys_regs[CNTKCTL_EL1], cntkctl); |
1636 | write_sysreg(ctxt->sys_regs[PAR_EL1], par_el1); |
1637 | + write_sysreg(ctxt->sys_regs[TPIDR_EL1], tpidr_el1); |
1638 | |
1639 | write_sysreg(ctxt->gp_regs.sp_el1, sp_el1); |
1640 | write_sysreg_el1(ctxt->gp_regs.elr_el1, elr); |
1641 | write_sysreg_el1(ctxt->gp_regs.spsr[KVM_SPSR_EL1],spsr); |
1642 | + write_sysreg_el2(ctxt->gp_regs.regs.pc, elr); |
1643 | + write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr); |
1644 | } |
1645 | |
1646 | static hyp_alternate_select(__sysreg_call_restore_host_state, |
1647 | @@ -183,3 +183,8 @@ void __hyp_text __sysreg32_restore_state(struct kvm_vcpu *vcpu) |
1648 | if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY) |
1649 | write_sysreg(sysreg[DBGVCR32_EL2], dbgvcr32_el2); |
1650 | } |
1651 | + |
1652 | +void __hyp_text __kvm_set_tpidr_el2(u64 tpidr_el2) |
1653 | +{ |
1654 | + asm("msr tpidr_el2, %0": : "r" (tpidr_el2)); |
1655 | +} |
1656 | diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c |
1657 | index 5bc460884639..29a27a09f21f 100644 |
1658 | --- a/arch/arm64/kvm/reset.c |
1659 | +++ b/arch/arm64/kvm/reset.c |
1660 | @@ -135,6 +135,10 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) |
1661 | /* Reset PMU */ |
1662 | kvm_pmu_vcpu_reset(vcpu); |
1663 | |
1664 | + /* Default workaround setup is enabled (if supported) */ |
1665 | + if (kvm_arm_have_ssbd() == KVM_SSBD_KERNEL) |
1666 | + vcpu->arch.workaround_flags |= VCPU_WORKAROUND_2_FLAG; |
1667 | + |
1668 | /* Reset timer */ |
1669 | return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq); |
1670 | } |
1671 | diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c |
1672 | index cb1e9c184b5a..513a63b9b991 100644 |
1673 | --- a/arch/mips/kernel/process.c |
1674 | +++ b/arch/mips/kernel/process.c |
1675 | @@ -26,6 +26,7 @@ |
1676 | #include <linux/kallsyms.h> |
1677 | #include <linux/random.h> |
1678 | #include <linux/prctl.h> |
1679 | +#include <linux/nmi.h> |
1680 | |
1681 | #include <asm/asm.h> |
1682 | #include <asm/bootinfo.h> |
1683 | @@ -633,28 +634,42 @@ unsigned long arch_align_stack(unsigned long sp) |
1684 | return sp & ALMASK; |
1685 | } |
1686 | |
1687 | -static void arch_dump_stack(void *info) |
1688 | -{ |
1689 | - struct pt_regs *regs; |
1690 | +static DEFINE_PER_CPU(struct call_single_data, backtrace_csd); |
1691 | +static struct cpumask backtrace_csd_busy; |
1692 | |
1693 | - regs = get_irq_regs(); |
1694 | - |
1695 | - if (regs) |
1696 | - show_regs(regs); |
1697 | - else |
1698 | - dump_stack(); |
1699 | +static void handle_backtrace(void *info) |
1700 | +{ |
1701 | + nmi_cpu_backtrace(get_irq_regs()); |
1702 | + cpumask_clear_cpu(smp_processor_id(), &backtrace_csd_busy); |
1703 | } |
1704 | |
1705 | -void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) |
1706 | +static void raise_backtrace(cpumask_t *mask) |
1707 | { |
1708 | - long this_cpu = get_cpu(); |
1709 | + struct call_single_data *csd; |
1710 | + int cpu; |
1711 | |
1712 | - if (cpumask_test_cpu(this_cpu, mask) && !exclude_self) |
1713 | - dump_stack(); |
1714 | + for_each_cpu(cpu, mask) { |
1715 | + /* |
1716 | + * If we previously sent an IPI to the target CPU & it hasn't |
1717 | + * cleared its bit in the busy cpumask then it didn't handle |
1718 | + * our previous IPI & it's not safe for us to reuse the |
1719 | + * call_single_data_t. |
1720 | + */ |
1721 | + if (cpumask_test_and_set_cpu(cpu, &backtrace_csd_busy)) { |
1722 | + pr_warn("Unable to send backtrace IPI to CPU%u - perhaps it hung?\n", |
1723 | + cpu); |
1724 | + continue; |
1725 | + } |
1726 | |
1727 | - smp_call_function_many(mask, arch_dump_stack, NULL, 1); |
1728 | + csd = &per_cpu(backtrace_csd, cpu); |
1729 | + csd->func = handle_backtrace; |
1730 | + smp_call_function_single_async(cpu, csd); |
1731 | + } |
1732 | +} |
1733 | |
1734 | - put_cpu(); |
1735 | +void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) |
1736 | +{ |
1737 | + nmi_trigger_cpumask_backtrace(mask, exclude_self, raise_backtrace); |
1738 | } |
1739 | |
1740 | int mips_get_process_fp_mode(struct task_struct *task) |
1741 | diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h |
1742 | index 8d8c24f3a963..742712b4bdc3 100644 |
1743 | --- a/arch/x86/include/asm/asm.h |
1744 | +++ b/arch/x86/include/asm/asm.h |
1745 | @@ -45,6 +45,65 @@ |
1746 | #define _ASM_SI __ASM_REG(si) |
1747 | #define _ASM_DI __ASM_REG(di) |
1748 | |
1749 | +#ifndef __x86_64__ |
1750 | +/* 32 bit */ |
1751 | + |
1752 | +#define _ASM_ARG1 _ASM_AX |
1753 | +#define _ASM_ARG2 _ASM_DX |
1754 | +#define _ASM_ARG3 _ASM_CX |
1755 | + |
1756 | +#define _ASM_ARG1L eax |
1757 | +#define _ASM_ARG2L edx |
1758 | +#define _ASM_ARG3L ecx |
1759 | + |
1760 | +#define _ASM_ARG1W ax |
1761 | +#define _ASM_ARG2W dx |
1762 | +#define _ASM_ARG3W cx |
1763 | + |
1764 | +#define _ASM_ARG1B al |
1765 | +#define _ASM_ARG2B dl |
1766 | +#define _ASM_ARG3B cl |
1767 | + |
1768 | +#else |
1769 | +/* 64 bit */ |
1770 | + |
1771 | +#define _ASM_ARG1 _ASM_DI |
1772 | +#define _ASM_ARG2 _ASM_SI |
1773 | +#define _ASM_ARG3 _ASM_DX |
1774 | +#define _ASM_ARG4 _ASM_CX |
1775 | +#define _ASM_ARG5 r8 |
1776 | +#define _ASM_ARG6 r9 |
1777 | + |
1778 | +#define _ASM_ARG1Q rdi |
1779 | +#define _ASM_ARG2Q rsi |
1780 | +#define _ASM_ARG3Q rdx |
1781 | +#define _ASM_ARG4Q rcx |
1782 | +#define _ASM_ARG5Q r8 |
1783 | +#define _ASM_ARG6Q r9 |
1784 | + |
1785 | +#define _ASM_ARG1L edi |
1786 | +#define _ASM_ARG2L esi |
1787 | +#define _ASM_ARG3L edx |
1788 | +#define _ASM_ARG4L ecx |
1789 | +#define _ASM_ARG5L r8d |
1790 | +#define _ASM_ARG6L r9d |
1791 | + |
1792 | +#define _ASM_ARG1W di |
1793 | +#define _ASM_ARG2W si |
1794 | +#define _ASM_ARG3W dx |
1795 | +#define _ASM_ARG4W cx |
1796 | +#define _ASM_ARG5W r8w |
1797 | +#define _ASM_ARG6W r9w |
1798 | + |
1799 | +#define _ASM_ARG1B dil |
1800 | +#define _ASM_ARG2B sil |
1801 | +#define _ASM_ARG3B dl |
1802 | +#define _ASM_ARG4B cl |
1803 | +#define _ASM_ARG5B r8b |
1804 | +#define _ASM_ARG6B r9b |
1805 | + |
1806 | +#endif |
1807 | + |
1808 | /* |
1809 | * Macros to generate condition code outputs from inline assembly, |
1810 | * The output operand must be type "bool". |
1811 | diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h |
1812 | index ac7692dcfa2e..8a8a6c66be9a 100644 |
1813 | --- a/arch/x86/include/asm/irqflags.h |
1814 | +++ b/arch/x86/include/asm/irqflags.h |
1815 | @@ -12,7 +12,7 @@ |
1816 | * Interrupt control: |
1817 | */ |
1818 | |
1819 | -static inline unsigned long native_save_fl(void) |
1820 | +extern inline unsigned long native_save_fl(void) |
1821 | { |
1822 | unsigned long flags; |
1823 | |
1824 | diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile |
1825 | index 4c9c61517613..a9ba968621cb 100644 |
1826 | --- a/arch/x86/kernel/Makefile |
1827 | +++ b/arch/x86/kernel/Makefile |
1828 | @@ -56,6 +56,7 @@ obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o |
1829 | obj-y += tsc.o tsc_msr.o io_delay.o rtc.o |
1830 | obj-y += pci-iommu_table.o |
1831 | obj-y += resource.o |
1832 | +obj-y += irqflags.o |
1833 | |
1834 | obj-y += process.o |
1835 | obj-y += fpu/ |
1836 | diff --git a/arch/x86/kernel/irqflags.S b/arch/x86/kernel/irqflags.S |
1837 | new file mode 100644 |
1838 | index 000000000000..ddeeaac8adda |
1839 | --- /dev/null |
1840 | +++ b/arch/x86/kernel/irqflags.S |
1841 | @@ -0,0 +1,26 @@ |
1842 | +/* SPDX-License-Identifier: GPL-2.0 */ |
1843 | + |
1844 | +#include <asm/asm.h> |
1845 | +#include <asm/export.h> |
1846 | +#include <linux/linkage.h> |
1847 | + |
1848 | +/* |
1849 | + * unsigned long native_save_fl(void) |
1850 | + */ |
1851 | +ENTRY(native_save_fl) |
1852 | + pushf |
1853 | + pop %_ASM_AX |
1854 | + ret |
1855 | +ENDPROC(native_save_fl) |
1856 | +EXPORT_SYMBOL(native_save_fl) |
1857 | + |
1858 | +/* |
1859 | + * void native_restore_fl(unsigned long flags) |
1860 | + * %eax/%rdi: flags |
1861 | + */ |
1862 | +ENTRY(native_restore_fl) |
1863 | + push %_ASM_ARG1 |
1864 | + popf |
1865 | + ret |
1866 | +ENDPROC(native_restore_fl) |
1867 | +EXPORT_SYMBOL(native_restore_fl) |
1868 | diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c |
1869 | index d0fac641e717..a0b88f148990 100644 |
1870 | --- a/drivers/atm/zatm.c |
1871 | +++ b/drivers/atm/zatm.c |
1872 | @@ -1483,6 +1483,8 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg) |
1873 | return -EFAULT; |
1874 | if (pool < 0 || pool > ZATM_LAST_POOL) |
1875 | return -EINVAL; |
1876 | + pool = array_index_nospec(pool, |
1877 | + ZATM_LAST_POOL + 1); |
1878 | if (copy_from_user(&info, |
1879 | &((struct zatm_pool_req __user *) arg)->info, |
1880 | sizeof(info))) return -EFAULT; |
1881 | diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c |
1882 | index dae1e39139e9..c7524bbbaf98 100644 |
1883 | --- a/drivers/crypto/amcc/crypto4xx_core.c |
1884 | +++ b/drivers/crypto/amcc/crypto4xx_core.c |
1885 | @@ -208,7 +208,7 @@ static u32 crypto4xx_build_pdr(struct crypto4xx_device *dev) |
1886 | dev->pdr_pa); |
1887 | return -ENOMEM; |
1888 | } |
1889 | - memset(dev->pdr, 0, sizeof(struct ce_pd) * PPC4XX_NUM_PD); |
1890 | + memset(dev->pdr, 0, sizeof(struct ce_pd) * PPC4XX_NUM_PD); |
1891 | dev->shadow_sa_pool = dma_alloc_coherent(dev->core_dev->device, |
1892 | 256 * PPC4XX_NUM_PD, |
1893 | &dev->shadow_sa_pool_pa, |
1894 | @@ -241,13 +241,15 @@ static u32 crypto4xx_build_pdr(struct crypto4xx_device *dev) |
1895 | |
1896 | static void crypto4xx_destroy_pdr(struct crypto4xx_device *dev) |
1897 | { |
1898 | - if (dev->pdr != NULL) |
1899 | + if (dev->pdr) |
1900 | dma_free_coherent(dev->core_dev->device, |
1901 | sizeof(struct ce_pd) * PPC4XX_NUM_PD, |
1902 | dev->pdr, dev->pdr_pa); |
1903 | + |
1904 | if (dev->shadow_sa_pool) |
1905 | dma_free_coherent(dev->core_dev->device, 256 * PPC4XX_NUM_PD, |
1906 | dev->shadow_sa_pool, dev->shadow_sa_pool_pa); |
1907 | + |
1908 | if (dev->shadow_sr_pool) |
1909 | dma_free_coherent(dev->core_dev->device, |
1910 | sizeof(struct sa_state_record) * PPC4XX_NUM_PD, |
1911 | @@ -417,12 +419,12 @@ static u32 crypto4xx_build_sdr(struct crypto4xx_device *dev) |
1912 | |
1913 | static void crypto4xx_destroy_sdr(struct crypto4xx_device *dev) |
1914 | { |
1915 | - if (dev->sdr != NULL) |
1916 | + if (dev->sdr) |
1917 | dma_free_coherent(dev->core_dev->device, |
1918 | sizeof(struct ce_sd) * PPC4XX_NUM_SD, |
1919 | dev->sdr, dev->sdr_pa); |
1920 | |
1921 | - if (dev->scatter_buffer_va != NULL) |
1922 | + if (dev->scatter_buffer_va) |
1923 | dma_free_coherent(dev->core_dev->device, |
1924 | dev->scatter_buffer_size * PPC4XX_NUM_SD, |
1925 | dev->scatter_buffer_va, |
1926 | @@ -1034,12 +1036,10 @@ int crypto4xx_register_alg(struct crypto4xx_device *sec_dev, |
1927 | break; |
1928 | } |
1929 | |
1930 | - if (rc) { |
1931 | - list_del(&alg->entry); |
1932 | + if (rc) |
1933 | kfree(alg); |
1934 | - } else { |
1935 | + else |
1936 | list_add_tail(&alg->entry, &sec_dev->alg_list); |
1937 | - } |
1938 | } |
1939 | |
1940 | return 0; |
1941 | @@ -1193,7 +1193,7 @@ static int crypto4xx_probe(struct platform_device *ofdev) |
1942 | |
1943 | rc = crypto4xx_build_gdr(core_dev->dev); |
1944 | if (rc) |
1945 | - goto err_build_gdr; |
1946 | + goto err_build_pdr; |
1947 | |
1948 | rc = crypto4xx_build_sdr(core_dev->dev); |
1949 | if (rc) |
1950 | @@ -1236,12 +1236,11 @@ static int crypto4xx_probe(struct platform_device *ofdev) |
1951 | err_request_irq: |
1952 | irq_dispose_mapping(core_dev->irq); |
1953 | tasklet_kill(&core_dev->tasklet); |
1954 | - crypto4xx_destroy_sdr(core_dev->dev); |
1955 | err_build_sdr: |
1956 | + crypto4xx_destroy_sdr(core_dev->dev); |
1957 | crypto4xx_destroy_gdr(core_dev->dev); |
1958 | -err_build_gdr: |
1959 | - crypto4xx_destroy_pdr(core_dev->dev); |
1960 | err_build_pdr: |
1961 | + crypto4xx_destroy_pdr(core_dev->dev); |
1962 | kfree(core_dev->dev); |
1963 | err_alloc_dev: |
1964 | kfree(core_dev); |
1965 | diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c |
1966 | index 9cf7fcd28034..16a7df2a0246 100644 |
1967 | --- a/drivers/mtd/devices/m25p80.c |
1968 | +++ b/drivers/mtd/devices/m25p80.c |
1969 | @@ -172,7 +172,8 @@ static ssize_t m25p80_read(struct spi_nor *nor, loff_t from, size_t len, |
1970 | |
1971 | t[1].rx_buf = buf; |
1972 | t[1].rx_nbits = m25p80_rx_nbits(nor); |
1973 | - t[1].len = min(len, spi_max_transfer_size(spi)); |
1974 | + t[1].len = min3(len, spi_max_transfer_size(spi), |
1975 | + spi_max_message_size(spi) - t[0].len); |
1976 | spi_message_add_tail(&t[1], &m); |
1977 | |
1978 | ret = spi_sync(spi, &m); |
1979 | diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c |
1980 | index 08d91efceed0..c4078401b7de 100644 |
1981 | --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c |
1982 | +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c |
1983 | @@ -1063,7 +1063,8 @@ static int bcm_enet_open(struct net_device *dev) |
1984 | val = enet_readl(priv, ENET_CTL_REG); |
1985 | val |= ENET_CTL_ENABLE_MASK; |
1986 | enet_writel(priv, val, ENET_CTL_REG); |
1987 | - enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG); |
1988 | + if (priv->dma_has_sram) |
1989 | + enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG); |
1990 | enet_dmac_writel(priv, priv->dma_chan_en_mask, |
1991 | ENETDMAC_CHANCFG, priv->rx_chan); |
1992 | |
1993 | @@ -1790,7 +1791,9 @@ static int bcm_enet_probe(struct platform_device *pdev) |
1994 | ret = PTR_ERR(priv->mac_clk); |
1995 | goto out; |
1996 | } |
1997 | - clk_prepare_enable(priv->mac_clk); |
1998 | + ret = clk_prepare_enable(priv->mac_clk); |
1999 | + if (ret) |
2000 | + goto out_put_clk_mac; |
2001 | |
2002 | /* initialize default and fetch platform data */ |
2003 | priv->rx_ring_size = BCMENET_DEF_RX_DESC; |
2004 | @@ -1822,9 +1825,11 @@ static int bcm_enet_probe(struct platform_device *pdev) |
2005 | if (IS_ERR(priv->phy_clk)) { |
2006 | ret = PTR_ERR(priv->phy_clk); |
2007 | priv->phy_clk = NULL; |
2008 | - goto out_put_clk_mac; |
2009 | + goto out_disable_clk_mac; |
2010 | } |
2011 | - clk_prepare_enable(priv->phy_clk); |
2012 | + ret = clk_prepare_enable(priv->phy_clk); |
2013 | + if (ret) |
2014 | + goto out_put_clk_phy; |
2015 | } |
2016 | |
2017 | /* do minimal hardware init to be able to probe mii bus */ |
2018 | @@ -1915,13 +1920,16 @@ static int bcm_enet_probe(struct platform_device *pdev) |
2019 | out_uninit_hw: |
2020 | /* turn off mdc clock */ |
2021 | enet_writel(priv, 0, ENET_MIISC_REG); |
2022 | - if (priv->phy_clk) { |
2023 | + if (priv->phy_clk) |
2024 | clk_disable_unprepare(priv->phy_clk); |
2025 | + |
2026 | +out_put_clk_phy: |
2027 | + if (priv->phy_clk) |
2028 | clk_put(priv->phy_clk); |
2029 | - } |
2030 | |
2031 | -out_put_clk_mac: |
2032 | +out_disable_clk_mac: |
2033 | clk_disable_unprepare(priv->mac_clk); |
2034 | +out_put_clk_mac: |
2035 | clk_put(priv->mac_clk); |
2036 | out: |
2037 | free_netdev(dev); |
2038 | @@ -2766,7 +2774,9 @@ static int bcm_enetsw_probe(struct platform_device *pdev) |
2039 | ret = PTR_ERR(priv->mac_clk); |
2040 | goto out_unmap; |
2041 | } |
2042 | - clk_enable(priv->mac_clk); |
2043 | + ret = clk_prepare_enable(priv->mac_clk); |
2044 | + if (ret) |
2045 | + goto out_put_clk; |
2046 | |
2047 | priv->rx_chan = 0; |
2048 | priv->tx_chan = 1; |
2049 | @@ -2787,7 +2797,7 @@ static int bcm_enetsw_probe(struct platform_device *pdev) |
2050 | |
2051 | ret = register_netdev(dev); |
2052 | if (ret) |
2053 | - goto out_put_clk; |
2054 | + goto out_disable_clk; |
2055 | |
2056 | netif_carrier_off(dev); |
2057 | platform_set_drvdata(pdev, dev); |
2058 | @@ -2796,6 +2806,9 @@ static int bcm_enetsw_probe(struct platform_device *pdev) |
2059 | |
2060 | return 0; |
2061 | |
2062 | +out_disable_clk: |
2063 | + clk_disable_unprepare(priv->mac_clk); |
2064 | + |
2065 | out_put_clk: |
2066 | clk_put(priv->mac_clk); |
2067 | |
2068 | @@ -2827,6 +2840,9 @@ static int bcm_enetsw_remove(struct platform_device *pdev) |
2069 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2070 | release_mem_region(res->start, resource_size(res)); |
2071 | |
2072 | + clk_disable_unprepare(priv->mac_clk); |
2073 | + clk_put(priv->mac_clk); |
2074 | + |
2075 | free_netdev(dev); |
2076 | return 0; |
2077 | } |
2078 | diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c |
2079 | index 43da891fab97..dc0efbd91c32 100644 |
2080 | --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c |
2081 | +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c |
2082 | @@ -50,6 +50,7 @@ |
2083 | #include <linux/stringify.h> |
2084 | #include <linux/sched.h> |
2085 | #include <linux/slab.h> |
2086 | +#include <linux/nospec.h> |
2087 | #include <asm/uaccess.h> |
2088 | |
2089 | #include "common.h" |
2090 | @@ -2259,6 +2260,7 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) |
2091 | |
2092 | if (t.qset_idx >= nqsets) |
2093 | return -EINVAL; |
2094 | + t.qset_idx = array_index_nospec(t.qset_idx, nqsets); |
2095 | |
2096 | q = &adapter->params.sge.qset[q1 + t.qset_idx]; |
2097 | t.rspq_size = q->rspq_size; |
2098 | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c |
2099 | index 6631fb0782d7..9680c8805178 100644 |
2100 | --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c |
2101 | +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c |
2102 | @@ -784,6 +784,7 @@ static void cmd_work_handler(struct work_struct *work) |
2103 | struct semaphore *sem; |
2104 | unsigned long flags; |
2105 | int alloc_ret; |
2106 | + int cmd_mode; |
2107 | |
2108 | sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem; |
2109 | down(sem); |
2110 | @@ -830,6 +831,7 @@ static void cmd_work_handler(struct work_struct *work) |
2111 | set_signature(ent, !cmd->checksum_disabled); |
2112 | dump_command(dev, ent, 1); |
2113 | ent->ts1 = ktime_get_ns(); |
2114 | + cmd_mode = cmd->mode; |
2115 | |
2116 | if (ent->callback) |
2117 | schedule_delayed_work(&ent->cb_timeout_work, cb_timeout); |
2118 | @@ -854,7 +856,7 @@ static void cmd_work_handler(struct work_struct *work) |
2119 | iowrite32be(1 << ent->idx, &dev->iseg->cmd_dbell); |
2120 | mmiowb(); |
2121 | /* if not in polling don't use ent after this point */ |
2122 | - if (cmd->mode == CMD_MODE_POLLING) { |
2123 | + if (cmd_mode == CMD_MODE_POLLING) { |
2124 | poll_timeout(ent); |
2125 | /* make sure we read the descriptor after ownership is SW */ |
2126 | rmb(); |
2127 | @@ -1256,7 +1258,7 @@ static ssize_t outlen_write(struct file *filp, const char __user *buf, |
2128 | { |
2129 | struct mlx5_core_dev *dev = filp->private_data; |
2130 | struct mlx5_cmd_debug *dbg = &dev->cmd.dbg; |
2131 | - char outlen_str[8]; |
2132 | + char outlen_str[8] = {0}; |
2133 | int outlen; |
2134 | void *ptr; |
2135 | int err; |
2136 | @@ -1271,8 +1273,6 @@ static ssize_t outlen_write(struct file *filp, const char __user *buf, |
2137 | if (copy_from_user(outlen_str, buf, count)) |
2138 | return -EFAULT; |
2139 | |
2140 | - outlen_str[7] = 0; |
2141 | - |
2142 | err = sscanf(outlen_str, "%d", &outlen); |
2143 | if (err < 0) |
2144 | return err; |
2145 | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c |
2146 | index 34e7184e23c9..43d7c8378fb4 100644 |
2147 | --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c |
2148 | +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c |
2149 | @@ -575,7 +575,7 @@ EXPORT_SYMBOL_GPL(mlx5_set_port_prio_tc); |
2150 | static int mlx5_set_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *in, |
2151 | int inlen) |
2152 | { |
2153 | - u32 out[MLX5_ST_SZ_DW(qtct_reg)]; |
2154 | + u32 out[MLX5_ST_SZ_DW(qetc_reg)]; |
2155 | |
2156 | if (!MLX5_CAP_GEN(mdev, ets)) |
2157 | return -ENOTSUPP; |
2158 | @@ -587,7 +587,7 @@ static int mlx5_set_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *in, |
2159 | static int mlx5_query_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *out, |
2160 | int outlen) |
2161 | { |
2162 | - u32 in[MLX5_ST_SZ_DW(qtct_reg)]; |
2163 | + u32 in[MLX5_ST_SZ_DW(qetc_reg)]; |
2164 | |
2165 | if (!MLX5_CAP_GEN(mdev, ets)) |
2166 | return -ENOTSUPP; |
2167 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c |
2168 | index 9d59cb85c012..7b6824e560d2 100644 |
2169 | --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c |
2170 | +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c |
2171 | @@ -677,9 +677,9 @@ qed_dcbx_get_local_lldp_params(struct qed_hwfn *p_hwfn, |
2172 | p_local = &p_hwfn->p_dcbx_info->lldp_local[LLDP_NEAREST_BRIDGE]; |
2173 | |
2174 | memcpy(params->lldp_local.local_chassis_id, p_local->local_chassis_id, |
2175 | - ARRAY_SIZE(p_local->local_chassis_id)); |
2176 | + sizeof(p_local->local_chassis_id)); |
2177 | memcpy(params->lldp_local.local_port_id, p_local->local_port_id, |
2178 | - ARRAY_SIZE(p_local->local_port_id)); |
2179 | + sizeof(p_local->local_port_id)); |
2180 | } |
2181 | |
2182 | static void |
2183 | @@ -692,9 +692,9 @@ qed_dcbx_get_remote_lldp_params(struct qed_hwfn *p_hwfn, |
2184 | p_remote = &p_hwfn->p_dcbx_info->lldp_remote[LLDP_NEAREST_BRIDGE]; |
2185 | |
2186 | memcpy(params->lldp_remote.peer_chassis_id, p_remote->peer_chassis_id, |
2187 | - ARRAY_SIZE(p_remote->peer_chassis_id)); |
2188 | + sizeof(p_remote->peer_chassis_id)); |
2189 | memcpy(params->lldp_remote.peer_port_id, p_remote->peer_port_id, |
2190 | - ARRAY_SIZE(p_remote->peer_port_id)); |
2191 | + sizeof(p_remote->peer_port_id)); |
2192 | } |
2193 | |
2194 | static int |
2195 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c |
2196 | index 0b949c6d83fc..f36bd0bd37da 100644 |
2197 | --- a/drivers/net/ethernet/qlogic/qed/qed_main.c |
2198 | +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c |
2199 | @@ -23,6 +23,7 @@ |
2200 | #include <linux/vmalloc.h> |
2201 | #include <linux/qed/qed_if.h> |
2202 | #include <linux/qed/qed_ll2_if.h> |
2203 | +#include <linux/crash_dump.h> |
2204 | |
2205 | #include "qed.h" |
2206 | #include "qed_sriov.h" |
2207 | @@ -701,6 +702,14 @@ static int qed_slowpath_setup_int(struct qed_dev *cdev, |
2208 | /* We want a minimum of one slowpath and one fastpath vector per hwfn */ |
2209 | cdev->int_params.in.min_msix_cnt = cdev->num_hwfns * 2; |
2210 | |
2211 | + if (is_kdump_kernel()) { |
2212 | + DP_INFO(cdev, |
2213 | + "Kdump kernel: Limit the max number of requested MSI-X vectors to %hd\n", |
2214 | + cdev->int_params.in.min_msix_cnt); |
2215 | + cdev->int_params.in.num_vectors = |
2216 | + cdev->int_params.in.min_msix_cnt; |
2217 | + } |
2218 | + |
2219 | rc = qed_set_int_mode(cdev, false); |
2220 | if (rc) { |
2221 | DP_ERR(cdev, "qed_slowpath_setup_int ERR\n"); |
2222 | diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c |
2223 | index d6ad0fbd054e..920321bf4bb6 100644 |
2224 | --- a/drivers/net/ethernet/sun/sungem.c |
2225 | +++ b/drivers/net/ethernet/sun/sungem.c |
2226 | @@ -59,8 +59,7 @@ |
2227 | #include <linux/sungem_phy.h> |
2228 | #include "sungem.h" |
2229 | |
2230 | -/* Stripping FCS is causing problems, disabled for now */ |
2231 | -#undef STRIP_FCS |
2232 | +#define STRIP_FCS |
2233 | |
2234 | #define DEFAULT_MSG (NETIF_MSG_DRV | \ |
2235 | NETIF_MSG_PROBE | \ |
2236 | @@ -434,7 +433,7 @@ static int gem_rxmac_reset(struct gem *gp) |
2237 | writel(desc_dma & 0xffffffff, gp->regs + RXDMA_DBLOW); |
2238 | writel(RX_RING_SIZE - 4, gp->regs + RXDMA_KICK); |
2239 | val = (RXDMA_CFG_BASE | (RX_OFFSET << 10) | |
2240 | - ((14 / 2) << 13) | RXDMA_CFG_FTHRESH_128); |
2241 | + (ETH_HLEN << 13) | RXDMA_CFG_FTHRESH_128); |
2242 | writel(val, gp->regs + RXDMA_CFG); |
2243 | if (readl(gp->regs + GREG_BIFCFG) & GREG_BIFCFG_M66EN) |
2244 | writel(((5 & RXDMA_BLANK_IPKTS) | |
2245 | @@ -759,7 +758,6 @@ static int gem_rx(struct gem *gp, int work_to_do) |
2246 | struct net_device *dev = gp->dev; |
2247 | int entry, drops, work_done = 0; |
2248 | u32 done; |
2249 | - __sum16 csum; |
2250 | |
2251 | if (netif_msg_rx_status(gp)) |
2252 | printk(KERN_DEBUG "%s: rx interrupt, done: %d, rx_new: %d\n", |
2253 | @@ -854,9 +852,13 @@ static int gem_rx(struct gem *gp, int work_to_do) |
2254 | skb = copy_skb; |
2255 | } |
2256 | |
2257 | - csum = (__force __sum16)htons((status & RXDCTRL_TCPCSUM) ^ 0xffff); |
2258 | - skb->csum = csum_unfold(csum); |
2259 | - skb->ip_summed = CHECKSUM_COMPLETE; |
2260 | + if (likely(dev->features & NETIF_F_RXCSUM)) { |
2261 | + __sum16 csum; |
2262 | + |
2263 | + csum = (__force __sum16)htons((status & RXDCTRL_TCPCSUM) ^ 0xffff); |
2264 | + skb->csum = csum_unfold(csum); |
2265 | + skb->ip_summed = CHECKSUM_COMPLETE; |
2266 | + } |
2267 | skb->protocol = eth_type_trans(skb, gp->dev); |
2268 | |
2269 | napi_gro_receive(&gp->napi, skb); |
2270 | @@ -1754,7 +1756,7 @@ static void gem_init_dma(struct gem *gp) |
2271 | writel(0, gp->regs + TXDMA_KICK); |
2272 | |
2273 | val = (RXDMA_CFG_BASE | (RX_OFFSET << 10) | |
2274 | - ((14 / 2) << 13) | RXDMA_CFG_FTHRESH_128); |
2275 | + (ETH_HLEN << 13) | RXDMA_CFG_FTHRESH_128); |
2276 | writel(val, gp->regs + RXDMA_CFG); |
2277 | |
2278 | writel(desc_dma >> 32, gp->regs + RXDMA_DBHI); |
2279 | @@ -2972,8 +2974,8 @@ static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2280 | pci_set_drvdata(pdev, dev); |
2281 | |
2282 | /* We can do scatter/gather and HW checksum */ |
2283 | - dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM; |
2284 | - dev->features |= dev->hw_features | NETIF_F_RXCSUM; |
2285 | + dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM; |
2286 | + dev->features = dev->hw_features; |
2287 | if (pci_using_dac) |
2288 | dev->features |= NETIF_F_HIGHDMA; |
2289 | |
2290 | diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c |
2291 | index dfbc4ef6d507..24eb5755604f 100644 |
2292 | --- a/drivers/net/ipvlan/ipvlan_main.c |
2293 | +++ b/drivers/net/ipvlan/ipvlan_main.c |
2294 | @@ -525,7 +525,8 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev, |
2295 | ipvlan->dev = dev; |
2296 | ipvlan->port = port; |
2297 | ipvlan->sfeatures = IPVLAN_FEATURES; |
2298 | - ipvlan_adjust_mtu(ipvlan, phy_dev); |
2299 | + if (!tb[IFLA_MTU]) |
2300 | + ipvlan_adjust_mtu(ipvlan, phy_dev); |
2301 | INIT_LIST_HEAD(&ipvlan->addrs); |
2302 | |
2303 | /* TODO Probably put random address here to be presented to the |
2304 | diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c |
2305 | index f5a96678494b..5e0626c80b81 100644 |
2306 | --- a/drivers/net/usb/lan78xx.c |
2307 | +++ b/drivers/net/usb/lan78xx.c |
2308 | @@ -2964,6 +2964,7 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) |
2309 | pkt_cnt = 0; |
2310 | count = 0; |
2311 | length = 0; |
2312 | + spin_lock_irqsave(&tqp->lock, flags); |
2313 | for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) { |
2314 | if (skb_is_gso(skb)) { |
2315 | if (pkt_cnt) { |
2316 | @@ -2972,7 +2973,8 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) |
2317 | } |
2318 | count = 1; |
2319 | length = skb->len - TX_OVERHEAD; |
2320 | - skb2 = skb_dequeue(tqp); |
2321 | + __skb_unlink(skb, tqp); |
2322 | + spin_unlock_irqrestore(&tqp->lock, flags); |
2323 | goto gso_skb; |
2324 | } |
2325 | |
2326 | @@ -2981,6 +2983,7 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) |
2327 | skb_totallen = skb->len + roundup(skb_totallen, sizeof(u32)); |
2328 | pkt_cnt++; |
2329 | } |
2330 | + spin_unlock_irqrestore(&tqp->lock, flags); |
2331 | |
2332 | /* copy to a single skb */ |
2333 | skb = alloc_skb(skb_totallen, GFP_ATOMIC); |
2334 | diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c |
2335 | index 85bc0ca61389..6d654d65f8a0 100644 |
2336 | --- a/drivers/net/usb/qmi_wwan.c |
2337 | +++ b/drivers/net/usb/qmi_wwan.c |
2338 | @@ -946,6 +946,7 @@ static const struct usb_device_id products[] = { |
2339 | {QMI_FIXED_INTF(0x413c, 0x81b3, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ |
2340 | {QMI_FIXED_INTF(0x413c, 0x81b6, 8)}, /* Dell Wireless 5811e */ |
2341 | {QMI_FIXED_INTF(0x413c, 0x81b6, 10)}, /* Dell Wireless 5811e */ |
2342 | + {QMI_FIXED_INTF(0x413c, 0x81d7, 1)}, /* Dell Wireless 5821e */ |
2343 | {QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */ |
2344 | {QMI_FIXED_INTF(0x03f0, 0x9d1d, 1)}, /* HP lt4120 Snapdragon X5 LTE */ |
2345 | {QMI_FIXED_INTF(0x22de, 0x9061, 3)}, /* WeTelecom WPD-600N */ |
2346 | diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c |
2347 | index d3d89b05f66e..5988674818ed 100644 |
2348 | --- a/drivers/net/usb/r8152.c |
2349 | +++ b/drivers/net/usb/r8152.c |
2350 | @@ -3327,7 +3327,8 @@ static int rtl8152_close(struct net_device *netdev) |
2351 | #ifdef CONFIG_PM_SLEEP |
2352 | unregister_pm_notifier(&tp->pm_notifier); |
2353 | #endif |
2354 | - napi_disable(&tp->napi); |
2355 | + if (!test_bit(RTL8152_UNPLUG, &tp->flags)) |
2356 | + napi_disable(&tp->napi); |
2357 | clear_bit(WORK_ENABLE, &tp->flags); |
2358 | usb_kill_urb(tp->intr_urb); |
2359 | cancel_delayed_work_sync(&tp->schedule); |
2360 | diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c |
2361 | index 4da4e458142c..9526643312d9 100644 |
2362 | --- a/drivers/net/wireless/realtek/rtlwifi/core.c |
2363 | +++ b/drivers/net/wireless/realtek/rtlwifi/core.c |
2364 | @@ -131,7 +131,6 @@ static void rtl_fw_do_work(const struct firmware *firmware, void *context, |
2365 | firmware->size); |
2366 | rtlpriv->rtlhal.wowlan_fwsize = firmware->size; |
2367 | } |
2368 | - rtlpriv->rtlhal.fwsize = firmware->size; |
2369 | release_firmware(firmware); |
2370 | } |
2371 | |
2372 | diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c |
2373 | index 487586e2d8b9..353c93bc459b 100644 |
2374 | --- a/drivers/vhost/net.c |
2375 | +++ b/drivers/vhost/net.c |
2376 | @@ -1052,7 +1052,8 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) |
2377 | if (ubufs) |
2378 | vhost_net_ubuf_put_wait_and_free(ubufs); |
2379 | err_ubufs: |
2380 | - sockfd_put(sock); |
2381 | + if (sock) |
2382 | + sockfd_put(sock); |
2383 | err_vq: |
2384 | mutex_unlock(&vq->mutex); |
2385 | err: |
2386 | diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c |
2387 | index f2961b13e8c5..c26d046adaaa 100644 |
2388 | --- a/fs/ocfs2/aops.c |
2389 | +++ b/fs/ocfs2/aops.c |
2390 | @@ -134,6 +134,19 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock, |
2391 | return err; |
2392 | } |
2393 | |
2394 | +static int ocfs2_lock_get_block(struct inode *inode, sector_t iblock, |
2395 | + struct buffer_head *bh_result, int create) |
2396 | +{ |
2397 | + int ret = 0; |
2398 | + struct ocfs2_inode_info *oi = OCFS2_I(inode); |
2399 | + |
2400 | + down_read(&oi->ip_alloc_sem); |
2401 | + ret = ocfs2_get_block(inode, iblock, bh_result, create); |
2402 | + up_read(&oi->ip_alloc_sem); |
2403 | + |
2404 | + return ret; |
2405 | +} |
2406 | + |
2407 | int ocfs2_get_block(struct inode *inode, sector_t iblock, |
2408 | struct buffer_head *bh_result, int create) |
2409 | { |
2410 | @@ -2120,7 +2133,7 @@ static void ocfs2_dio_free_write_ctx(struct inode *inode, |
2411 | * called like this: dio->get_blocks(dio->inode, fs_startblk, |
2412 | * fs_count, map_bh, dio->rw == WRITE); |
2413 | */ |
2414 | -static int ocfs2_dio_get_block(struct inode *inode, sector_t iblock, |
2415 | +static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock, |
2416 | struct buffer_head *bh_result, int create) |
2417 | { |
2418 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
2419 | @@ -2146,12 +2159,9 @@ static int ocfs2_dio_get_block(struct inode *inode, sector_t iblock, |
2420 | * while file size will be changed. |
2421 | */ |
2422 | if (pos + total_len <= i_size_read(inode)) { |
2423 | - down_read(&oi->ip_alloc_sem); |
2424 | - /* This is the fast path for re-write. */ |
2425 | - ret = ocfs2_get_block(inode, iblock, bh_result, create); |
2426 | - |
2427 | - up_read(&oi->ip_alloc_sem); |
2428 | |
2429 | + /* This is the fast path for re-write. */ |
2430 | + ret = ocfs2_lock_get_block(inode, iblock, bh_result, create); |
2431 | if (buffer_mapped(bh_result) && |
2432 | !buffer_new(bh_result) && |
2433 | ret == 0) |
2434 | @@ -2416,9 +2426,9 @@ static ssize_t ocfs2_direct_IO(struct kiocb *iocb, struct iov_iter *iter) |
2435 | return 0; |
2436 | |
2437 | if (iov_iter_rw(iter) == READ) |
2438 | - get_block = ocfs2_get_block; |
2439 | + get_block = ocfs2_lock_get_block; |
2440 | else |
2441 | - get_block = ocfs2_dio_get_block; |
2442 | + get_block = ocfs2_dio_wr_get_block; |
2443 | |
2444 | return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, |
2445 | iter, get_block, |
2446 | diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c |
2447 | index b17d180bdc16..c204ac9b49e5 100644 |
2448 | --- a/fs/ocfs2/cluster/nodemanager.c |
2449 | +++ b/fs/ocfs2/cluster/nodemanager.c |
2450 | @@ -40,6 +40,9 @@ char *o2nm_fence_method_desc[O2NM_FENCE_METHODS] = { |
2451 | "panic", /* O2NM_FENCE_PANIC */ |
2452 | }; |
2453 | |
2454 | +static inline void o2nm_lock_subsystem(void); |
2455 | +static inline void o2nm_unlock_subsystem(void); |
2456 | + |
2457 | struct o2nm_node *o2nm_get_node_by_num(u8 node_num) |
2458 | { |
2459 | struct o2nm_node *node = NULL; |
2460 | @@ -181,7 +184,10 @@ static struct o2nm_cluster *to_o2nm_cluster_from_node(struct o2nm_node *node) |
2461 | { |
2462 | /* through the first node_set .parent |
2463 | * mycluster/nodes/mynode == o2nm_cluster->o2nm_node_group->o2nm_node */ |
2464 | - return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent); |
2465 | + if (node->nd_item.ci_parent) |
2466 | + return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent); |
2467 | + else |
2468 | + return NULL; |
2469 | } |
2470 | |
2471 | enum { |
2472 | @@ -194,7 +200,7 @@ static ssize_t o2nm_node_num_store(struct config_item *item, const char *page, |
2473 | size_t count) |
2474 | { |
2475 | struct o2nm_node *node = to_o2nm_node(item); |
2476 | - struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); |
2477 | + struct o2nm_cluster *cluster; |
2478 | unsigned long tmp; |
2479 | char *p = (char *)page; |
2480 | int ret = 0; |
2481 | @@ -214,6 +220,13 @@ static ssize_t o2nm_node_num_store(struct config_item *item, const char *page, |
2482 | !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) |
2483 | return -EINVAL; /* XXX */ |
2484 | |
2485 | + o2nm_lock_subsystem(); |
2486 | + cluster = to_o2nm_cluster_from_node(node); |
2487 | + if (!cluster) { |
2488 | + o2nm_unlock_subsystem(); |
2489 | + return -EINVAL; |
2490 | + } |
2491 | + |
2492 | write_lock(&cluster->cl_nodes_lock); |
2493 | if (cluster->cl_nodes[tmp]) |
2494 | ret = -EEXIST; |
2495 | @@ -226,6 +239,8 @@ static ssize_t o2nm_node_num_store(struct config_item *item, const char *page, |
2496 | set_bit(tmp, cluster->cl_nodes_bitmap); |
2497 | } |
2498 | write_unlock(&cluster->cl_nodes_lock); |
2499 | + o2nm_unlock_subsystem(); |
2500 | + |
2501 | if (ret) |
2502 | return ret; |
2503 | |
2504 | @@ -269,7 +284,7 @@ static ssize_t o2nm_node_ipv4_address_store(struct config_item *item, |
2505 | size_t count) |
2506 | { |
2507 | struct o2nm_node *node = to_o2nm_node(item); |
2508 | - struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); |
2509 | + struct o2nm_cluster *cluster; |
2510 | int ret, i; |
2511 | struct rb_node **p, *parent; |
2512 | unsigned int octets[4]; |
2513 | @@ -286,6 +301,13 @@ static ssize_t o2nm_node_ipv4_address_store(struct config_item *item, |
2514 | be32_add_cpu(&ipv4_addr, octets[i] << (i * 8)); |
2515 | } |
2516 | |
2517 | + o2nm_lock_subsystem(); |
2518 | + cluster = to_o2nm_cluster_from_node(node); |
2519 | + if (!cluster) { |
2520 | + o2nm_unlock_subsystem(); |
2521 | + return -EINVAL; |
2522 | + } |
2523 | + |
2524 | ret = 0; |
2525 | write_lock(&cluster->cl_nodes_lock); |
2526 | if (o2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent)) |
2527 | @@ -298,6 +320,8 @@ static ssize_t o2nm_node_ipv4_address_store(struct config_item *item, |
2528 | rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree); |
2529 | } |
2530 | write_unlock(&cluster->cl_nodes_lock); |
2531 | + o2nm_unlock_subsystem(); |
2532 | + |
2533 | if (ret) |
2534 | return ret; |
2535 | |
2536 | @@ -315,7 +339,7 @@ static ssize_t o2nm_node_local_store(struct config_item *item, const char *page, |
2537 | size_t count) |
2538 | { |
2539 | struct o2nm_node *node = to_o2nm_node(item); |
2540 | - struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); |
2541 | + struct o2nm_cluster *cluster; |
2542 | unsigned long tmp; |
2543 | char *p = (char *)page; |
2544 | ssize_t ret; |
2545 | @@ -333,17 +357,26 @@ static ssize_t o2nm_node_local_store(struct config_item *item, const char *page, |
2546 | !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) |
2547 | return -EINVAL; /* XXX */ |
2548 | |
2549 | + o2nm_lock_subsystem(); |
2550 | + cluster = to_o2nm_cluster_from_node(node); |
2551 | + if (!cluster) { |
2552 | + ret = -EINVAL; |
2553 | + goto out; |
2554 | + } |
2555 | + |
2556 | /* the only failure case is trying to set a new local node |
2557 | * when a different one is already set */ |
2558 | if (tmp && tmp == cluster->cl_has_local && |
2559 | - cluster->cl_local_node != node->nd_num) |
2560 | - return -EBUSY; |
2561 | + cluster->cl_local_node != node->nd_num) { |
2562 | + ret = -EBUSY; |
2563 | + goto out; |
2564 | + } |
2565 | |
2566 | /* bring up the rx thread if we're setting the new local node. */ |
2567 | if (tmp && !cluster->cl_has_local) { |
2568 | ret = o2net_start_listening(node); |
2569 | if (ret) |
2570 | - return ret; |
2571 | + goto out; |
2572 | } |
2573 | |
2574 | if (!tmp && cluster->cl_has_local && |
2575 | @@ -358,7 +391,11 @@ static ssize_t o2nm_node_local_store(struct config_item *item, const char *page, |
2576 | cluster->cl_local_node = node->nd_num; |
2577 | } |
2578 | |
2579 | - return count; |
2580 | + ret = count; |
2581 | + |
2582 | +out: |
2583 | + o2nm_unlock_subsystem(); |
2584 | + return ret; |
2585 | } |
2586 | |
2587 | CONFIGFS_ATTR(o2nm_node_, num); |
2588 | @@ -738,6 +775,16 @@ static struct o2nm_cluster_group o2nm_cluster_group = { |
2589 | }, |
2590 | }; |
2591 | |
2592 | +static inline void o2nm_lock_subsystem(void) |
2593 | +{ |
2594 | + mutex_lock(&o2nm_cluster_group.cs_subsys.su_mutex); |
2595 | +} |
2596 | + |
2597 | +static inline void o2nm_unlock_subsystem(void) |
2598 | +{ |
2599 | + mutex_unlock(&o2nm_cluster_group.cs_subsys.su_mutex); |
2600 | +} |
2601 | + |
2602 | int o2nm_depend_item(struct config_item *item) |
2603 | { |
2604 | return configfs_depend_item(&o2nm_cluster_group.cs_subsys, item); |
2605 | diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c |
2606 | index 4f3f928076f3..92470e5973f8 100644 |
2607 | --- a/fs/reiserfs/prints.c |
2608 | +++ b/fs/reiserfs/prints.c |
2609 | @@ -76,83 +76,99 @@ static char *le_type(struct reiserfs_key *key) |
2610 | } |
2611 | |
2612 | /* %k */ |
2613 | -static void sprintf_le_key(char *buf, struct reiserfs_key *key) |
2614 | +static int scnprintf_le_key(char *buf, size_t size, struct reiserfs_key *key) |
2615 | { |
2616 | if (key) |
2617 | - sprintf(buf, "[%d %d %s %s]", le32_to_cpu(key->k_dir_id), |
2618 | - le32_to_cpu(key->k_objectid), le_offset(key), |
2619 | - le_type(key)); |
2620 | + return scnprintf(buf, size, "[%d %d %s %s]", |
2621 | + le32_to_cpu(key->k_dir_id), |
2622 | + le32_to_cpu(key->k_objectid), le_offset(key), |
2623 | + le_type(key)); |
2624 | else |
2625 | - sprintf(buf, "[NULL]"); |
2626 | + return scnprintf(buf, size, "[NULL]"); |
2627 | } |
2628 | |
2629 | /* %K */ |
2630 | -static void sprintf_cpu_key(char *buf, struct cpu_key *key) |
2631 | +static int scnprintf_cpu_key(char *buf, size_t size, struct cpu_key *key) |
2632 | { |
2633 | if (key) |
2634 | - sprintf(buf, "[%d %d %s %s]", key->on_disk_key.k_dir_id, |
2635 | - key->on_disk_key.k_objectid, reiserfs_cpu_offset(key), |
2636 | - cpu_type(key)); |
2637 | + return scnprintf(buf, size, "[%d %d %s %s]", |
2638 | + key->on_disk_key.k_dir_id, |
2639 | + key->on_disk_key.k_objectid, |
2640 | + reiserfs_cpu_offset(key), cpu_type(key)); |
2641 | else |
2642 | - sprintf(buf, "[NULL]"); |
2643 | + return scnprintf(buf, size, "[NULL]"); |
2644 | } |
2645 | |
2646 | -static void sprintf_de_head(char *buf, struct reiserfs_de_head *deh) |
2647 | +static int scnprintf_de_head(char *buf, size_t size, |
2648 | + struct reiserfs_de_head *deh) |
2649 | { |
2650 | if (deh) |
2651 | - sprintf(buf, |
2652 | - "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]", |
2653 | - deh_offset(deh), deh_dir_id(deh), deh_objectid(deh), |
2654 | - deh_location(deh), deh_state(deh)); |
2655 | + return scnprintf(buf, size, |
2656 | + "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]", |
2657 | + deh_offset(deh), deh_dir_id(deh), |
2658 | + deh_objectid(deh), deh_location(deh), |
2659 | + deh_state(deh)); |
2660 | else |
2661 | - sprintf(buf, "[NULL]"); |
2662 | + return scnprintf(buf, size, "[NULL]"); |
2663 | |
2664 | } |
2665 | |
2666 | -static void sprintf_item_head(char *buf, struct item_head *ih) |
2667 | +static int scnprintf_item_head(char *buf, size_t size, struct item_head *ih) |
2668 | { |
2669 | if (ih) { |
2670 | - strcpy(buf, |
2671 | - (ih_version(ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*"); |
2672 | - sprintf_le_key(buf + strlen(buf), &(ih->ih_key)); |
2673 | - sprintf(buf + strlen(buf), ", item_len %d, item_location %d, " |
2674 | - "free_space(entry_count) %d", |
2675 | - ih_item_len(ih), ih_location(ih), ih_free_space(ih)); |
2676 | + char *p = buf; |
2677 | + char * const end = buf + size; |
2678 | + |
2679 | + p += scnprintf(p, end - p, "%s", |
2680 | + (ih_version(ih) == KEY_FORMAT_3_6) ? |
2681 | + "*3.6* " : "*3.5*"); |
2682 | + |
2683 | + p += scnprintf_le_key(p, end - p, &ih->ih_key); |
2684 | + |
2685 | + p += scnprintf(p, end - p, |
2686 | + ", item_len %d, item_location %d, free_space(entry_count) %d", |
2687 | + ih_item_len(ih), ih_location(ih), |
2688 | + ih_free_space(ih)); |
2689 | + return p - buf; |
2690 | } else |
2691 | - sprintf(buf, "[NULL]"); |
2692 | + return scnprintf(buf, size, "[NULL]"); |
2693 | } |
2694 | |
2695 | -static void sprintf_direntry(char *buf, struct reiserfs_dir_entry *de) |
2696 | +static int scnprintf_direntry(char *buf, size_t size, |
2697 | + struct reiserfs_dir_entry *de) |
2698 | { |
2699 | char name[20]; |
2700 | |
2701 | memcpy(name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen); |
2702 | name[de->de_namelen > 19 ? 19 : de->de_namelen] = 0; |
2703 | - sprintf(buf, "\"%s\"==>[%d %d]", name, de->de_dir_id, de->de_objectid); |
2704 | + return scnprintf(buf, size, "\"%s\"==>[%d %d]", |
2705 | + name, de->de_dir_id, de->de_objectid); |
2706 | } |
2707 | |
2708 | -static void sprintf_block_head(char *buf, struct buffer_head *bh) |
2709 | +static int scnprintf_block_head(char *buf, size_t size, struct buffer_head *bh) |
2710 | { |
2711 | - sprintf(buf, "level=%d, nr_items=%d, free_space=%d rdkey ", |
2712 | - B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh)); |
2713 | + return scnprintf(buf, size, |
2714 | + "level=%d, nr_items=%d, free_space=%d rdkey ", |
2715 | + B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh)); |
2716 | } |
2717 | |
2718 | -static void sprintf_buffer_head(char *buf, struct buffer_head *bh) |
2719 | +static int scnprintf_buffer_head(char *buf, size_t size, struct buffer_head *bh) |
2720 | { |
2721 | - sprintf(buf, |
2722 | - "dev %pg, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)", |
2723 | - bh->b_bdev, bh->b_size, |
2724 | - (unsigned long long)bh->b_blocknr, atomic_read(&(bh->b_count)), |
2725 | - bh->b_state, bh->b_page, |
2726 | - buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE", |
2727 | - buffer_dirty(bh) ? "DIRTY" : "CLEAN", |
2728 | - buffer_locked(bh) ? "LOCKED" : "UNLOCKED"); |
2729 | + return scnprintf(buf, size, |
2730 | + "dev %pg, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)", |
2731 | + bh->b_bdev, bh->b_size, |
2732 | + (unsigned long long)bh->b_blocknr, |
2733 | + atomic_read(&(bh->b_count)), |
2734 | + bh->b_state, bh->b_page, |
2735 | + buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE", |
2736 | + buffer_dirty(bh) ? "DIRTY" : "CLEAN", |
2737 | + buffer_locked(bh) ? "LOCKED" : "UNLOCKED"); |
2738 | } |
2739 | |
2740 | -static void sprintf_disk_child(char *buf, struct disk_child *dc) |
2741 | +static int scnprintf_disk_child(char *buf, size_t size, struct disk_child *dc) |
2742 | { |
2743 | - sprintf(buf, "[dc_number=%d, dc_size=%u]", dc_block_number(dc), |
2744 | - dc_size(dc)); |
2745 | + return scnprintf(buf, size, "[dc_number=%d, dc_size=%u]", |
2746 | + dc_block_number(dc), dc_size(dc)); |
2747 | } |
2748 | |
2749 | static char *is_there_reiserfs_struct(char *fmt, int *what) |
2750 | @@ -189,55 +205,60 @@ static void prepare_error_buf(const char *fmt, va_list args) |
2751 | char *fmt1 = fmt_buf; |
2752 | char *k; |
2753 | char *p = error_buf; |
2754 | + char * const end = &error_buf[sizeof(error_buf)]; |
2755 | int what; |
2756 | |
2757 | spin_lock(&error_lock); |
2758 | |
2759 | - strcpy(fmt1, fmt); |
2760 | + if (WARN_ON(strscpy(fmt_buf, fmt, sizeof(fmt_buf)) < 0)) { |
2761 | + strscpy(error_buf, "format string too long", end - error_buf); |
2762 | + goto out_unlock; |
2763 | + } |
2764 | |
2765 | while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) { |
2766 | *k = 0; |
2767 | |
2768 | - p += vsprintf(p, fmt1, args); |
2769 | + p += vscnprintf(p, end - p, fmt1, args); |
2770 | |
2771 | switch (what) { |
2772 | case 'k': |
2773 | - sprintf_le_key(p, va_arg(args, struct reiserfs_key *)); |
2774 | + p += scnprintf_le_key(p, end - p, |
2775 | + va_arg(args, struct reiserfs_key *)); |
2776 | break; |
2777 | case 'K': |
2778 | - sprintf_cpu_key(p, va_arg(args, struct cpu_key *)); |
2779 | + p += scnprintf_cpu_key(p, end - p, |
2780 | + va_arg(args, struct cpu_key *)); |
2781 | break; |
2782 | case 'h': |
2783 | - sprintf_item_head(p, va_arg(args, struct item_head *)); |
2784 | + p += scnprintf_item_head(p, end - p, |
2785 | + va_arg(args, struct item_head *)); |
2786 | break; |
2787 | case 't': |
2788 | - sprintf_direntry(p, |
2789 | - va_arg(args, |
2790 | - struct reiserfs_dir_entry *)); |
2791 | + p += scnprintf_direntry(p, end - p, |
2792 | + va_arg(args, struct reiserfs_dir_entry *)); |
2793 | break; |
2794 | case 'y': |
2795 | - sprintf_disk_child(p, |
2796 | - va_arg(args, struct disk_child *)); |
2797 | + p += scnprintf_disk_child(p, end - p, |
2798 | + va_arg(args, struct disk_child *)); |
2799 | break; |
2800 | case 'z': |
2801 | - sprintf_block_head(p, |
2802 | - va_arg(args, struct buffer_head *)); |
2803 | + p += scnprintf_block_head(p, end - p, |
2804 | + va_arg(args, struct buffer_head *)); |
2805 | break; |
2806 | case 'b': |
2807 | - sprintf_buffer_head(p, |
2808 | - va_arg(args, struct buffer_head *)); |
2809 | + p += scnprintf_buffer_head(p, end - p, |
2810 | + va_arg(args, struct buffer_head *)); |
2811 | break; |
2812 | case 'a': |
2813 | - sprintf_de_head(p, |
2814 | - va_arg(args, |
2815 | - struct reiserfs_de_head *)); |
2816 | + p += scnprintf_de_head(p, end - p, |
2817 | + va_arg(args, struct reiserfs_de_head *)); |
2818 | break; |
2819 | } |
2820 | |
2821 | - p += strlen(p); |
2822 | fmt1 = k + 2; |
2823 | } |
2824 | - vsprintf(p, fmt1, args); |
2825 | + p += vscnprintf(p, end - p, fmt1, args); |
2826 | +out_unlock: |
2827 | spin_unlock(&error_lock); |
2828 | |
2829 | } |
2830 | diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h |
2831 | index a031897fca76..ca1d2cc2cdfa 100644 |
2832 | --- a/include/linux/arm-smccc.h |
2833 | +++ b/include/linux/arm-smccc.h |
2834 | @@ -80,6 +80,11 @@ |
2835 | ARM_SMCCC_SMC_32, \ |
2836 | 0, 0x8000) |
2837 | |
2838 | +#define ARM_SMCCC_ARCH_WORKAROUND_2 \ |
2839 | + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ |
2840 | + ARM_SMCCC_SMC_32, \ |
2841 | + 0, 0x7fff) |
2842 | + |
2843 | #ifndef __ASSEMBLY__ |
2844 | |
2845 | #include <linux/linkage.h> |
2846 | @@ -291,5 +296,10 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, |
2847 | */ |
2848 | #define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__) |
2849 | |
2850 | +/* Return codes defined in ARM DEN 0070A */ |
2851 | +#define SMCCC_RET_SUCCESS 0 |
2852 | +#define SMCCC_RET_NOT_SUPPORTED -1 |
2853 | +#define SMCCC_RET_NOT_REQUIRED -2 |
2854 | + |
2855 | #endif /*__ASSEMBLY__*/ |
2856 | #endif /*__LINUX_ARM_SMCCC_H*/ |
2857 | diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h |
2858 | index ad793c69cc46..8e82e3373eaf 100644 |
2859 | --- a/include/linux/compiler-gcc.h |
2860 | +++ b/include/linux/compiler-gcc.h |
2861 | @@ -64,22 +64,41 @@ |
2862 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) |
2863 | #endif |
2864 | |
2865 | +/* |
2866 | + * Feature detection for gnu_inline (gnu89 extern inline semantics). Either |
2867 | + * __GNUC_STDC_INLINE__ is defined (not using gnu89 extern inline semantics, |
2868 | + * and we opt in to the gnu89 semantics), or __GNUC_STDC_INLINE__ is not |
2869 | + * defined so the gnu89 semantics are the default. |
2870 | + */ |
2871 | +#ifdef __GNUC_STDC_INLINE__ |
2872 | +# define __gnu_inline __attribute__((gnu_inline)) |
2873 | +#else |
2874 | +# define __gnu_inline |
2875 | +#endif |
2876 | + |
2877 | /* |
2878 | * Force always-inline if the user requests it so via the .config, |
2879 | - * or if gcc is too old: |
2880 | + * or if gcc is too old. |
2881 | + * GCC does not warn about unused static inline functions for |
2882 | + * -Wunused-function. This turns out to avoid the need for complex #ifdef |
2883 | + * directives. Suppress the warning in clang as well by using "unused" |
2884 | + * function attribute, which is redundant but not harmful for gcc. |
2885 | + * Prefer gnu_inline, so that extern inline functions do not emit an |
2886 | + * externally visible function. This makes extern inline behave as per gnu89 |
2887 | + * semantics rather than c99. This prevents multiple symbol definition errors |
2888 | + * of extern inline functions at link time. |
2889 | + * A lot of inline functions can cause havoc with function tracing. |
2890 | */ |
2891 | #if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ |
2892 | !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4) |
2893 | -#define inline inline __attribute__((always_inline)) notrace |
2894 | -#define __inline__ __inline__ __attribute__((always_inline)) notrace |
2895 | -#define __inline __inline __attribute__((always_inline)) notrace |
2896 | +#define inline \ |
2897 | + inline __attribute__((always_inline, unused)) notrace __gnu_inline |
2898 | #else |
2899 | -/* A lot of inline functions can cause havoc with function tracing */ |
2900 | -#define inline inline notrace |
2901 | -#define __inline__ __inline__ notrace |
2902 | -#define __inline __inline notrace |
2903 | +#define inline inline __attribute__((unused)) notrace __gnu_inline |
2904 | #endif |
2905 | |
2906 | +#define __inline__ inline |
2907 | +#define __inline inline |
2908 | #define __always_inline inline __attribute__((always_inline)) |
2909 | #define noinline __attribute__((noinline)) |
2910 | |
2911 | diff --git a/include/linux/string.h b/include/linux/string.h |
2912 | index 0c88c0a1a72b..60042e5e88ff 100644 |
2913 | --- a/include/linux/string.h |
2914 | +++ b/include/linux/string.h |
2915 | @@ -27,7 +27,7 @@ extern char * strncpy(char *,const char *, __kernel_size_t); |
2916 | size_t strlcpy(char *, const char *, size_t); |
2917 | #endif |
2918 | #ifndef __HAVE_ARCH_STRSCPY |
2919 | -ssize_t __must_check strscpy(char *, const char *, size_t); |
2920 | +ssize_t strscpy(char *, const char *, size_t); |
2921 | #endif |
2922 | #ifndef __HAVE_ARCH_STRCAT |
2923 | extern char * strcat(char *, const char *); |
2924 | diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c |
2925 | index cb6fbb525ba6..18c1f07e4f3b 100644 |
2926 | --- a/net/bridge/netfilter/ebtables.c |
2927 | +++ b/net/bridge/netfilter/ebtables.c |
2928 | @@ -406,6 +406,12 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par, |
2929 | watcher = xt_request_find_target(NFPROTO_BRIDGE, w->u.name, 0); |
2930 | if (IS_ERR(watcher)) |
2931 | return PTR_ERR(watcher); |
2932 | + |
2933 | + if (watcher->family != NFPROTO_BRIDGE) { |
2934 | + module_put(watcher->me); |
2935 | + return -ENOENT; |
2936 | + } |
2937 | + |
2938 | w->u.watcher = watcher; |
2939 | |
2940 | par->target = watcher; |
2941 | @@ -727,6 +733,13 @@ ebt_check_entry(struct ebt_entry *e, struct net *net, |
2942 | goto cleanup_watchers; |
2943 | } |
2944 | |
2945 | + /* Reject UNSPEC, xtables verdicts/return values are incompatible */ |
2946 | + if (target->family != NFPROTO_BRIDGE) { |
2947 | + module_put(target->me); |
2948 | + ret = -ENOENT; |
2949 | + goto cleanup_watchers; |
2950 | + } |
2951 | + |
2952 | t->u.target = target; |
2953 | if (t->u.target == &ebt_standard_target) { |
2954 | if (gap < sizeof(struct ebt_standard_target)) { |
2955 | diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c |
2956 | index 119c04317d48..03fcf3ee1534 100644 |
2957 | --- a/net/dccp/ccids/ccid3.c |
2958 | +++ b/net/dccp/ccids/ccid3.c |
2959 | @@ -599,7 +599,7 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk, |
2960 | { |
2961 | struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); |
2962 | struct dccp_sock *dp = dccp_sk(sk); |
2963 | - ktime_t now = ktime_get_real(); |
2964 | + ktime_t now = ktime_get(); |
2965 | s64 delta = 0; |
2966 | |
2967 | switch (fbtype) { |
2968 | @@ -624,15 +624,14 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk, |
2969 | case CCID3_FBACK_PERIODIC: |
2970 | delta = ktime_us_delta(now, hc->rx_tstamp_last_feedback); |
2971 | if (delta <= 0) |
2972 | - DCCP_BUG("delta (%ld) <= 0", (long)delta); |
2973 | - else |
2974 | - hc->rx_x_recv = scaled_div32(hc->rx_bytes_recv, delta); |
2975 | + delta = 1; |
2976 | + hc->rx_x_recv = scaled_div32(hc->rx_bytes_recv, delta); |
2977 | break; |
2978 | default: |
2979 | return; |
2980 | } |
2981 | |
2982 | - ccid3_pr_debug("Interval %ldusec, X_recv=%u, 1/p=%u\n", (long)delta, |
2983 | + ccid3_pr_debug("Interval %lldusec, X_recv=%u, 1/p=%u\n", delta, |
2984 | hc->rx_x_recv, hc->rx_pinv); |
2985 | |
2986 | hc->rx_tstamp_last_feedback = now; |
2987 | @@ -679,7 +678,8 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) |
2988 | static u32 ccid3_first_li(struct sock *sk) |
2989 | { |
2990 | struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); |
2991 | - u32 x_recv, p, delta; |
2992 | + u32 x_recv, p; |
2993 | + s64 delta; |
2994 | u64 fval; |
2995 | |
2996 | if (hc->rx_rtt == 0) { |
2997 | @@ -687,7 +687,9 @@ static u32 ccid3_first_li(struct sock *sk) |
2998 | hc->rx_rtt = DCCP_FALLBACK_RTT; |
2999 | } |
3000 | |
3001 | - delta = ktime_to_us(net_timedelta(hc->rx_tstamp_last_feedback)); |
3002 | + delta = ktime_us_delta(ktime_get(), hc->rx_tstamp_last_feedback); |
3003 | + if (delta <= 0) |
3004 | + delta = 1; |
3005 | x_recv = scaled_div32(hc->rx_bytes_recv, delta); |
3006 | if (x_recv == 0) { /* would also trigger divide-by-zero */ |
3007 | DCCP_WARN("X_recv==0\n"); |
3008 | diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c |
3009 | index f0252768ecf4..5f5d9eafccf5 100644 |
3010 | --- a/net/dns_resolver/dns_key.c |
3011 | +++ b/net/dns_resolver/dns_key.c |
3012 | @@ -87,35 +87,39 @@ dns_resolver_preparse(struct key_preparsed_payload *prep) |
3013 | opt++; |
3014 | kdebug("options: '%s'", opt); |
3015 | do { |
3016 | + int opt_len, opt_nlen; |
3017 | const char *eq; |
3018 | - int opt_len, opt_nlen, opt_vlen, tmp; |
3019 | + char optval[128]; |
3020 | |
3021 | next_opt = memchr(opt, '#', end - opt) ?: end; |
3022 | opt_len = next_opt - opt; |
3023 | - if (opt_len <= 0 || opt_len > 128) { |
3024 | + if (opt_len <= 0 || opt_len > sizeof(optval)) { |
3025 | pr_warn_ratelimited("Invalid option length (%d) for dns_resolver key\n", |
3026 | opt_len); |
3027 | return -EINVAL; |
3028 | } |
3029 | |
3030 | - eq = memchr(opt, '=', opt_len) ?: end; |
3031 | - opt_nlen = eq - opt; |
3032 | - eq++; |
3033 | - opt_vlen = next_opt - eq; /* will be -1 if no value */ |
3034 | + eq = memchr(opt, '=', opt_len); |
3035 | + if (eq) { |
3036 | + opt_nlen = eq - opt; |
3037 | + eq++; |
3038 | + memcpy(optval, eq, next_opt - eq); |
3039 | + optval[next_opt - eq] = '\0'; |
3040 | + } else { |
3041 | + opt_nlen = opt_len; |
3042 | + optval[0] = '\0'; |
3043 | + } |
3044 | |
3045 | - tmp = opt_vlen >= 0 ? opt_vlen : 0; |
3046 | - kdebug("option '%*.*s' val '%*.*s'", |
3047 | - opt_nlen, opt_nlen, opt, tmp, tmp, eq); |
3048 | + kdebug("option '%*.*s' val '%s'", |
3049 | + opt_nlen, opt_nlen, opt, optval); |
3050 | |
3051 | /* see if it's an error number representing a DNS error |
3052 | * that's to be recorded as the result in this key */ |
3053 | if (opt_nlen == sizeof(DNS_ERRORNO_OPTION) - 1 && |
3054 | memcmp(opt, DNS_ERRORNO_OPTION, opt_nlen) == 0) { |
3055 | kdebug("dns error number option"); |
3056 | - if (opt_vlen <= 0) |
3057 | - goto bad_option_value; |
3058 | |
3059 | - ret = kstrtoul(eq, 10, &derrno); |
3060 | + ret = kstrtoul(optval, 10, &derrno); |
3061 | if (ret < 0) |
3062 | goto bad_option_value; |
3063 | |
3064 | diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c |
3065 | index 566cfc50f7cf..51a0039cb318 100644 |
3066 | --- a/net/ipv4/sysctl_net_ipv4.c |
3067 | +++ b/net/ipv4/sysctl_net_ipv4.c |
3068 | @@ -212,8 +212,9 @@ static int proc_tcp_fastopen_key(struct ctl_table *ctl, int write, |
3069 | { |
3070 | struct ctl_table tbl = { .maxlen = (TCP_FASTOPEN_KEY_LENGTH * 2 + 10) }; |
3071 | struct tcp_fastopen_context *ctxt; |
3072 | - int ret; |
3073 | u32 user_key[4]; /* 16 bytes, matching TCP_FASTOPEN_KEY_LENGTH */ |
3074 | + __le32 key[4]; |
3075 | + int ret, i; |
3076 | |
3077 | tbl.data = kmalloc(tbl.maxlen, GFP_KERNEL); |
3078 | if (!tbl.data) |
3079 | @@ -222,11 +223,14 @@ static int proc_tcp_fastopen_key(struct ctl_table *ctl, int write, |
3080 | rcu_read_lock(); |
3081 | ctxt = rcu_dereference(tcp_fastopen_ctx); |
3082 | if (ctxt) |
3083 | - memcpy(user_key, ctxt->key, TCP_FASTOPEN_KEY_LENGTH); |
3084 | + memcpy(key, ctxt->key, TCP_FASTOPEN_KEY_LENGTH); |
3085 | else |
3086 | - memset(user_key, 0, sizeof(user_key)); |
3087 | + memset(key, 0, sizeof(key)); |
3088 | rcu_read_unlock(); |
3089 | |
3090 | + for (i = 0; i < ARRAY_SIZE(key); i++) |
3091 | + user_key[i] = le32_to_cpu(key[i]); |
3092 | + |
3093 | snprintf(tbl.data, tbl.maxlen, "%08x-%08x-%08x-%08x", |
3094 | user_key[0], user_key[1], user_key[2], user_key[3]); |
3095 | ret = proc_dostring(&tbl, write, buffer, lenp, ppos); |
3096 | @@ -242,12 +246,16 @@ static int proc_tcp_fastopen_key(struct ctl_table *ctl, int write, |
3097 | * first invocation of tcp_fastopen_cookie_gen |
3098 | */ |
3099 | tcp_fastopen_init_key_once(false); |
3100 | - tcp_fastopen_reset_cipher(user_key, TCP_FASTOPEN_KEY_LENGTH); |
3101 | + |
3102 | + for (i = 0; i < ARRAY_SIZE(user_key); i++) |
3103 | + key[i] = cpu_to_le32(user_key[i]); |
3104 | + |
3105 | + tcp_fastopen_reset_cipher(key, TCP_FASTOPEN_KEY_LENGTH); |
3106 | } |
3107 | |
3108 | bad_key: |
3109 | pr_debug("proc FO key set 0x%x-%x-%x-%x <- 0x%s: %u\n", |
3110 | - user_key[0], user_key[1], user_key[2], user_key[3], |
3111 | + user_key[0], user_key[1], user_key[2], user_key[3], |
3112 | (char *)tbl.data, ret); |
3113 | kfree(tbl.data); |
3114 | return ret; |
3115 | diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c |
3116 | index 8999e25fd0e1..be453aa8fce8 100644 |
3117 | --- a/net/ipv4/tcp_input.c |
3118 | +++ b/net/ipv4/tcp_input.c |
3119 | @@ -3236,6 +3236,15 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, |
3120 | |
3121 | if (tcp_is_reno(tp)) { |
3122 | tcp_remove_reno_sacks(sk, pkts_acked); |
3123 | + |
3124 | + /* If any of the cumulatively ACKed segments was |
3125 | + * retransmitted, non-SACK case cannot confirm that |
3126 | + * progress was due to original transmission due to |
3127 | + * lack of TCPCB_SACKED_ACKED bits even if some of |
3128 | + * the packets may have been never retransmitted. |
3129 | + */ |
3130 | + if (flag & FLAG_RETRANS_DATA_ACKED) |
3131 | + flag &= ~FLAG_ORIG_SACK_ACKED; |
3132 | } else { |
3133 | int delta; |
3134 | |
3135 | diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c |
3136 | index 64ec23388450..722a9db8c6a7 100644 |
3137 | --- a/net/ipv6/netfilter/nf_conntrack_reasm.c |
3138 | +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c |
3139 | @@ -618,6 +618,8 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) |
3140 | fq->q.meat == fq->q.len && |
3141 | nf_ct_frag6_reasm(fq, skb, dev)) |
3142 | ret = 0; |
3143 | + else |
3144 | + skb_dst_drop(skb); |
3145 | |
3146 | out_unlock: |
3147 | spin_unlock_bh(&fq->q.lock); |
3148 | diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c |
3149 | index 3f266115294f..04759a0c3273 100644 |
3150 | --- a/net/nfc/llcp_commands.c |
3151 | +++ b/net/nfc/llcp_commands.c |
3152 | @@ -753,11 +753,14 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, |
3153 | pr_debug("Fragment %zd bytes remaining %zd", |
3154 | frag_len, remaining_len); |
3155 | |
3156 | - pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT, |
3157 | + pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, 0, |
3158 | frag_len + LLCP_HEADER_SIZE, &err); |
3159 | if (pdu == NULL) { |
3160 | - pr_err("Could not allocate PDU\n"); |
3161 | - continue; |
3162 | + pr_err("Could not allocate PDU (error=%d)\n", err); |
3163 | + len -= remaining_len; |
3164 | + if (len == 0) |
3165 | + len = err; |
3166 | + break; |
3167 | } |
3168 | |
3169 | pdu = llcp_add_header(pdu, dsap, ssap, LLCP_PDU_UI); |
3170 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c |
3171 | index 2c4a47f29f36..ea601f7ca2f8 100644 |
3172 | --- a/net/packet/af_packet.c |
3173 | +++ b/net/packet/af_packet.c |
3174 | @@ -2265,6 +2265,12 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, |
3175 | if (po->stats.stats1.tp_drops) |
3176 | status |= TP_STATUS_LOSING; |
3177 | } |
3178 | + |
3179 | + if (do_vnet && |
3180 | + __packet_rcv_vnet(skb, h.raw + macoff - |
3181 | + sizeof(struct virtio_net_hdr))) |
3182 | + goto drop_n_account; |
3183 | + |
3184 | po->stats.stats1.tp_packets++; |
3185 | if (copy_skb) { |
3186 | status |= TP_STATUS_COPY; |
3187 | @@ -2272,14 +2278,6 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, |
3188 | } |
3189 | spin_unlock(&sk->sk_receive_queue.lock); |
3190 | |
3191 | - if (do_vnet) { |
3192 | - if (__packet_rcv_vnet(skb, h.raw + macoff - |
3193 | - sizeof(struct virtio_net_hdr))) { |
3194 | - spin_lock(&sk->sk_receive_queue.lock); |
3195 | - goto drop_n_account; |
3196 | - } |
3197 | - } |
3198 | - |
3199 | skb_copy_bits(skb, 0, h.raw + macoff, snaplen); |
3200 | |
3201 | if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp))) |
3202 | diff --git a/net/rds/loop.c b/net/rds/loop.c |
3203 | index f2bf78de5688..dac6218a460e 100644 |
3204 | --- a/net/rds/loop.c |
3205 | +++ b/net/rds/loop.c |
3206 | @@ -193,4 +193,5 @@ struct rds_transport rds_loop_transport = { |
3207 | .inc_copy_to_user = rds_message_inc_copy_to_user, |
3208 | .inc_free = rds_loop_inc_free, |
3209 | .t_name = "loopback", |
3210 | + .t_type = RDS_TRANS_LOOP, |
3211 | }; |
3212 | diff --git a/net/rds/rds.h b/net/rds/rds.h |
3213 | index 30a51fec0f63..edfc3397aa24 100644 |
3214 | --- a/net/rds/rds.h |
3215 | +++ b/net/rds/rds.h |
3216 | @@ -440,6 +440,11 @@ struct rds_notifier { |
3217 | int n_status; |
3218 | }; |
3219 | |
3220 | +/* Available as part of RDS core, so doesn't need to participate |
3221 | + * in get_preferred transport etc |
3222 | + */ |
3223 | +#define RDS_TRANS_LOOP 3 |
3224 | + |
3225 | /** |
3226 | * struct rds_transport - transport specific behavioural hooks |
3227 | * |
3228 | diff --git a/net/rds/recv.c b/net/rds/recv.c |
3229 | index cbfabdf3ff48..f16ee1b13b8d 100644 |
3230 | --- a/net/rds/recv.c |
3231 | +++ b/net/rds/recv.c |
3232 | @@ -94,6 +94,11 @@ static void rds_recv_rcvbuf_delta(struct rds_sock *rs, struct sock *sk, |
3233 | return; |
3234 | |
3235 | rs->rs_rcv_bytes += delta; |
3236 | + |
3237 | + /* loop transport doesn't send/recv congestion updates */ |
3238 | + if (rs->rs_transport->t_type == RDS_TRANS_LOOP) |
3239 | + return; |
3240 | + |
3241 | now_congested = rs->rs_rcv_bytes > rds_sk_rcvbuf(rs); |
3242 | |
3243 | rdsdebug("rs %p (%pI4:%u) recv bytes %d buf %d " |
3244 | diff --git a/net/sched/sch_blackhole.c b/net/sched/sch_blackhole.c |
3245 | index c98a61e980ba..9c4c2bb547d7 100644 |
3246 | --- a/net/sched/sch_blackhole.c |
3247 | +++ b/net/sched/sch_blackhole.c |
3248 | @@ -21,7 +21,7 @@ static int blackhole_enqueue(struct sk_buff *skb, struct Qdisc *sch, |
3249 | struct sk_buff **to_free) |
3250 | { |
3251 | qdisc_drop(skb, sch, to_free); |
3252 | - return NET_XMIT_SUCCESS; |
3253 | + return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; |
3254 | } |
3255 | |
3256 | static struct sk_buff *blackhole_dequeue(struct Qdisc *sch) |
3257 | diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c |
3258 | index 95021246ee26..3d6dbdf850aa 100644 |
3259 | --- a/virt/kvm/arm/hyp/vgic-v2-sr.c |
3260 | +++ b/virt/kvm/arm/hyp/vgic-v2-sr.c |
3261 | @@ -203,7 +203,7 @@ int __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu) |
3262 | return -1; |
3263 | |
3264 | rd = kvm_vcpu_dabt_get_rd(vcpu); |
3265 | - addr = kern_hyp_va((kern_hyp_va(&kvm_vgic_global_state))->vcpu_base_va); |
3266 | + addr = kern_hyp_va(hyp_symbol_addr(kvm_vgic_global_state)->vcpu_base_va); |
3267 | addr += fault_ipa - vgic->vgic_cpu_base; |
3268 | |
3269 | if (kvm_vcpu_dabt_iswrite(vcpu)) { |