Contents of /trunk/kernel-alx-legacy/patches-4.9/0268-4.9.169-all-fixes.patch
Parent Directory | Revision Log
Revision 3608 -
(show annotations)
(download)
Fri Aug 14 07:34:29 2020 UTC (4 years, 1 month ago) by niro
File size: 97398 byte(s)
Fri Aug 14 07:34:29 2020 UTC (4 years, 1 month ago) by niro
File size: 97398 byte(s)
-added kerenl-alx-legacy pkg
1 | diff --git a/Makefile b/Makefile |
2 | index f44094d2b147..23cc23c47adf 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1,6 +1,6 @@ |
6 | VERSION = 4 |
7 | PATCHLEVEL = 9 |
8 | -SUBLEVEL = 168 |
9 | +SUBLEVEL = 169 |
10 | EXTRAVERSION = |
11 | NAME = Roaring Lionus |
12 | |
13 | @@ -507,7 +507,7 @@ endif |
14 | ifeq ($(cc-name),clang) |
15 | ifneq ($(CROSS_COMPILE),) |
16 | CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE:%-=%)) |
17 | -GCC_TOOLCHAIN_DIR := $(dir $(shell which $(LD))) |
18 | +GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) |
19 | CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR) |
20 | GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..) |
21 | endif |
22 | diff --git a/arch/arm/boot/dts/sama5d2-pinfunc.h b/arch/arm/boot/dts/sama5d2-pinfunc.h |
23 | index 8a394f336003..ee65702f9645 100644 |
24 | --- a/arch/arm/boot/dts/sama5d2-pinfunc.h |
25 | +++ b/arch/arm/boot/dts/sama5d2-pinfunc.h |
26 | @@ -517,7 +517,7 @@ |
27 | #define PIN_PC9__GPIO PINMUX_PIN(PIN_PC9, 0, 0) |
28 | #define PIN_PC9__FIQ PINMUX_PIN(PIN_PC9, 1, 3) |
29 | #define PIN_PC9__GTSUCOMP PINMUX_PIN(PIN_PC9, 2, 1) |
30 | -#define PIN_PC9__ISC_D0 PINMUX_PIN(PIN_PC9, 2, 1) |
31 | +#define PIN_PC9__ISC_D0 PINMUX_PIN(PIN_PC9, 3, 1) |
32 | #define PIN_PC9__TIOA4 PINMUX_PIN(PIN_PC9, 4, 2) |
33 | #define PIN_PC10 74 |
34 | #define PIN_PC10__GPIO PINMUX_PIN(PIN_PC10, 0, 0) |
35 | diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h |
36 | index 2a5090fb9113..d7116f5935fb 100644 |
37 | --- a/arch/arm64/include/asm/futex.h |
38 | +++ b/arch/arm64/include/asm/futex.h |
39 | @@ -33,8 +33,8 @@ |
40 | " prfm pstl1strm, %2\n" \ |
41 | "1: ldxr %w1, %2\n" \ |
42 | insn "\n" \ |
43 | -"2: stlxr %w3, %w0, %2\n" \ |
44 | -" cbnz %w3, 1b\n" \ |
45 | +"2: stlxr %w0, %w3, %2\n" \ |
46 | +" cbnz %w0, 1b\n" \ |
47 | " dmb ish\n" \ |
48 | "3:\n" \ |
49 | " .pushsection .fixup,\"ax\"\n" \ |
50 | @@ -53,29 +53,29 @@ |
51 | static inline int |
52 | arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) |
53 | { |
54 | - int oldval = 0, ret, tmp; |
55 | + int oldval, ret, tmp; |
56 | |
57 | pagefault_disable(); |
58 | |
59 | switch (op) { |
60 | case FUTEX_OP_SET: |
61 | - __futex_atomic_op("mov %w0, %w4", |
62 | + __futex_atomic_op("mov %w3, %w4", |
63 | ret, oldval, uaddr, tmp, oparg); |
64 | break; |
65 | case FUTEX_OP_ADD: |
66 | - __futex_atomic_op("add %w0, %w1, %w4", |
67 | + __futex_atomic_op("add %w3, %w1, %w4", |
68 | ret, oldval, uaddr, tmp, oparg); |
69 | break; |
70 | case FUTEX_OP_OR: |
71 | - __futex_atomic_op("orr %w0, %w1, %w4", |
72 | + __futex_atomic_op("orr %w3, %w1, %w4", |
73 | ret, oldval, uaddr, tmp, oparg); |
74 | break; |
75 | case FUTEX_OP_ANDN: |
76 | - __futex_atomic_op("and %w0, %w1, %w4", |
77 | + __futex_atomic_op("and %w3, %w1, %w4", |
78 | ret, oldval, uaddr, tmp, ~oparg); |
79 | break; |
80 | case FUTEX_OP_XOR: |
81 | - __futex_atomic_op("eor %w0, %w1, %w4", |
82 | + __futex_atomic_op("eor %w3, %w1, %w4", |
83 | ret, oldval, uaddr, tmp, oparg); |
84 | break; |
85 | default: |
86 | diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c |
87 | index fa6b2fad7a3d..5d3df68272f5 100644 |
88 | --- a/arch/arm64/mm/init.c |
89 | +++ b/arch/arm64/mm/init.c |
90 | @@ -272,7 +272,7 @@ void __init arm64_memblock_init(void) |
91 | * memory spans, randomize the linear region as well. |
92 | */ |
93 | if (memstart_offset_seed > 0 && range >= ARM64_MEMSTART_ALIGN) { |
94 | - range = range / ARM64_MEMSTART_ALIGN + 1; |
95 | + range /= ARM64_MEMSTART_ALIGN; |
96 | memstart_addr -= ARM64_MEMSTART_ALIGN * |
97 | ((range * memstart_offset_seed) >> 16); |
98 | } |
99 | diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h |
100 | index 2e674e13e005..656984ec1958 100644 |
101 | --- a/arch/parisc/include/asm/processor.h |
102 | +++ b/arch/parisc/include/asm/processor.h |
103 | @@ -323,6 +323,8 @@ extern int _parisc_requires_coherency; |
104 | #define parisc_requires_coherency() (0) |
105 | #endif |
106 | |
107 | +extern int running_on_qemu; |
108 | + |
109 | #endif /* __ASSEMBLY__ */ |
110 | |
111 | #endif /* __ASM_PARISC_PROCESSOR_H */ |
112 | diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c |
113 | index c3a532abac03..2e5216c28bb1 100644 |
114 | --- a/arch/parisc/kernel/process.c |
115 | +++ b/arch/parisc/kernel/process.c |
116 | @@ -206,12 +206,6 @@ void __cpuidle arch_cpu_idle(void) |
117 | |
118 | static int __init parisc_idle_init(void) |
119 | { |
120 | - const char *marker; |
121 | - |
122 | - /* check QEMU/SeaBIOS marker in PAGE0 */ |
123 | - marker = (char *) &PAGE0->pad0; |
124 | - running_on_qemu = (memcmp(marker, "SeaBIOS", 8) == 0); |
125 | - |
126 | if (!running_on_qemu) |
127 | cpu_idle_poll_ctrl(1); |
128 | |
129 | diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c |
130 | index 2e66a887788e..581b0c66e521 100644 |
131 | --- a/arch/parisc/kernel/setup.c |
132 | +++ b/arch/parisc/kernel/setup.c |
133 | @@ -403,6 +403,9 @@ void start_parisc(void) |
134 | int ret, cpunum; |
135 | struct pdc_coproc_cfg coproc_cfg; |
136 | |
137 | + /* check QEMU/SeaBIOS marker in PAGE0 */ |
138 | + running_on_qemu = (memcmp(&PAGE0->pad0, "SeaBIOS", 8) == 0); |
139 | + |
140 | cpunum = smp_processor_id(); |
141 | |
142 | set_firmware_width_unlocked(); |
143 | diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c |
144 | index 47ef8fdcd382..22754e0c3bda 100644 |
145 | --- a/arch/parisc/kernel/time.c |
146 | +++ b/arch/parisc/kernel/time.c |
147 | @@ -299,7 +299,7 @@ static int __init init_cr16_clocksource(void) |
148 | * The cr16 interval timers are not syncronized across CPUs, so mark |
149 | * them unstable and lower rating on SMP systems. |
150 | */ |
151 | - if (num_online_cpus() > 1) { |
152 | + if (num_online_cpus() > 1 && !running_on_qemu) { |
153 | clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; |
154 | clocksource_cr16.rating = 0; |
155 | } |
156 | diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig |
157 | index 0a6bb48854e3..fa8f2aa88189 100644 |
158 | --- a/arch/powerpc/Kconfig |
159 | +++ b/arch/powerpc/Kconfig |
160 | @@ -128,7 +128,7 @@ config PPC |
161 | select ARCH_HAS_GCOV_PROFILE_ALL |
162 | select GENERIC_SMP_IDLE_THREAD |
163 | select GENERIC_CMOS_UPDATE |
164 | - select GENERIC_CPU_VULNERABILITIES if PPC_BOOK3S_64 |
165 | + select GENERIC_CPU_VULNERABILITIES if PPC_BARRIER_NOSPEC |
166 | select GENERIC_TIME_VSYSCALL_OLD |
167 | select GENERIC_CLOCKEVENTS |
168 | select GENERIC_CLOCKEVENTS_BROADCAST if SMP |
169 | @@ -164,6 +164,11 @@ config PPC |
170 | select HAVE_ARCH_HARDENED_USERCOPY |
171 | select HAVE_KERNEL_GZIP |
172 | |
173 | +config PPC_BARRIER_NOSPEC |
174 | + bool |
175 | + default y |
176 | + depends on PPC_BOOK3S_64 || PPC_FSL_BOOK3E |
177 | + |
178 | config GENERIC_CSUM |
179 | def_bool CPU_LITTLE_ENDIAN |
180 | |
181 | diff --git a/arch/powerpc/include/asm/asm-prototypes.h b/arch/powerpc/include/asm/asm-prototypes.h |
182 | index e0baba1535e6..f3daa175f86c 100644 |
183 | --- a/arch/powerpc/include/asm/asm-prototypes.h |
184 | +++ b/arch/powerpc/include/asm/asm-prototypes.h |
185 | @@ -121,4 +121,10 @@ extern s64 __ashrdi3(s64, int); |
186 | extern int __cmpdi2(s64, s64); |
187 | extern int __ucmpdi2(u64, u64); |
188 | |
189 | +/* Patch sites */ |
190 | +extern s32 patch__call_flush_count_cache; |
191 | +extern s32 patch__flush_count_cache_return; |
192 | + |
193 | +extern long flush_count_cache; |
194 | + |
195 | #endif /* _ASM_POWERPC_ASM_PROTOTYPES_H */ |
196 | diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h |
197 | index 798ab37c9930..80024c4f2093 100644 |
198 | --- a/arch/powerpc/include/asm/barrier.h |
199 | +++ b/arch/powerpc/include/asm/barrier.h |
200 | @@ -77,6 +77,27 @@ do { \ |
201 | |
202 | #define smp_mb__before_spinlock() smp_mb() |
203 | |
204 | +#ifdef CONFIG_PPC_BOOK3S_64 |
205 | +#define NOSPEC_BARRIER_SLOT nop |
206 | +#elif defined(CONFIG_PPC_FSL_BOOK3E) |
207 | +#define NOSPEC_BARRIER_SLOT nop; nop |
208 | +#endif |
209 | + |
210 | +#ifdef CONFIG_PPC_BARRIER_NOSPEC |
211 | +/* |
212 | + * Prevent execution of subsequent instructions until preceding branches have |
213 | + * been fully resolved and are no longer executing speculatively. |
214 | + */ |
215 | +#define barrier_nospec_asm NOSPEC_BARRIER_FIXUP_SECTION; NOSPEC_BARRIER_SLOT |
216 | + |
217 | +// This also acts as a compiler barrier due to the memory clobber. |
218 | +#define barrier_nospec() asm (stringify_in_c(barrier_nospec_asm) ::: "memory") |
219 | + |
220 | +#else /* !CONFIG_PPC_BARRIER_NOSPEC */ |
221 | +#define barrier_nospec_asm |
222 | +#define barrier_nospec() |
223 | +#endif /* CONFIG_PPC_BARRIER_NOSPEC */ |
224 | + |
225 | #include <asm-generic/barrier.h> |
226 | |
227 | #endif /* _ASM_POWERPC_BARRIER_H */ |
228 | diff --git a/arch/powerpc/include/asm/code-patching-asm.h b/arch/powerpc/include/asm/code-patching-asm.h |
229 | new file mode 100644 |
230 | index 000000000000..ed7b1448493a |
231 | --- /dev/null |
232 | +++ b/arch/powerpc/include/asm/code-patching-asm.h |
233 | @@ -0,0 +1,18 @@ |
234 | +/* SPDX-License-Identifier: GPL-2.0+ */ |
235 | +/* |
236 | + * Copyright 2018, Michael Ellerman, IBM Corporation. |
237 | + */ |
238 | +#ifndef _ASM_POWERPC_CODE_PATCHING_ASM_H |
239 | +#define _ASM_POWERPC_CODE_PATCHING_ASM_H |
240 | + |
241 | +/* Define a "site" that can be patched */ |
242 | +.macro patch_site label name |
243 | + .pushsection ".rodata" |
244 | + .balign 4 |
245 | + .global \name |
246 | +\name: |
247 | + .4byte \label - . |
248 | + .popsection |
249 | +.endm |
250 | + |
251 | +#endif /* _ASM_POWERPC_CODE_PATCHING_ASM_H */ |
252 | diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h |
253 | index b4ab1f497335..ab934f8232bd 100644 |
254 | --- a/arch/powerpc/include/asm/code-patching.h |
255 | +++ b/arch/powerpc/include/asm/code-patching.h |
256 | @@ -28,6 +28,8 @@ unsigned int create_cond_branch(const unsigned int *addr, |
257 | unsigned long target, int flags); |
258 | int patch_branch(unsigned int *addr, unsigned long target, int flags); |
259 | int patch_instruction(unsigned int *addr, unsigned int instr); |
260 | +int patch_instruction_site(s32 *addr, unsigned int instr); |
261 | +int patch_branch_site(s32 *site, unsigned long target, int flags); |
262 | |
263 | int instr_is_relative_branch(unsigned int instr); |
264 | int instr_is_relative_link_branch(unsigned int instr); |
265 | diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h |
266 | index 0bf8202feca6..175128e19025 100644 |
267 | --- a/arch/powerpc/include/asm/feature-fixups.h |
268 | +++ b/arch/powerpc/include/asm/feature-fixups.h |
269 | @@ -213,6 +213,25 @@ void setup_feature_keys(void); |
270 | FTR_ENTRY_OFFSET 951b-952b; \ |
271 | .popsection; |
272 | |
273 | +#define NOSPEC_BARRIER_FIXUP_SECTION \ |
274 | +953: \ |
275 | + .pushsection __barrier_nospec_fixup,"a"; \ |
276 | + .align 2; \ |
277 | +954: \ |
278 | + FTR_ENTRY_OFFSET 953b-954b; \ |
279 | + .popsection; |
280 | + |
281 | +#define START_BTB_FLUSH_SECTION \ |
282 | +955: \ |
283 | + |
284 | +#define END_BTB_FLUSH_SECTION \ |
285 | +956: \ |
286 | + .pushsection __btb_flush_fixup,"a"; \ |
287 | + .align 2; \ |
288 | +957: \ |
289 | + FTR_ENTRY_OFFSET 955b-957b; \ |
290 | + FTR_ENTRY_OFFSET 956b-957b; \ |
291 | + .popsection; |
292 | |
293 | #ifndef __ASSEMBLY__ |
294 | |
295 | @@ -220,6 +239,8 @@ extern long stf_barrier_fallback; |
296 | extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup; |
297 | extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup; |
298 | extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup; |
299 | +extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup; |
300 | +extern long __start__btb_flush_fixup, __stop__btb_flush_fixup; |
301 | |
302 | #endif |
303 | |
304 | diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h |
305 | index 9d978102bf0d..9587d301db55 100644 |
306 | --- a/arch/powerpc/include/asm/hvcall.h |
307 | +++ b/arch/powerpc/include/asm/hvcall.h |
308 | @@ -316,10 +316,12 @@ |
309 | #define H_CPU_CHAR_BRANCH_HINTS_HONORED (1ull << 58) // IBM bit 5 |
310 | #define H_CPU_CHAR_THREAD_RECONFIG_CTRL (1ull << 57) // IBM bit 6 |
311 | #define H_CPU_CHAR_COUNT_CACHE_DISABLED (1ull << 56) // IBM bit 7 |
312 | +#define H_CPU_CHAR_BCCTR_FLUSH_ASSIST (1ull << 54) // IBM bit 9 |
313 | |
314 | #define H_CPU_BEHAV_FAVOUR_SECURITY (1ull << 63) // IBM bit 0 |
315 | #define H_CPU_BEHAV_L1D_FLUSH_PR (1ull << 62) // IBM bit 1 |
316 | #define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ull << 61) // IBM bit 2 |
317 | +#define H_CPU_BEHAV_FLUSH_COUNT_CACHE (1ull << 58) // IBM bit 5 |
318 | |
319 | #ifndef __ASSEMBLY__ |
320 | #include <linux/types.h> |
321 | diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h |
322 | index c73750b0d9fa..bbd35ba36a22 100644 |
323 | --- a/arch/powerpc/include/asm/ppc_asm.h |
324 | +++ b/arch/powerpc/include/asm/ppc_asm.h |
325 | @@ -437,7 +437,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) |
326 | .machine push ; \ |
327 | .machine "power4" ; \ |
328 | lis scratch,0x60000000@h; \ |
329 | - dcbt r0,scratch,0b01010; \ |
330 | + dcbt 0,scratch,0b01010; \ |
331 | .machine pop |
332 | |
333 | /* |
334 | @@ -780,4 +780,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) |
335 | .long 0x2400004c /* rfid */ |
336 | #endif /* !CONFIG_PPC_BOOK3E */ |
337 | #endif /* __ASSEMBLY__ */ |
338 | + |
339 | +/* |
340 | + * Helper macro for exception table entries |
341 | + */ |
342 | +#define EX_TABLE(_fault, _target) \ |
343 | + stringify_in_c(.section __ex_table,"a";)\ |
344 | + stringify_in_c(.balign 4;) \ |
345 | + stringify_in_c(.long (_fault) - . ;) \ |
346 | + stringify_in_c(.long (_target) - . ;) \ |
347 | + stringify_in_c(.previous) |
348 | + |
349 | +#ifdef CONFIG_PPC_FSL_BOOK3E |
350 | +#define BTB_FLUSH(reg) \ |
351 | + lis reg,BUCSR_INIT@h; \ |
352 | + ori reg,reg,BUCSR_INIT@l; \ |
353 | + mtspr SPRN_BUCSR,reg; \ |
354 | + isync; |
355 | +#else |
356 | +#define BTB_FLUSH(reg) |
357 | +#endif /* CONFIG_PPC_FSL_BOOK3E */ |
358 | + |
359 | #endif /* _ASM_POWERPC_PPC_ASM_H */ |
360 | diff --git a/arch/powerpc/include/asm/security_features.h b/arch/powerpc/include/asm/security_features.h |
361 | index 44989b22383c..759597bf0fd8 100644 |
362 | --- a/arch/powerpc/include/asm/security_features.h |
363 | +++ b/arch/powerpc/include/asm/security_features.h |
364 | @@ -22,6 +22,7 @@ enum stf_barrier_type { |
365 | |
366 | void setup_stf_barrier(void); |
367 | void do_stf_barrier_fixups(enum stf_barrier_type types); |
368 | +void setup_count_cache_flush(void); |
369 | |
370 | static inline void security_ftr_set(unsigned long feature) |
371 | { |
372 | @@ -59,6 +60,9 @@ static inline bool security_ftr_enabled(unsigned long feature) |
373 | // Indirect branch prediction cache disabled |
374 | #define SEC_FTR_COUNT_CACHE_DISABLED 0x0000000000000020ull |
375 | |
376 | +// bcctr 2,0,0 triggers a hardware assisted count cache flush |
377 | +#define SEC_FTR_BCCTR_FLUSH_ASSIST 0x0000000000000800ull |
378 | + |
379 | |
380 | // Features indicating need for Spectre/Meltdown mitigations |
381 | |
382 | @@ -74,6 +78,9 @@ static inline bool security_ftr_enabled(unsigned long feature) |
383 | // Firmware configuration indicates user favours security over performance |
384 | #define SEC_FTR_FAVOUR_SECURITY 0x0000000000000200ull |
385 | |
386 | +// Software required to flush count cache on context switch |
387 | +#define SEC_FTR_FLUSH_COUNT_CACHE 0x0000000000000400ull |
388 | + |
389 | |
390 | // Features enabled by default |
391 | #define SEC_FTR_DEFAULT \ |
392 | diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h |
393 | index 3f160cd20107..862ebce3ae54 100644 |
394 | --- a/arch/powerpc/include/asm/setup.h |
395 | +++ b/arch/powerpc/include/asm/setup.h |
396 | @@ -8,6 +8,7 @@ extern void ppc_printk_progress(char *s, unsigned short hex); |
397 | |
398 | extern unsigned int rtas_data; |
399 | extern unsigned long long memory_limit; |
400 | +extern bool init_mem_is_free; |
401 | extern unsigned long klimit; |
402 | extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); |
403 | |
404 | @@ -50,6 +51,26 @@ enum l1d_flush_type { |
405 | |
406 | void setup_rfi_flush(enum l1d_flush_type, bool enable); |
407 | void do_rfi_flush_fixups(enum l1d_flush_type types); |
408 | +#ifdef CONFIG_PPC_BARRIER_NOSPEC |
409 | +void setup_barrier_nospec(void); |
410 | +#else |
411 | +static inline void setup_barrier_nospec(void) { }; |
412 | +#endif |
413 | +void do_barrier_nospec_fixups(bool enable); |
414 | +extern bool barrier_nospec_enabled; |
415 | + |
416 | +#ifdef CONFIG_PPC_BARRIER_NOSPEC |
417 | +void do_barrier_nospec_fixups_range(bool enable, void *start, void *end); |
418 | +#else |
419 | +static inline void do_barrier_nospec_fixups_range(bool enable, void *start, void *end) { }; |
420 | +#endif |
421 | + |
422 | +#ifdef CONFIG_PPC_FSL_BOOK3E |
423 | +void setup_spectre_v2(void); |
424 | +#else |
425 | +static inline void setup_spectre_v2(void) {}; |
426 | +#endif |
427 | +void do_btb_flush_fixups(void); |
428 | |
429 | #endif /* !__ASSEMBLY__ */ |
430 | |
431 | diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h |
432 | index 31913b3ac7ab..da852153c1f8 100644 |
433 | --- a/arch/powerpc/include/asm/uaccess.h |
434 | +++ b/arch/powerpc/include/asm/uaccess.h |
435 | @@ -269,6 +269,7 @@ do { \ |
436 | __chk_user_ptr(ptr); \ |
437 | if (!is_kernel_addr((unsigned long)__gu_addr)) \ |
438 | might_fault(); \ |
439 | + barrier_nospec(); \ |
440 | __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ |
441 | (x) = (__typeof__(*(ptr)))__gu_val; \ |
442 | __gu_err; \ |
443 | @@ -280,8 +281,10 @@ do { \ |
444 | unsigned long __gu_val = 0; \ |
445 | __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ |
446 | might_fault(); \ |
447 | - if (access_ok(VERIFY_READ, __gu_addr, (size))) \ |
448 | + if (access_ok(VERIFY_READ, __gu_addr, (size))) { \ |
449 | + barrier_nospec(); \ |
450 | __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ |
451 | + } \ |
452 | (x) = (__force __typeof__(*(ptr)))__gu_val; \ |
453 | __gu_err; \ |
454 | }) |
455 | @@ -292,6 +295,7 @@ do { \ |
456 | unsigned long __gu_val; \ |
457 | __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ |
458 | __chk_user_ptr(ptr); \ |
459 | + barrier_nospec(); \ |
460 | __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ |
461 | (x) = (__force __typeof__(*(ptr)))__gu_val; \ |
462 | __gu_err; \ |
463 | @@ -348,15 +352,19 @@ static inline unsigned long __copy_from_user_inatomic(void *to, |
464 | |
465 | switch (n) { |
466 | case 1: |
467 | + barrier_nospec(); |
468 | __get_user_size(*(u8 *)to, from, 1, ret); |
469 | break; |
470 | case 2: |
471 | + barrier_nospec(); |
472 | __get_user_size(*(u16 *)to, from, 2, ret); |
473 | break; |
474 | case 4: |
475 | + barrier_nospec(); |
476 | __get_user_size(*(u32 *)to, from, 4, ret); |
477 | break; |
478 | case 8: |
479 | + barrier_nospec(); |
480 | __get_user_size(*(u64 *)to, from, 8, ret); |
481 | break; |
482 | } |
483 | @@ -366,6 +374,7 @@ static inline unsigned long __copy_from_user_inatomic(void *to, |
484 | |
485 | check_object_size(to, n, false); |
486 | |
487 | + barrier_nospec(); |
488 | return __copy_tofrom_user((__force void __user *)to, from, n); |
489 | } |
490 | |
491 | diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile |
492 | index 13885786282b..d80fbf0884ff 100644 |
493 | --- a/arch/powerpc/kernel/Makefile |
494 | +++ b/arch/powerpc/kernel/Makefile |
495 | @@ -44,9 +44,10 @@ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ |
496 | obj-$(CONFIG_VDSO32) += vdso32/ |
497 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o |
498 | obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o |
499 | -obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o security.o |
500 | +obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o |
501 | obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o |
502 | obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o |
503 | +obj-$(CONFIG_PPC_BARRIER_NOSPEC) += security.o |
504 | obj-$(CONFIG_PPC64) += vdso64/ |
505 | obj-$(CONFIG_ALTIVEC) += vecemu.o |
506 | obj-$(CONFIG_PPC_970_NAP) += idle_power4.o |
507 | diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S |
508 | index 370645687cc7..bdd88f9d7926 100644 |
509 | --- a/arch/powerpc/kernel/entry_32.S |
510 | +++ b/arch/powerpc/kernel/entry_32.S |
511 | @@ -34,6 +34,7 @@ |
512 | #include <asm/ftrace.h> |
513 | #include <asm/ptrace.h> |
514 | #include <asm/export.h> |
515 | +#include <asm/barrier.h> |
516 | |
517 | /* |
518 | * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE. |
519 | @@ -347,6 +348,15 @@ syscall_dotrace_cont: |
520 | ori r10,r10,sys_call_table@l |
521 | slwi r0,r0,2 |
522 | bge- 66f |
523 | + |
524 | + barrier_nospec_asm |
525 | + /* |
526 | + * Prevent the load of the handler below (based on the user-passed |
527 | + * system call number) being speculatively executed until the test |
528 | + * against NR_syscalls and branch to .66f above has |
529 | + * committed. |
530 | + */ |
531 | + |
532 | lwzx r10,r10,r0 /* Fetch system call handler [ptr] */ |
533 | mtlr r10 |
534 | addi r9,r1,STACK_FRAME_OVERHEAD |
535 | diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S |
536 | index e24ae0fa80ed..390ebf4ef384 100644 |
537 | --- a/arch/powerpc/kernel/entry_64.S |
538 | +++ b/arch/powerpc/kernel/entry_64.S |
539 | @@ -26,6 +26,7 @@ |
540 | #include <asm/page.h> |
541 | #include <asm/mmu.h> |
542 | #include <asm/thread_info.h> |
543 | +#include <asm/code-patching-asm.h> |
544 | #include <asm/ppc_asm.h> |
545 | #include <asm/asm-offsets.h> |
546 | #include <asm/cputable.h> |
547 | @@ -38,6 +39,7 @@ |
548 | #include <asm/context_tracking.h> |
549 | #include <asm/tm.h> |
550 | #include <asm/ppc-opcode.h> |
551 | +#include <asm/barrier.h> |
552 | #include <asm/export.h> |
553 | #ifdef CONFIG_PPC_BOOK3S |
554 | #include <asm/exception-64s.h> |
555 | @@ -78,6 +80,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM) |
556 | std r0,GPR0(r1) |
557 | std r10,GPR1(r1) |
558 | beq 2f /* if from kernel mode */ |
559 | +#ifdef CONFIG_PPC_FSL_BOOK3E |
560 | +START_BTB_FLUSH_SECTION |
561 | + BTB_FLUSH(r10) |
562 | +END_BTB_FLUSH_SECTION |
563 | +#endif |
564 | ACCOUNT_CPU_USER_ENTRY(r13, r10, r11) |
565 | 2: std r2,GPR2(r1) |
566 | std r3,GPR3(r1) |
567 | @@ -180,6 +187,15 @@ system_call: /* label this so stack traces look sane */ |
568 | clrldi r8,r8,32 |
569 | 15: |
570 | slwi r0,r0,4 |
571 | + |
572 | + barrier_nospec_asm |
573 | + /* |
574 | + * Prevent the load of the handler below (based on the user-passed |
575 | + * system call number) being speculatively executed until the test |
576 | + * against NR_syscalls and branch to .Lsyscall_enosys above has |
577 | + * committed. |
578 | + */ |
579 | + |
580 | ldx r12,r11,r0 /* Fetch system call handler [ptr] */ |
581 | mtctr r12 |
582 | bctrl /* Call handler */ |
583 | @@ -473,6 +489,57 @@ _GLOBAL(ret_from_kernel_thread) |
584 | li r3,0 |
585 | b .Lsyscall_exit |
586 | |
587 | +#ifdef CONFIG_PPC_BOOK3S_64 |
588 | + |
589 | +#define FLUSH_COUNT_CACHE \ |
590 | +1: nop; \ |
591 | + patch_site 1b, patch__call_flush_count_cache |
592 | + |
593 | + |
594 | +#define BCCTR_FLUSH .long 0x4c400420 |
595 | + |
596 | +.macro nops number |
597 | + .rept \number |
598 | + nop |
599 | + .endr |
600 | +.endm |
601 | + |
602 | +.balign 32 |
603 | +.global flush_count_cache |
604 | +flush_count_cache: |
605 | + /* Save LR into r9 */ |
606 | + mflr r9 |
607 | + |
608 | + .rept 64 |
609 | + bl .+4 |
610 | + .endr |
611 | + b 1f |
612 | + nops 6 |
613 | + |
614 | + .balign 32 |
615 | + /* Restore LR */ |
616 | +1: mtlr r9 |
617 | + li r9,0x7fff |
618 | + mtctr r9 |
619 | + |
620 | + BCCTR_FLUSH |
621 | + |
622 | +2: nop |
623 | + patch_site 2b patch__flush_count_cache_return |
624 | + |
625 | + nops 3 |
626 | + |
627 | + .rept 278 |
628 | + .balign 32 |
629 | + BCCTR_FLUSH |
630 | + nops 7 |
631 | + .endr |
632 | + |
633 | + blr |
634 | +#else |
635 | +#define FLUSH_COUNT_CACHE |
636 | +#endif /* CONFIG_PPC_BOOK3S_64 */ |
637 | + |
638 | /* |
639 | * This routine switches between two different tasks. The process |
640 | * state of one is saved on its kernel stack. Then the state |
641 | @@ -504,6 +571,8 @@ _GLOBAL(_switch) |
642 | std r23,_CCR(r1) |
643 | std r1,KSP(r3) /* Set old stack pointer */ |
644 | |
645 | + FLUSH_COUNT_CACHE |
646 | + |
647 | #ifdef CONFIG_SMP |
648 | /* We need a sync somewhere here to make sure that if the |
649 | * previous task gets rescheduled on another CPU, it sees all |
650 | diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S |
651 | index ca03eb229a9a..423b5257d3a1 100644 |
652 | --- a/arch/powerpc/kernel/exceptions-64e.S |
653 | +++ b/arch/powerpc/kernel/exceptions-64e.S |
654 | @@ -295,7 +295,8 @@ ret_from_mc_except: |
655 | andi. r10,r11,MSR_PR; /* save stack pointer */ \ |
656 | beq 1f; /* branch around if supervisor */ \ |
657 | ld r1,PACAKSAVE(r13); /* get kernel stack coming from usr */\ |
658 | -1: cmpdi cr1,r1,0; /* check if SP makes sense */ \ |
659 | +1: type##_BTB_FLUSH \ |
660 | + cmpdi cr1,r1,0; /* check if SP makes sense */ \ |
661 | bge- cr1,exc_##n##_bad_stack;/* bad stack (TODO: out of line) */ \ |
662 | mfspr r10,SPRN_##type##_SRR0; /* read SRR0 before touching stack */ |
663 | |
664 | @@ -327,6 +328,30 @@ ret_from_mc_except: |
665 | #define SPRN_MC_SRR0 SPRN_MCSRR0 |
666 | #define SPRN_MC_SRR1 SPRN_MCSRR1 |
667 | |
668 | +#ifdef CONFIG_PPC_FSL_BOOK3E |
669 | +#define GEN_BTB_FLUSH \ |
670 | + START_BTB_FLUSH_SECTION \ |
671 | + beq 1f; \ |
672 | + BTB_FLUSH(r10) \ |
673 | + 1: \ |
674 | + END_BTB_FLUSH_SECTION |
675 | + |
676 | +#define CRIT_BTB_FLUSH \ |
677 | + START_BTB_FLUSH_SECTION \ |
678 | + BTB_FLUSH(r10) \ |
679 | + END_BTB_FLUSH_SECTION |
680 | + |
681 | +#define DBG_BTB_FLUSH CRIT_BTB_FLUSH |
682 | +#define MC_BTB_FLUSH CRIT_BTB_FLUSH |
683 | +#define GDBELL_BTB_FLUSH GEN_BTB_FLUSH |
684 | +#else |
685 | +#define GEN_BTB_FLUSH |
686 | +#define CRIT_BTB_FLUSH |
687 | +#define DBG_BTB_FLUSH |
688 | +#define MC_BTB_FLUSH |
689 | +#define GDBELL_BTB_FLUSH |
690 | +#endif |
691 | + |
692 | #define NORMAL_EXCEPTION_PROLOG(n, intnum, addition) \ |
693 | EXCEPTION_PROLOG(n, intnum, GEN, addition##_GEN(n)) |
694 | |
695 | diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h |
696 | index a620203f7de3..7b98c7351f6c 100644 |
697 | --- a/arch/powerpc/kernel/head_booke.h |
698 | +++ b/arch/powerpc/kernel/head_booke.h |
699 | @@ -31,6 +31,16 @@ |
700 | */ |
701 | #define THREAD_NORMSAVE(offset) (THREAD_NORMSAVES + (offset * 4)) |
702 | |
703 | +#ifdef CONFIG_PPC_FSL_BOOK3E |
704 | +#define BOOKE_CLEAR_BTB(reg) \ |
705 | +START_BTB_FLUSH_SECTION \ |
706 | + BTB_FLUSH(reg) \ |
707 | +END_BTB_FLUSH_SECTION |
708 | +#else |
709 | +#define BOOKE_CLEAR_BTB(reg) |
710 | +#endif |
711 | + |
712 | + |
713 | #define NORMAL_EXCEPTION_PROLOG(intno) \ |
714 | mtspr SPRN_SPRG_WSCRATCH0, r10; /* save one register */ \ |
715 | mfspr r10, SPRN_SPRG_THREAD; \ |
716 | @@ -42,6 +52,7 @@ |
717 | andi. r11, r11, MSR_PR; /* check whether user or kernel */\ |
718 | mr r11, r1; \ |
719 | beq 1f; \ |
720 | + BOOKE_CLEAR_BTB(r11) \ |
721 | /* if from user, start at top of this thread's kernel stack */ \ |
722 | lwz r11, THREAD_INFO-THREAD(r10); \ |
723 | ALLOC_STACK_FRAME(r11, THREAD_SIZE); \ |
724 | @@ -127,6 +138,7 @@ |
725 | stw r9,_CCR(r8); /* save CR on stack */\ |
726 | mfspr r11,exc_level_srr1; /* check whether user or kernel */\ |
727 | DO_KVM BOOKE_INTERRUPT_##intno exc_level_srr1; \ |
728 | + BOOKE_CLEAR_BTB(r10) \ |
729 | andi. r11,r11,MSR_PR; \ |
730 | mfspr r11,SPRN_SPRG_THREAD; /* if from user, start at top of */\ |
731 | lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ |
732 | diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S |
733 | index bf4c6021515f..60a0aeefc4a7 100644 |
734 | --- a/arch/powerpc/kernel/head_fsl_booke.S |
735 | +++ b/arch/powerpc/kernel/head_fsl_booke.S |
736 | @@ -452,6 +452,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) |
737 | mfcr r13 |
738 | stw r13, THREAD_NORMSAVE(3)(r10) |
739 | DO_KVM BOOKE_INTERRUPT_DTLB_MISS SPRN_SRR1 |
740 | +START_BTB_FLUSH_SECTION |
741 | + mfspr r11, SPRN_SRR1 |
742 | + andi. r10,r11,MSR_PR |
743 | + beq 1f |
744 | + BTB_FLUSH(r10) |
745 | +1: |
746 | +END_BTB_FLUSH_SECTION |
747 | mfspr r10, SPRN_DEAR /* Get faulting address */ |
748 | |
749 | /* If we are faulting a kernel address, we have to use the |
750 | @@ -546,6 +553,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) |
751 | mfcr r13 |
752 | stw r13, THREAD_NORMSAVE(3)(r10) |
753 | DO_KVM BOOKE_INTERRUPT_ITLB_MISS SPRN_SRR1 |
754 | +START_BTB_FLUSH_SECTION |
755 | + mfspr r11, SPRN_SRR1 |
756 | + andi. r10,r11,MSR_PR |
757 | + beq 1f |
758 | + BTB_FLUSH(r10) |
759 | +1: |
760 | +END_BTB_FLUSH_SECTION |
761 | + |
762 | mfspr r10, SPRN_SRR0 /* Get faulting address */ |
763 | |
764 | /* If we are faulting a kernel address, we have to use the |
765 | diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c |
766 | index 30b89d5cbb03..3b1c3bb91025 100644 |
767 | --- a/arch/powerpc/kernel/module.c |
768 | +++ b/arch/powerpc/kernel/module.c |
769 | @@ -72,7 +72,15 @@ int module_finalize(const Elf_Ehdr *hdr, |
770 | do_feature_fixups(powerpc_firmware_features, |
771 | (void *)sect->sh_addr, |
772 | (void *)sect->sh_addr + sect->sh_size); |
773 | -#endif |
774 | +#endif /* CONFIG_PPC64 */ |
775 | + |
776 | +#ifdef CONFIG_PPC_BARRIER_NOSPEC |
777 | + sect = find_section(hdr, sechdrs, "__spec_barrier_fixup"); |
778 | + if (sect != NULL) |
779 | + do_barrier_nospec_fixups_range(barrier_nospec_enabled, |
780 | + (void *)sect->sh_addr, |
781 | + (void *)sect->sh_addr + sect->sh_size); |
782 | +#endif /* CONFIG_PPC_BARRIER_NOSPEC */ |
783 | |
784 | sect = find_section(hdr, sechdrs, "__lwsync_fixup"); |
785 | if (sect != NULL) |
786 | diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c |
787 | index 2277df84ef6e..30542e833ebe 100644 |
788 | --- a/arch/powerpc/kernel/security.c |
789 | +++ b/arch/powerpc/kernel/security.c |
790 | @@ -9,11 +9,121 @@ |
791 | #include <linux/device.h> |
792 | #include <linux/seq_buf.h> |
793 | |
794 | +#include <asm/asm-prototypes.h> |
795 | +#include <asm/code-patching.h> |
796 | +#include <asm/debug.h> |
797 | #include <asm/security_features.h> |
798 | +#include <asm/setup.h> |
799 | |
800 | |
801 | unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT; |
802 | |
803 | +enum count_cache_flush_type { |
804 | + COUNT_CACHE_FLUSH_NONE = 0x1, |
805 | + COUNT_CACHE_FLUSH_SW = 0x2, |
806 | + COUNT_CACHE_FLUSH_HW = 0x4, |
807 | +}; |
808 | +static enum count_cache_flush_type count_cache_flush_type = COUNT_CACHE_FLUSH_NONE; |
809 | + |
810 | +bool barrier_nospec_enabled; |
811 | +static bool no_nospec; |
812 | +static bool btb_flush_enabled; |
813 | +#ifdef CONFIG_PPC_FSL_BOOK3E |
814 | +static bool no_spectrev2; |
815 | +#endif |
816 | + |
817 | +static void enable_barrier_nospec(bool enable) |
818 | +{ |
819 | + barrier_nospec_enabled = enable; |
820 | + do_barrier_nospec_fixups(enable); |
821 | +} |
822 | + |
823 | +void setup_barrier_nospec(void) |
824 | +{ |
825 | + bool enable; |
826 | + |
827 | + /* |
828 | + * It would make sense to check SEC_FTR_SPEC_BAR_ORI31 below as well. |
829 | + * But there's a good reason not to. The two flags we check below are |
830 | + * both are enabled by default in the kernel, so if the hcall is not |
831 | + * functional they will be enabled. |
832 | + * On a system where the host firmware has been updated (so the ori |
833 | + * functions as a barrier), but on which the hypervisor (KVM/Qemu) has |
834 | + * not been updated, we would like to enable the barrier. Dropping the |
835 | + * check for SEC_FTR_SPEC_BAR_ORI31 achieves that. The only downside is |
836 | + * we potentially enable the barrier on systems where the host firmware |
837 | + * is not updated, but that's harmless as it's a no-op. |
838 | + */ |
839 | + enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && |
840 | + security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR); |
841 | + |
842 | + if (!no_nospec) |
843 | + enable_barrier_nospec(enable); |
844 | +} |
845 | + |
846 | +static int __init handle_nospectre_v1(char *p) |
847 | +{ |
848 | + no_nospec = true; |
849 | + |
850 | + return 0; |
851 | +} |
852 | +early_param("nospectre_v1", handle_nospectre_v1); |
853 | + |
854 | +#ifdef CONFIG_DEBUG_FS |
855 | +static int barrier_nospec_set(void *data, u64 val) |
856 | +{ |
857 | + switch (val) { |
858 | + case 0: |
859 | + case 1: |
860 | + break; |
861 | + default: |
862 | + return -EINVAL; |
863 | + } |
864 | + |
865 | + if (!!val == !!barrier_nospec_enabled) |
866 | + return 0; |
867 | + |
868 | + enable_barrier_nospec(!!val); |
869 | + |
870 | + return 0; |
871 | +} |
872 | + |
873 | +static int barrier_nospec_get(void *data, u64 *val) |
874 | +{ |
875 | + *val = barrier_nospec_enabled ? 1 : 0; |
876 | + return 0; |
877 | +} |
878 | + |
879 | +DEFINE_SIMPLE_ATTRIBUTE(fops_barrier_nospec, |
880 | + barrier_nospec_get, barrier_nospec_set, "%llu\n"); |
881 | + |
882 | +static __init int barrier_nospec_debugfs_init(void) |
883 | +{ |
884 | + debugfs_create_file("barrier_nospec", 0600, powerpc_debugfs_root, NULL, |
885 | + &fops_barrier_nospec); |
886 | + return 0; |
887 | +} |
888 | +device_initcall(barrier_nospec_debugfs_init); |
889 | +#endif /* CONFIG_DEBUG_FS */ |
890 | + |
891 | +#ifdef CONFIG_PPC_FSL_BOOK3E |
892 | +static int __init handle_nospectre_v2(char *p) |
893 | +{ |
894 | + no_spectrev2 = true; |
895 | + |
896 | + return 0; |
897 | +} |
898 | +early_param("nospectre_v2", handle_nospectre_v2); |
899 | +void setup_spectre_v2(void) |
900 | +{ |
901 | + if (no_spectrev2) |
902 | + do_btb_flush_fixups(); |
903 | + else |
904 | + btb_flush_enabled = true; |
905 | +} |
906 | +#endif /* CONFIG_PPC_FSL_BOOK3E */ |
907 | + |
908 | +#ifdef CONFIG_PPC_BOOK3S_64 |
909 | ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf) |
910 | { |
911 | bool thread_priv; |
912 | @@ -46,25 +156,39 @@ ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, cha |
913 | |
914 | return sprintf(buf, "Vulnerable\n"); |
915 | } |
916 | +#endif |
917 | |
918 | ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf) |
919 | { |
920 | - if (!security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR)) |
921 | - return sprintf(buf, "Not affected\n"); |
922 | + struct seq_buf s; |
923 | |
924 | - return sprintf(buf, "Vulnerable\n"); |
925 | + seq_buf_init(&s, buf, PAGE_SIZE - 1); |
926 | + |
927 | + if (security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR)) { |
928 | + if (barrier_nospec_enabled) |
929 | + seq_buf_printf(&s, "Mitigation: __user pointer sanitization"); |
930 | + else |
931 | + seq_buf_printf(&s, "Vulnerable"); |
932 | + |
933 | + if (security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31)) |
934 | + seq_buf_printf(&s, ", ori31 speculation barrier enabled"); |
935 | + |
936 | + seq_buf_printf(&s, "\n"); |
937 | + } else |
938 | + seq_buf_printf(&s, "Not affected\n"); |
939 | + |
940 | + return s.len; |
941 | } |
942 | |
943 | ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf) |
944 | { |
945 | - bool bcs, ccd, ori; |
946 | struct seq_buf s; |
947 | + bool bcs, ccd; |
948 | |
949 | seq_buf_init(&s, buf, PAGE_SIZE - 1); |
950 | |
951 | bcs = security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED); |
952 | ccd = security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED); |
953 | - ori = security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31); |
954 | |
955 | if (bcs || ccd) { |
956 | seq_buf_printf(&s, "Mitigation: "); |
957 | @@ -77,17 +201,23 @@ ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, c |
958 | |
959 | if (ccd) |
960 | seq_buf_printf(&s, "Indirect branch cache disabled"); |
961 | - } else |
962 | + } else if (count_cache_flush_type != COUNT_CACHE_FLUSH_NONE) { |
963 | + seq_buf_printf(&s, "Mitigation: Software count cache flush"); |
964 | + |
965 | + if (count_cache_flush_type == COUNT_CACHE_FLUSH_HW) |
966 | + seq_buf_printf(&s, " (hardware accelerated)"); |
967 | + } else if (btb_flush_enabled) { |
968 | + seq_buf_printf(&s, "Mitigation: Branch predictor state flush"); |
969 | + } else { |
970 | seq_buf_printf(&s, "Vulnerable"); |
971 | - |
972 | - if (ori) |
973 | - seq_buf_printf(&s, ", ori31 speculation barrier enabled"); |
974 | + } |
975 | |
976 | seq_buf_printf(&s, "\n"); |
977 | |
978 | return s.len; |
979 | } |
980 | |
981 | +#ifdef CONFIG_PPC_BOOK3S_64 |
982 | /* |
983 | * Store-forwarding barrier support. |
984 | */ |
985 | @@ -235,3 +365,71 @@ static __init int stf_barrier_debugfs_init(void) |
986 | } |
987 | device_initcall(stf_barrier_debugfs_init); |
988 | #endif /* CONFIG_DEBUG_FS */ |
989 | + |
990 | +static void toggle_count_cache_flush(bool enable) |
991 | +{ |
992 | + if (!enable || !security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) { |
993 | + patch_instruction_site(&patch__call_flush_count_cache, PPC_INST_NOP); |
994 | + count_cache_flush_type = COUNT_CACHE_FLUSH_NONE; |
995 | + pr_info("count-cache-flush: software flush disabled.\n"); |
996 | + return; |
997 | + } |
998 | + |
999 | + patch_branch_site(&patch__call_flush_count_cache, |
1000 | + (u64)&flush_count_cache, BRANCH_SET_LINK); |
1001 | + |
1002 | + if (!security_ftr_enabled(SEC_FTR_BCCTR_FLUSH_ASSIST)) { |
1003 | + count_cache_flush_type = COUNT_CACHE_FLUSH_SW; |
1004 | + pr_info("count-cache-flush: full software flush sequence enabled.\n"); |
1005 | + return; |
1006 | + } |
1007 | + |
1008 | + patch_instruction_site(&patch__flush_count_cache_return, PPC_INST_BLR); |
1009 | + count_cache_flush_type = COUNT_CACHE_FLUSH_HW; |
1010 | + pr_info("count-cache-flush: hardware assisted flush sequence enabled\n"); |
1011 | +} |
1012 | + |
1013 | +void setup_count_cache_flush(void) |
1014 | +{ |
1015 | + toggle_count_cache_flush(true); |
1016 | +} |
1017 | + |
1018 | +#ifdef CONFIG_DEBUG_FS |
1019 | +static int count_cache_flush_set(void *data, u64 val) |
1020 | +{ |
1021 | + bool enable; |
1022 | + |
1023 | + if (val == 1) |
1024 | + enable = true; |
1025 | + else if (val == 0) |
1026 | + enable = false; |
1027 | + else |
1028 | + return -EINVAL; |
1029 | + |
1030 | + toggle_count_cache_flush(enable); |
1031 | + |
1032 | + return 0; |
1033 | +} |
1034 | + |
1035 | +static int count_cache_flush_get(void *data, u64 *val) |
1036 | +{ |
1037 | + if (count_cache_flush_type == COUNT_CACHE_FLUSH_NONE) |
1038 | + *val = 0; |
1039 | + else |
1040 | + *val = 1; |
1041 | + |
1042 | + return 0; |
1043 | +} |
1044 | + |
1045 | +DEFINE_SIMPLE_ATTRIBUTE(fops_count_cache_flush, count_cache_flush_get, |
1046 | + count_cache_flush_set, "%llu\n"); |
1047 | + |
1048 | +static __init int count_cache_flush_debugfs_init(void) |
1049 | +{ |
1050 | + debugfs_create_file("count_cache_flush", 0600, powerpc_debugfs_root, |
1051 | + NULL, &fops_count_cache_flush); |
1052 | + return 0; |
1053 | +} |
1054 | +device_initcall(count_cache_flush_debugfs_init); |
1055 | +#endif /* CONFIG_DEBUG_FS */ |
1056 | +#endif /* CONFIG_PPC_BOOK3S_64 */ |
1057 | diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c |
1058 | index bf0f712ac0e0..5e7d70c5d065 100644 |
1059 | --- a/arch/powerpc/kernel/setup-common.c |
1060 | +++ b/arch/powerpc/kernel/setup-common.c |
1061 | @@ -918,6 +918,9 @@ void __init setup_arch(char **cmdline_p) |
1062 | if (ppc_md.setup_arch) |
1063 | ppc_md.setup_arch(); |
1064 | |
1065 | + setup_barrier_nospec(); |
1066 | + setup_spectre_v2(); |
1067 | + |
1068 | paging_init(); |
1069 | |
1070 | /* Initialize the MMU context management stuff. */ |
1071 | diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c |
1072 | index d929afab7b24..bdf2f7b995bb 100644 |
1073 | --- a/arch/powerpc/kernel/signal_64.c |
1074 | +++ b/arch/powerpc/kernel/signal_64.c |
1075 | @@ -746,12 +746,25 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, |
1076 | if (restore_tm_sigcontexts(current, &uc->uc_mcontext, |
1077 | &uc_transact->uc_mcontext)) |
1078 | goto badframe; |
1079 | - } |
1080 | - else |
1081 | - /* Fall through, for non-TM restore */ |
1082 | + } else |
1083 | #endif |
1084 | - if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext)) |
1085 | - goto badframe; |
1086 | + { |
1087 | + /* |
1088 | + * Fall through, for non-TM restore |
1089 | + * |
1090 | + * Unset MSR[TS] on the thread regs since MSR from user |
1091 | + * context does not have MSR active, and recheckpoint was |
1092 | + * not called since restore_tm_sigcontexts() was not called |
1093 | + * also. |
1094 | + * |
1095 | + * If not unsetting it, the code can RFID to userspace with |
1096 | + * MSR[TS] set, but without CPU in the proper state, |
1097 | + * causing a TM bad thing. |
1098 | + */ |
1099 | + current->thread.regs->msr &= ~MSR_TS_MASK; |
1100 | + if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext)) |
1101 | + goto badframe; |
1102 | + } |
1103 | |
1104 | if (restore_altstack(&uc->uc_stack)) |
1105 | goto badframe; |
1106 | diff --git a/arch/powerpc/kernel/swsusp_asm64.S b/arch/powerpc/kernel/swsusp_asm64.S |
1107 | index 988f38dced0f..82d8aae81c6a 100644 |
1108 | --- a/arch/powerpc/kernel/swsusp_asm64.S |
1109 | +++ b/arch/powerpc/kernel/swsusp_asm64.S |
1110 | @@ -179,7 +179,7 @@ nothing_to_copy: |
1111 | sld r3, r3, r0 |
1112 | li r0, 0 |
1113 | 1: |
1114 | - dcbf r0,r3 |
1115 | + dcbf 0,r3 |
1116 | addi r3,r3,0x20 |
1117 | bdnz 1b |
1118 | |
1119 | diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S |
1120 | index c16fddbb6ab8..50d365060855 100644 |
1121 | --- a/arch/powerpc/kernel/vmlinux.lds.S |
1122 | +++ b/arch/powerpc/kernel/vmlinux.lds.S |
1123 | @@ -153,8 +153,25 @@ SECTIONS |
1124 | *(__rfi_flush_fixup) |
1125 | __stop___rfi_flush_fixup = .; |
1126 | } |
1127 | -#endif |
1128 | +#endif /* CONFIG_PPC64 */ |
1129 | + |
1130 | +#ifdef CONFIG_PPC_BARRIER_NOSPEC |
1131 | + . = ALIGN(8); |
1132 | + __spec_barrier_fixup : AT(ADDR(__spec_barrier_fixup) - LOAD_OFFSET) { |
1133 | + __start___barrier_nospec_fixup = .; |
1134 | + *(__barrier_nospec_fixup) |
1135 | + __stop___barrier_nospec_fixup = .; |
1136 | + } |
1137 | +#endif /* CONFIG_PPC_BARRIER_NOSPEC */ |
1138 | |
1139 | +#ifdef CONFIG_PPC_FSL_BOOK3E |
1140 | + . = ALIGN(8); |
1141 | + __spec_btb_flush_fixup : AT(ADDR(__spec_btb_flush_fixup) - LOAD_OFFSET) { |
1142 | + __start__btb_flush_fixup = .; |
1143 | + *(__btb_flush_fixup) |
1144 | + __stop__btb_flush_fixup = .; |
1145 | + } |
1146 | +#endif |
1147 | EXCEPTION_TABLE(0) |
1148 | |
1149 | NOTES :kernel :notes |
1150 | diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S |
1151 | index 81bd8a07aa51..612b7f6a887f 100644 |
1152 | --- a/arch/powerpc/kvm/bookehv_interrupts.S |
1153 | +++ b/arch/powerpc/kvm/bookehv_interrupts.S |
1154 | @@ -75,6 +75,10 @@ |
1155 | PPC_LL r1, VCPU_HOST_STACK(r4) |
1156 | PPC_LL r2, HOST_R2(r1) |
1157 | |
1158 | +START_BTB_FLUSH_SECTION |
1159 | + BTB_FLUSH(r10) |
1160 | +END_BTB_FLUSH_SECTION |
1161 | + |
1162 | mfspr r10, SPRN_PID |
1163 | lwz r8, VCPU_HOST_PID(r4) |
1164 | PPC_LL r11, VCPU_SHARED(r4) |
1165 | diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c |
1166 | index 990db69a1d0b..fa88f641ac03 100644 |
1167 | --- a/arch/powerpc/kvm/e500_emulate.c |
1168 | +++ b/arch/powerpc/kvm/e500_emulate.c |
1169 | @@ -277,6 +277,13 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va |
1170 | vcpu->arch.pwrmgtcr0 = spr_val; |
1171 | break; |
1172 | |
1173 | + case SPRN_BUCSR: |
1174 | + /* |
1175 | + * If we are here, it means that we have already flushed the |
1176 | + * branch predictor, so just return to guest. |
1177 | + */ |
1178 | + break; |
1179 | + |
1180 | /* extra exceptions */ |
1181 | #ifdef CONFIG_SPE_POSSIBLE |
1182 | case SPRN_IVOR32: |
1183 | diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c |
1184 | index 753d591f1b52..14535ad4cdd1 100644 |
1185 | --- a/arch/powerpc/lib/code-patching.c |
1186 | +++ b/arch/powerpc/lib/code-patching.c |
1187 | @@ -14,12 +14,20 @@ |
1188 | #include <asm/page.h> |
1189 | #include <asm/code-patching.h> |
1190 | #include <asm/uaccess.h> |
1191 | +#include <asm/setup.h> |
1192 | +#include <asm/sections.h> |
1193 | |
1194 | |
1195 | int patch_instruction(unsigned int *addr, unsigned int instr) |
1196 | { |
1197 | int err; |
1198 | |
1199 | + /* Make sure we aren't patching a freed init section */ |
1200 | + if (init_mem_is_free && init_section_contains(addr, 4)) { |
1201 | + pr_debug("Skipping init section patching addr: 0x%px\n", addr); |
1202 | + return 0; |
1203 | + } |
1204 | + |
1205 | __put_user_size(instr, addr, 4, err); |
1206 | if (err) |
1207 | return err; |
1208 | @@ -32,6 +40,22 @@ int patch_branch(unsigned int *addr, unsigned long target, int flags) |
1209 | return patch_instruction(addr, create_branch(addr, target, flags)); |
1210 | } |
1211 | |
1212 | +int patch_branch_site(s32 *site, unsigned long target, int flags) |
1213 | +{ |
1214 | + unsigned int *addr; |
1215 | + |
1216 | + addr = (unsigned int *)((unsigned long)site + *site); |
1217 | + return patch_instruction(addr, create_branch(addr, target, flags)); |
1218 | +} |
1219 | + |
1220 | +int patch_instruction_site(s32 *site, unsigned int instr) |
1221 | +{ |
1222 | + unsigned int *addr; |
1223 | + |
1224 | + addr = (unsigned int *)((unsigned long)site + *site); |
1225 | + return patch_instruction(addr, instr); |
1226 | +} |
1227 | + |
1228 | unsigned int create_branch(const unsigned int *addr, |
1229 | unsigned long target, int flags) |
1230 | { |
1231 | diff --git a/arch/powerpc/lib/copypage_power7.S b/arch/powerpc/lib/copypage_power7.S |
1232 | index a84d333ecb09..ca5fc8fa7efc 100644 |
1233 | --- a/arch/powerpc/lib/copypage_power7.S |
1234 | +++ b/arch/powerpc/lib/copypage_power7.S |
1235 | @@ -45,13 +45,13 @@ _GLOBAL(copypage_power7) |
1236 | .machine push |
1237 | .machine "power4" |
1238 | /* setup read stream 0 */ |
1239 | - dcbt r0,r4,0b01000 /* addr from */ |
1240 | - dcbt r0,r7,0b01010 /* length and depth from */ |
1241 | + dcbt 0,r4,0b01000 /* addr from */ |
1242 | + dcbt 0,r7,0b01010 /* length and depth from */ |
1243 | /* setup write stream 1 */ |
1244 | - dcbtst r0,r9,0b01000 /* addr to */ |
1245 | - dcbtst r0,r10,0b01010 /* length and depth to */ |
1246 | + dcbtst 0,r9,0b01000 /* addr to */ |
1247 | + dcbtst 0,r10,0b01010 /* length and depth to */ |
1248 | eieio |
1249 | - dcbt r0,r8,0b01010 /* all streams GO */ |
1250 | + dcbt 0,r8,0b01010 /* all streams GO */ |
1251 | .machine pop |
1252 | |
1253 | #ifdef CONFIG_ALTIVEC |
1254 | @@ -83,7 +83,7 @@ _GLOBAL(copypage_power7) |
1255 | li r12,112 |
1256 | |
1257 | .align 5 |
1258 | -1: lvx v7,r0,r4 |
1259 | +1: lvx v7,0,r4 |
1260 | lvx v6,r4,r6 |
1261 | lvx v5,r4,r7 |
1262 | lvx v4,r4,r8 |
1263 | @@ -92,7 +92,7 @@ _GLOBAL(copypage_power7) |
1264 | lvx v1,r4,r11 |
1265 | lvx v0,r4,r12 |
1266 | addi r4,r4,128 |
1267 | - stvx v7,r0,r3 |
1268 | + stvx v7,0,r3 |
1269 | stvx v6,r3,r6 |
1270 | stvx v5,r3,r7 |
1271 | stvx v4,r3,r8 |
1272 | diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S |
1273 | index da0c568d18c4..391694814691 100644 |
1274 | --- a/arch/powerpc/lib/copyuser_power7.S |
1275 | +++ b/arch/powerpc/lib/copyuser_power7.S |
1276 | @@ -327,13 +327,13 @@ err1; stb r0,0(r3) |
1277 | .machine push |
1278 | .machine "power4" |
1279 | /* setup read stream 0 */ |
1280 | - dcbt r0,r6,0b01000 /* addr from */ |
1281 | - dcbt r0,r7,0b01010 /* length and depth from */ |
1282 | + dcbt 0,r6,0b01000 /* addr from */ |
1283 | + dcbt 0,r7,0b01010 /* length and depth from */ |
1284 | /* setup write stream 1 */ |
1285 | - dcbtst r0,r9,0b01000 /* addr to */ |
1286 | - dcbtst r0,r10,0b01010 /* length and depth to */ |
1287 | + dcbtst 0,r9,0b01000 /* addr to */ |
1288 | + dcbtst 0,r10,0b01010 /* length and depth to */ |
1289 | eieio |
1290 | - dcbt r0,r8,0b01010 /* all streams GO */ |
1291 | + dcbt 0,r8,0b01010 /* all streams GO */ |
1292 | .machine pop |
1293 | |
1294 | beq cr1,.Lunwind_stack_nonvmx_copy |
1295 | @@ -388,26 +388,26 @@ err3; std r0,0(r3) |
1296 | li r11,48 |
1297 | |
1298 | bf cr7*4+3,5f |
1299 | -err3; lvx v1,r0,r4 |
1300 | +err3; lvx v1,0,r4 |
1301 | addi r4,r4,16 |
1302 | -err3; stvx v1,r0,r3 |
1303 | +err3; stvx v1,0,r3 |
1304 | addi r3,r3,16 |
1305 | |
1306 | 5: bf cr7*4+2,6f |
1307 | -err3; lvx v1,r0,r4 |
1308 | +err3; lvx v1,0,r4 |
1309 | err3; lvx v0,r4,r9 |
1310 | addi r4,r4,32 |
1311 | -err3; stvx v1,r0,r3 |
1312 | +err3; stvx v1,0,r3 |
1313 | err3; stvx v0,r3,r9 |
1314 | addi r3,r3,32 |
1315 | |
1316 | 6: bf cr7*4+1,7f |
1317 | -err3; lvx v3,r0,r4 |
1318 | +err3; lvx v3,0,r4 |
1319 | err3; lvx v2,r4,r9 |
1320 | err3; lvx v1,r4,r10 |
1321 | err3; lvx v0,r4,r11 |
1322 | addi r4,r4,64 |
1323 | -err3; stvx v3,r0,r3 |
1324 | +err3; stvx v3,0,r3 |
1325 | err3; stvx v2,r3,r9 |
1326 | err3; stvx v1,r3,r10 |
1327 | err3; stvx v0,r3,r11 |
1328 | @@ -433,7 +433,7 @@ err3; stvx v0,r3,r11 |
1329 | */ |
1330 | .align 5 |
1331 | 8: |
1332 | -err4; lvx v7,r0,r4 |
1333 | +err4; lvx v7,0,r4 |
1334 | err4; lvx v6,r4,r9 |
1335 | err4; lvx v5,r4,r10 |
1336 | err4; lvx v4,r4,r11 |
1337 | @@ -442,7 +442,7 @@ err4; lvx v2,r4,r14 |
1338 | err4; lvx v1,r4,r15 |
1339 | err4; lvx v0,r4,r16 |
1340 | addi r4,r4,128 |
1341 | -err4; stvx v7,r0,r3 |
1342 | +err4; stvx v7,0,r3 |
1343 | err4; stvx v6,r3,r9 |
1344 | err4; stvx v5,r3,r10 |
1345 | err4; stvx v4,r3,r11 |
1346 | @@ -463,29 +463,29 @@ err4; stvx v0,r3,r16 |
1347 | mtocrf 0x01,r6 |
1348 | |
1349 | bf cr7*4+1,9f |
1350 | -err3; lvx v3,r0,r4 |
1351 | +err3; lvx v3,0,r4 |
1352 | err3; lvx v2,r4,r9 |
1353 | err3; lvx v1,r4,r10 |
1354 | err3; lvx v0,r4,r11 |
1355 | addi r4,r4,64 |
1356 | -err3; stvx v3,r0,r3 |
1357 | +err3; stvx v3,0,r3 |
1358 | err3; stvx v2,r3,r9 |
1359 | err3; stvx v1,r3,r10 |
1360 | err3; stvx v0,r3,r11 |
1361 | addi r3,r3,64 |
1362 | |
1363 | 9: bf cr7*4+2,10f |
1364 | -err3; lvx v1,r0,r4 |
1365 | +err3; lvx v1,0,r4 |
1366 | err3; lvx v0,r4,r9 |
1367 | addi r4,r4,32 |
1368 | -err3; stvx v1,r0,r3 |
1369 | +err3; stvx v1,0,r3 |
1370 | err3; stvx v0,r3,r9 |
1371 | addi r3,r3,32 |
1372 | |
1373 | 10: bf cr7*4+3,11f |
1374 | -err3; lvx v1,r0,r4 |
1375 | +err3; lvx v1,0,r4 |
1376 | addi r4,r4,16 |
1377 | -err3; stvx v1,r0,r3 |
1378 | +err3; stvx v1,0,r3 |
1379 | addi r3,r3,16 |
1380 | |
1381 | /* Up to 15B to go */ |
1382 | @@ -565,25 +565,25 @@ err3; lvx v0,0,r4 |
1383 | addi r4,r4,16 |
1384 | |
1385 | bf cr7*4+3,5f |
1386 | -err3; lvx v1,r0,r4 |
1387 | +err3; lvx v1,0,r4 |
1388 | VPERM(v8,v0,v1,v16) |
1389 | addi r4,r4,16 |
1390 | -err3; stvx v8,r0,r3 |
1391 | +err3; stvx v8,0,r3 |
1392 | addi r3,r3,16 |
1393 | vor v0,v1,v1 |
1394 | |
1395 | 5: bf cr7*4+2,6f |
1396 | -err3; lvx v1,r0,r4 |
1397 | +err3; lvx v1,0,r4 |
1398 | VPERM(v8,v0,v1,v16) |
1399 | err3; lvx v0,r4,r9 |
1400 | VPERM(v9,v1,v0,v16) |
1401 | addi r4,r4,32 |
1402 | -err3; stvx v8,r0,r3 |
1403 | +err3; stvx v8,0,r3 |
1404 | err3; stvx v9,r3,r9 |
1405 | addi r3,r3,32 |
1406 | |
1407 | 6: bf cr7*4+1,7f |
1408 | -err3; lvx v3,r0,r4 |
1409 | +err3; lvx v3,0,r4 |
1410 | VPERM(v8,v0,v3,v16) |
1411 | err3; lvx v2,r4,r9 |
1412 | VPERM(v9,v3,v2,v16) |
1413 | @@ -592,7 +592,7 @@ err3; lvx v1,r4,r10 |
1414 | err3; lvx v0,r4,r11 |
1415 | VPERM(v11,v1,v0,v16) |
1416 | addi r4,r4,64 |
1417 | -err3; stvx v8,r0,r3 |
1418 | +err3; stvx v8,0,r3 |
1419 | err3; stvx v9,r3,r9 |
1420 | err3; stvx v10,r3,r10 |
1421 | err3; stvx v11,r3,r11 |
1422 | @@ -618,7 +618,7 @@ err3; stvx v11,r3,r11 |
1423 | */ |
1424 | .align 5 |
1425 | 8: |
1426 | -err4; lvx v7,r0,r4 |
1427 | +err4; lvx v7,0,r4 |
1428 | VPERM(v8,v0,v7,v16) |
1429 | err4; lvx v6,r4,r9 |
1430 | VPERM(v9,v7,v6,v16) |
1431 | @@ -635,7 +635,7 @@ err4; lvx v1,r4,r15 |
1432 | err4; lvx v0,r4,r16 |
1433 | VPERM(v15,v1,v0,v16) |
1434 | addi r4,r4,128 |
1435 | -err4; stvx v8,r0,r3 |
1436 | +err4; stvx v8,0,r3 |
1437 | err4; stvx v9,r3,r9 |
1438 | err4; stvx v10,r3,r10 |
1439 | err4; stvx v11,r3,r11 |
1440 | @@ -656,7 +656,7 @@ err4; stvx v15,r3,r16 |
1441 | mtocrf 0x01,r6 |
1442 | |
1443 | bf cr7*4+1,9f |
1444 | -err3; lvx v3,r0,r4 |
1445 | +err3; lvx v3,0,r4 |
1446 | VPERM(v8,v0,v3,v16) |
1447 | err3; lvx v2,r4,r9 |
1448 | VPERM(v9,v3,v2,v16) |
1449 | @@ -665,27 +665,27 @@ err3; lvx v1,r4,r10 |
1450 | err3; lvx v0,r4,r11 |
1451 | VPERM(v11,v1,v0,v16) |
1452 | addi r4,r4,64 |
1453 | -err3; stvx v8,r0,r3 |
1454 | +err3; stvx v8,0,r3 |
1455 | err3; stvx v9,r3,r9 |
1456 | err3; stvx v10,r3,r10 |
1457 | err3; stvx v11,r3,r11 |
1458 | addi r3,r3,64 |
1459 | |
1460 | 9: bf cr7*4+2,10f |
1461 | -err3; lvx v1,r0,r4 |
1462 | +err3; lvx v1,0,r4 |
1463 | VPERM(v8,v0,v1,v16) |
1464 | err3; lvx v0,r4,r9 |
1465 | VPERM(v9,v1,v0,v16) |
1466 | addi r4,r4,32 |
1467 | -err3; stvx v8,r0,r3 |
1468 | +err3; stvx v8,0,r3 |
1469 | err3; stvx v9,r3,r9 |
1470 | addi r3,r3,32 |
1471 | |
1472 | 10: bf cr7*4+3,11f |
1473 | -err3; lvx v1,r0,r4 |
1474 | +err3; lvx v1,0,r4 |
1475 | VPERM(v8,v0,v1,v16) |
1476 | addi r4,r4,16 |
1477 | -err3; stvx v8,r0,r3 |
1478 | +err3; stvx v8,0,r3 |
1479 | addi r3,r3,16 |
1480 | |
1481 | /* Up to 15B to go */ |
1482 | diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c |
1483 | index cf1398e3c2e0..e6ed0ec94bc8 100644 |
1484 | --- a/arch/powerpc/lib/feature-fixups.c |
1485 | +++ b/arch/powerpc/lib/feature-fixups.c |
1486 | @@ -277,8 +277,101 @@ void do_rfi_flush_fixups(enum l1d_flush_type types) |
1487 | (types & L1D_FLUSH_MTTRIG) ? "mttrig type" |
1488 | : "unknown"); |
1489 | } |
1490 | + |
1491 | +void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end) |
1492 | +{ |
1493 | + unsigned int instr, *dest; |
1494 | + long *start, *end; |
1495 | + int i; |
1496 | + |
1497 | + start = fixup_start; |
1498 | + end = fixup_end; |
1499 | + |
1500 | + instr = 0x60000000; /* nop */ |
1501 | + |
1502 | + if (enable) { |
1503 | + pr_info("barrier-nospec: using ORI speculation barrier\n"); |
1504 | + instr = 0x63ff0000; /* ori 31,31,0 speculation barrier */ |
1505 | + } |
1506 | + |
1507 | + for (i = 0; start < end; start++, i++) { |
1508 | + dest = (void *)start + *start; |
1509 | + |
1510 | + pr_devel("patching dest %lx\n", (unsigned long)dest); |
1511 | + patch_instruction(dest, instr); |
1512 | + } |
1513 | + |
1514 | + printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i); |
1515 | +} |
1516 | + |
1517 | #endif /* CONFIG_PPC_BOOK3S_64 */ |
1518 | |
1519 | +#ifdef CONFIG_PPC_BARRIER_NOSPEC |
1520 | +void do_barrier_nospec_fixups(bool enable) |
1521 | +{ |
1522 | + void *start, *end; |
1523 | + |
1524 | + start = PTRRELOC(&__start___barrier_nospec_fixup), |
1525 | + end = PTRRELOC(&__stop___barrier_nospec_fixup); |
1526 | + |
1527 | + do_barrier_nospec_fixups_range(enable, start, end); |
1528 | +} |
1529 | +#endif /* CONFIG_PPC_BARRIER_NOSPEC */ |
1530 | + |
1531 | +#ifdef CONFIG_PPC_FSL_BOOK3E |
1532 | +void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end) |
1533 | +{ |
1534 | + unsigned int instr[2], *dest; |
1535 | + long *start, *end; |
1536 | + int i; |
1537 | + |
1538 | + start = fixup_start; |
1539 | + end = fixup_end; |
1540 | + |
1541 | + instr[0] = PPC_INST_NOP; |
1542 | + instr[1] = PPC_INST_NOP; |
1543 | + |
1544 | + if (enable) { |
1545 | + pr_info("barrier-nospec: using isync; sync as speculation barrier\n"); |
1546 | + instr[0] = PPC_INST_ISYNC; |
1547 | + instr[1] = PPC_INST_SYNC; |
1548 | + } |
1549 | + |
1550 | + for (i = 0; start < end; start++, i++) { |
1551 | + dest = (void *)start + *start; |
1552 | + |
1553 | + pr_devel("patching dest %lx\n", (unsigned long)dest); |
1554 | + patch_instruction(dest, instr[0]); |
1555 | + patch_instruction(dest + 1, instr[1]); |
1556 | + } |
1557 | + |
1558 | + printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i); |
1559 | +} |
1560 | + |
1561 | +static void patch_btb_flush_section(long *curr) |
1562 | +{ |
1563 | + unsigned int *start, *end; |
1564 | + |
1565 | + start = (void *)curr + *curr; |
1566 | + end = (void *)curr + *(curr + 1); |
1567 | + for (; start < end; start++) { |
1568 | + pr_devel("patching dest %lx\n", (unsigned long)start); |
1569 | + patch_instruction(start, PPC_INST_NOP); |
1570 | + } |
1571 | +} |
1572 | + |
1573 | +void do_btb_flush_fixups(void) |
1574 | +{ |
1575 | + long *start, *end; |
1576 | + |
1577 | + start = PTRRELOC(&__start__btb_flush_fixup); |
1578 | + end = PTRRELOC(&__stop__btb_flush_fixup); |
1579 | + |
1580 | + for (; start < end; start += 2) |
1581 | + patch_btb_flush_section(start); |
1582 | +} |
1583 | +#endif /* CONFIG_PPC_FSL_BOOK3E */ |
1584 | + |
1585 | void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) |
1586 | { |
1587 | long *start, *end; |
1588 | diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S |
1589 | index 786234fd4e91..193909abd18b 100644 |
1590 | --- a/arch/powerpc/lib/memcpy_power7.S |
1591 | +++ b/arch/powerpc/lib/memcpy_power7.S |
1592 | @@ -261,12 +261,12 @@ _GLOBAL(memcpy_power7) |
1593 | |
1594 | .machine push |
1595 | .machine "power4" |
1596 | - dcbt r0,r6,0b01000 |
1597 | - dcbt r0,r7,0b01010 |
1598 | - dcbtst r0,r9,0b01000 |
1599 | - dcbtst r0,r10,0b01010 |
1600 | + dcbt 0,r6,0b01000 |
1601 | + dcbt 0,r7,0b01010 |
1602 | + dcbtst 0,r9,0b01000 |
1603 | + dcbtst 0,r10,0b01010 |
1604 | eieio |
1605 | - dcbt r0,r8,0b01010 /* GO */ |
1606 | + dcbt 0,r8,0b01010 /* GO */ |
1607 | .machine pop |
1608 | |
1609 | beq cr1,.Lunwind_stack_nonvmx_copy |
1610 | @@ -321,26 +321,26 @@ _GLOBAL(memcpy_power7) |
1611 | li r11,48 |
1612 | |
1613 | bf cr7*4+3,5f |
1614 | - lvx v1,r0,r4 |
1615 | + lvx v1,0,r4 |
1616 | addi r4,r4,16 |
1617 | - stvx v1,r0,r3 |
1618 | + stvx v1,0,r3 |
1619 | addi r3,r3,16 |
1620 | |
1621 | 5: bf cr7*4+2,6f |
1622 | - lvx v1,r0,r4 |
1623 | + lvx v1,0,r4 |
1624 | lvx v0,r4,r9 |
1625 | addi r4,r4,32 |
1626 | - stvx v1,r0,r3 |
1627 | + stvx v1,0,r3 |
1628 | stvx v0,r3,r9 |
1629 | addi r3,r3,32 |
1630 | |
1631 | 6: bf cr7*4+1,7f |
1632 | - lvx v3,r0,r4 |
1633 | + lvx v3,0,r4 |
1634 | lvx v2,r4,r9 |
1635 | lvx v1,r4,r10 |
1636 | lvx v0,r4,r11 |
1637 | addi r4,r4,64 |
1638 | - stvx v3,r0,r3 |
1639 | + stvx v3,0,r3 |
1640 | stvx v2,r3,r9 |
1641 | stvx v1,r3,r10 |
1642 | stvx v0,r3,r11 |
1643 | @@ -366,7 +366,7 @@ _GLOBAL(memcpy_power7) |
1644 | */ |
1645 | .align 5 |
1646 | 8: |
1647 | - lvx v7,r0,r4 |
1648 | + lvx v7,0,r4 |
1649 | lvx v6,r4,r9 |
1650 | lvx v5,r4,r10 |
1651 | lvx v4,r4,r11 |
1652 | @@ -375,7 +375,7 @@ _GLOBAL(memcpy_power7) |
1653 | lvx v1,r4,r15 |
1654 | lvx v0,r4,r16 |
1655 | addi r4,r4,128 |
1656 | - stvx v7,r0,r3 |
1657 | + stvx v7,0,r3 |
1658 | stvx v6,r3,r9 |
1659 | stvx v5,r3,r10 |
1660 | stvx v4,r3,r11 |
1661 | @@ -396,29 +396,29 @@ _GLOBAL(memcpy_power7) |
1662 | mtocrf 0x01,r6 |
1663 | |
1664 | bf cr7*4+1,9f |
1665 | - lvx v3,r0,r4 |
1666 | + lvx v3,0,r4 |
1667 | lvx v2,r4,r9 |
1668 | lvx v1,r4,r10 |
1669 | lvx v0,r4,r11 |
1670 | addi r4,r4,64 |
1671 | - stvx v3,r0,r3 |
1672 | + stvx v3,0,r3 |
1673 | stvx v2,r3,r9 |
1674 | stvx v1,r3,r10 |
1675 | stvx v0,r3,r11 |
1676 | addi r3,r3,64 |
1677 | |
1678 | 9: bf cr7*4+2,10f |
1679 | - lvx v1,r0,r4 |
1680 | + lvx v1,0,r4 |
1681 | lvx v0,r4,r9 |
1682 | addi r4,r4,32 |
1683 | - stvx v1,r0,r3 |
1684 | + stvx v1,0,r3 |
1685 | stvx v0,r3,r9 |
1686 | addi r3,r3,32 |
1687 | |
1688 | 10: bf cr7*4+3,11f |
1689 | - lvx v1,r0,r4 |
1690 | + lvx v1,0,r4 |
1691 | addi r4,r4,16 |
1692 | - stvx v1,r0,r3 |
1693 | + stvx v1,0,r3 |
1694 | addi r3,r3,16 |
1695 | |
1696 | /* Up to 15B to go */ |
1697 | @@ -499,25 +499,25 @@ _GLOBAL(memcpy_power7) |
1698 | addi r4,r4,16 |
1699 | |
1700 | bf cr7*4+3,5f |
1701 | - lvx v1,r0,r4 |
1702 | + lvx v1,0,r4 |
1703 | VPERM(v8,v0,v1,v16) |
1704 | addi r4,r4,16 |
1705 | - stvx v8,r0,r3 |
1706 | + stvx v8,0,r3 |
1707 | addi r3,r3,16 |
1708 | vor v0,v1,v1 |
1709 | |
1710 | 5: bf cr7*4+2,6f |
1711 | - lvx v1,r0,r4 |
1712 | + lvx v1,0,r4 |
1713 | VPERM(v8,v0,v1,v16) |
1714 | lvx v0,r4,r9 |
1715 | VPERM(v9,v1,v0,v16) |
1716 | addi r4,r4,32 |
1717 | - stvx v8,r0,r3 |
1718 | + stvx v8,0,r3 |
1719 | stvx v9,r3,r9 |
1720 | addi r3,r3,32 |
1721 | |
1722 | 6: bf cr7*4+1,7f |
1723 | - lvx v3,r0,r4 |
1724 | + lvx v3,0,r4 |
1725 | VPERM(v8,v0,v3,v16) |
1726 | lvx v2,r4,r9 |
1727 | VPERM(v9,v3,v2,v16) |
1728 | @@ -526,7 +526,7 @@ _GLOBAL(memcpy_power7) |
1729 | lvx v0,r4,r11 |
1730 | VPERM(v11,v1,v0,v16) |
1731 | addi r4,r4,64 |
1732 | - stvx v8,r0,r3 |
1733 | + stvx v8,0,r3 |
1734 | stvx v9,r3,r9 |
1735 | stvx v10,r3,r10 |
1736 | stvx v11,r3,r11 |
1737 | @@ -552,7 +552,7 @@ _GLOBAL(memcpy_power7) |
1738 | */ |
1739 | .align 5 |
1740 | 8: |
1741 | - lvx v7,r0,r4 |
1742 | + lvx v7,0,r4 |
1743 | VPERM(v8,v0,v7,v16) |
1744 | lvx v6,r4,r9 |
1745 | VPERM(v9,v7,v6,v16) |
1746 | @@ -569,7 +569,7 @@ _GLOBAL(memcpy_power7) |
1747 | lvx v0,r4,r16 |
1748 | VPERM(v15,v1,v0,v16) |
1749 | addi r4,r4,128 |
1750 | - stvx v8,r0,r3 |
1751 | + stvx v8,0,r3 |
1752 | stvx v9,r3,r9 |
1753 | stvx v10,r3,r10 |
1754 | stvx v11,r3,r11 |
1755 | @@ -590,7 +590,7 @@ _GLOBAL(memcpy_power7) |
1756 | mtocrf 0x01,r6 |
1757 | |
1758 | bf cr7*4+1,9f |
1759 | - lvx v3,r0,r4 |
1760 | + lvx v3,0,r4 |
1761 | VPERM(v8,v0,v3,v16) |
1762 | lvx v2,r4,r9 |
1763 | VPERM(v9,v3,v2,v16) |
1764 | @@ -599,27 +599,27 @@ _GLOBAL(memcpy_power7) |
1765 | lvx v0,r4,r11 |
1766 | VPERM(v11,v1,v0,v16) |
1767 | addi r4,r4,64 |
1768 | - stvx v8,r0,r3 |
1769 | + stvx v8,0,r3 |
1770 | stvx v9,r3,r9 |
1771 | stvx v10,r3,r10 |
1772 | stvx v11,r3,r11 |
1773 | addi r3,r3,64 |
1774 | |
1775 | 9: bf cr7*4+2,10f |
1776 | - lvx v1,r0,r4 |
1777 | + lvx v1,0,r4 |
1778 | VPERM(v8,v0,v1,v16) |
1779 | lvx v0,r4,r9 |
1780 | VPERM(v9,v1,v0,v16) |
1781 | addi r4,r4,32 |
1782 | - stvx v8,r0,r3 |
1783 | + stvx v8,0,r3 |
1784 | stvx v9,r3,r9 |
1785 | addi r3,r3,32 |
1786 | |
1787 | 10: bf cr7*4+3,11f |
1788 | - lvx v1,r0,r4 |
1789 | + lvx v1,0,r4 |
1790 | VPERM(v8,v0,v1,v16) |
1791 | addi r4,r4,16 |
1792 | - stvx v8,r0,r3 |
1793 | + stvx v8,0,r3 |
1794 | addi r3,r3,16 |
1795 | |
1796 | /* Up to 15B to go */ |
1797 | diff --git a/arch/powerpc/lib/string_64.S b/arch/powerpc/lib/string_64.S |
1798 | index 57ace356c949..11e6372537fd 100644 |
1799 | --- a/arch/powerpc/lib/string_64.S |
1800 | +++ b/arch/powerpc/lib/string_64.S |
1801 | @@ -192,7 +192,7 @@ err1; std r0,8(r3) |
1802 | mtctr r6 |
1803 | mr r8,r3 |
1804 | 14: |
1805 | -err1; dcbz r0,r3 |
1806 | +err1; dcbz 0,r3 |
1807 | add r3,r3,r9 |
1808 | bdnz 14b |
1809 | |
1810 | diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c |
1811 | index 5f844337de21..1e93dbc88e80 100644 |
1812 | --- a/arch/powerpc/mm/mem.c |
1813 | +++ b/arch/powerpc/mm/mem.c |
1814 | @@ -62,6 +62,7 @@ |
1815 | #endif |
1816 | |
1817 | unsigned long long memory_limit; |
1818 | +bool init_mem_is_free; |
1819 | |
1820 | #ifdef CONFIG_HIGHMEM |
1821 | pte_t *kmap_pte; |
1822 | @@ -396,6 +397,7 @@ void __init mem_init(void) |
1823 | void free_initmem(void) |
1824 | { |
1825 | ppc_md.progress = ppc_printk_progress; |
1826 | + init_mem_is_free = true; |
1827 | free_initmem_default(POISON_FREE_INITMEM); |
1828 | } |
1829 | |
1830 | diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S |
1831 | index eb82d787d99a..b7e9c09dfe19 100644 |
1832 | --- a/arch/powerpc/mm/tlb_low_64e.S |
1833 | +++ b/arch/powerpc/mm/tlb_low_64e.S |
1834 | @@ -69,6 +69,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) |
1835 | std r15,EX_TLB_R15(r12) |
1836 | std r10,EX_TLB_CR(r12) |
1837 | #ifdef CONFIG_PPC_FSL_BOOK3E |
1838 | +START_BTB_FLUSH_SECTION |
1839 | + mfspr r11, SPRN_SRR1 |
1840 | + andi. r10,r11,MSR_PR |
1841 | + beq 1f |
1842 | + BTB_FLUSH(r10) |
1843 | +1: |
1844 | +END_BTB_FLUSH_SECTION |
1845 | std r7,EX_TLB_R7(r12) |
1846 | #endif |
1847 | TLB_MISS_PROLOG_STATS |
1848 | diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c |
1849 | index 17203abf38e8..365e2b620201 100644 |
1850 | --- a/arch/powerpc/platforms/powernv/setup.c |
1851 | +++ b/arch/powerpc/platforms/powernv/setup.c |
1852 | @@ -77,6 +77,12 @@ static void init_fw_feat_flags(struct device_node *np) |
1853 | if (fw_feature_is("enabled", "fw-count-cache-disabled", np)) |
1854 | security_ftr_set(SEC_FTR_COUNT_CACHE_DISABLED); |
1855 | |
1856 | + if (fw_feature_is("enabled", "fw-count-cache-flush-bcctr2,0,0", np)) |
1857 | + security_ftr_set(SEC_FTR_BCCTR_FLUSH_ASSIST); |
1858 | + |
1859 | + if (fw_feature_is("enabled", "needs-count-cache-flush-on-context-switch", np)) |
1860 | + security_ftr_set(SEC_FTR_FLUSH_COUNT_CACHE); |
1861 | + |
1862 | /* |
1863 | * The features below are enabled by default, so we instead look to see |
1864 | * if firmware has *disabled* them, and clear them if so. |
1865 | @@ -123,6 +129,7 @@ static void pnv_setup_rfi_flush(void) |
1866 | security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV)); |
1867 | |
1868 | setup_rfi_flush(type, enable); |
1869 | + setup_count_cache_flush(); |
1870 | } |
1871 | |
1872 | static void __init pnv_setup_arch(void) |
1873 | diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c |
1874 | index 91ade7755823..adb09ab87f7c 100644 |
1875 | --- a/arch/powerpc/platforms/pseries/setup.c |
1876 | +++ b/arch/powerpc/platforms/pseries/setup.c |
1877 | @@ -475,6 +475,12 @@ static void init_cpu_char_feature_flags(struct h_cpu_char_result *result) |
1878 | if (result->character & H_CPU_CHAR_COUNT_CACHE_DISABLED) |
1879 | security_ftr_set(SEC_FTR_COUNT_CACHE_DISABLED); |
1880 | |
1881 | + if (result->character & H_CPU_CHAR_BCCTR_FLUSH_ASSIST) |
1882 | + security_ftr_set(SEC_FTR_BCCTR_FLUSH_ASSIST); |
1883 | + |
1884 | + if (result->behaviour & H_CPU_BEHAV_FLUSH_COUNT_CACHE) |
1885 | + security_ftr_set(SEC_FTR_FLUSH_COUNT_CACHE); |
1886 | + |
1887 | /* |
1888 | * The features below are enabled by default, so we instead look to see |
1889 | * if firmware has *disabled* them, and clear them if so. |
1890 | @@ -525,6 +531,7 @@ void pseries_setup_rfi_flush(void) |
1891 | security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR); |
1892 | |
1893 | setup_rfi_flush(types, enable); |
1894 | + setup_count_cache_flush(); |
1895 | } |
1896 | |
1897 | static void __init pSeries_setup_arch(void) |
1898 | diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile |
1899 | index d5409660f5de..756dc9432d15 100644 |
1900 | --- a/arch/x86/entry/vdso/Makefile |
1901 | +++ b/arch/x86/entry/vdso/Makefile |
1902 | @@ -47,10 +47,8 @@ targets += $(vdso_img_sodbg) |
1903 | |
1904 | export CPPFLAGS_vdso.lds += -P -C |
1905 | |
1906 | -VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ |
1907 | - -Wl,--no-undefined \ |
1908 | - -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 \ |
1909 | - $(DISABLE_LTO) |
1910 | +VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -soname linux-vdso.so.1 --no-undefined \ |
1911 | + -z max-page-size=4096 |
1912 | |
1913 | $(obj)/vdso64.so.dbg: $(src)/vdso.lds $(vobjs) FORCE |
1914 | $(call if_changed,vdso) |
1915 | @@ -96,10 +94,8 @@ CFLAGS_REMOVE_vvar.o = -pg |
1916 | # |
1917 | |
1918 | CPPFLAGS_vdsox32.lds = $(CPPFLAGS_vdso.lds) |
1919 | -VDSO_LDFLAGS_vdsox32.lds = -Wl,-m,elf32_x86_64 \ |
1920 | - -Wl,-soname=linux-vdso.so.1 \ |
1921 | - -Wl,-z,max-page-size=4096 \ |
1922 | - -Wl,-z,common-page-size=4096 |
1923 | +VDSO_LDFLAGS_vdsox32.lds = -m elf32_x86_64 -soname linux-vdso.so.1 \ |
1924 | + -z max-page-size=4096 |
1925 | |
1926 | # 64-bit objects to re-brand as x32 |
1927 | vobjs64-for-x32 := $(filter-out $(vobjs-nox32),$(vobjs-y)) |
1928 | @@ -127,7 +123,7 @@ $(obj)/vdsox32.so.dbg: $(src)/vdsox32.lds $(vobjx32s) FORCE |
1929 | $(call if_changed,vdso) |
1930 | |
1931 | CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds) |
1932 | -VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-m,elf_i386 -Wl,-soname=linux-gate.so.1 |
1933 | +VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -soname linux-gate.so.1 |
1934 | |
1935 | # This makes sure the $(obj) subdirectory exists even though vdso32/ |
1936 | # is not a kbuild sub-make subdirectory. |
1937 | @@ -165,13 +161,13 @@ $(obj)/vdso32.so.dbg: FORCE \ |
1938 | # The DSO images are built using a special linker script. |
1939 | # |
1940 | quiet_cmd_vdso = VDSO $@ |
1941 | - cmd_vdso = $(CC) -nostdlib -o $@ \ |
1942 | + cmd_vdso = $(LD) -nostdlib -o $@ \ |
1943 | $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ |
1944 | - -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \ |
1945 | + -T $(filter %.lds,$^) $(filter %.o,$^) && \ |
1946 | sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' |
1947 | |
1948 | -VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=both) \ |
1949 | - $(call cc-ldoption, -Wl$(comma)--build-id) -Wl,-Bsymbolic $(LTO_CFLAGS) |
1950 | +VDSO_LDFLAGS = -shared $(call ld-option, --hash-style=both) \ |
1951 | + $(call ld-option, --build-id) -Bsymbolic |
1952 | GCOV_PROFILE := n |
1953 | |
1954 | # |
1955 | diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h |
1956 | index 8e9dbe7b73a1..5cc2ce4ab8a3 100644 |
1957 | --- a/arch/x86/include/asm/suspend_32.h |
1958 | +++ b/arch/x86/include/asm/suspend_32.h |
1959 | @@ -11,7 +11,13 @@ |
1960 | |
1961 | /* image of the saved processor state */ |
1962 | struct saved_context { |
1963 | - u16 es, fs, gs, ss; |
1964 | + /* |
1965 | + * On x86_32, all segment registers, with the possible exception of |
1966 | + * gs, are saved at kernel entry in pt_regs. |
1967 | + */ |
1968 | +#ifdef CONFIG_X86_32_LAZY_GS |
1969 | + u16 gs; |
1970 | +#endif |
1971 | unsigned long cr0, cr2, cr3, cr4; |
1972 | u64 misc_enable; |
1973 | bool misc_enable_saved; |
1974 | diff --git a/arch/x86/include/asm/suspend_64.h b/arch/x86/include/asm/suspend_64.h |
1975 | index 2bd96b4df140..701751918921 100644 |
1976 | --- a/arch/x86/include/asm/suspend_64.h |
1977 | +++ b/arch/x86/include/asm/suspend_64.h |
1978 | @@ -19,8 +19,20 @@ |
1979 | */ |
1980 | struct saved_context { |
1981 | struct pt_regs regs; |
1982 | - u16 ds, es, fs, gs, ss; |
1983 | - unsigned long gs_base, gs_kernel_base, fs_base; |
1984 | + |
1985 | + /* |
1986 | + * User CS and SS are saved in current_pt_regs(). The rest of the |
1987 | + * segment selectors need to be saved and restored here. |
1988 | + */ |
1989 | + u16 ds, es, fs, gs; |
1990 | + |
1991 | + /* |
1992 | + * Usermode FSBASE and GSBASE may not match the fs and gs selectors, |
1993 | + * so we save them separately. We save the kernelmode GSBASE to |
1994 | + * restore percpu access after resume. |
1995 | + */ |
1996 | + unsigned long kernelmode_gs_base, usermode_gs_base, fs_base; |
1997 | + |
1998 | unsigned long cr0, cr2, cr3, cr4, cr8; |
1999 | u64 misc_enable; |
2000 | bool misc_enable_saved; |
2001 | @@ -29,8 +41,7 @@ struct saved_context { |
2002 | u16 gdt_pad; /* Unused */ |
2003 | struct desc_ptr gdt_desc; |
2004 | u16 idt_pad; |
2005 | - u16 idt_limit; |
2006 | - unsigned long idt_base; |
2007 | + struct desc_ptr idt; |
2008 | u16 ldt; |
2009 | u16 tss; |
2010 | unsigned long tr; |
2011 | diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h |
2012 | index ccdc23d89b60..9f694537a103 100644 |
2013 | --- a/arch/x86/include/asm/xen/hypercall.h |
2014 | +++ b/arch/x86/include/asm/xen/hypercall.h |
2015 | @@ -216,6 +216,9 @@ privcmd_call(unsigned call, |
2016 | __HYPERCALL_DECLS; |
2017 | __HYPERCALL_5ARG(a1, a2, a3, a4, a5); |
2018 | |
2019 | + if (call >= PAGE_SIZE / sizeof(hypercall_page[0])) |
2020 | + return -EINVAL; |
2021 | + |
2022 | stac(); |
2023 | asm volatile(CALL_NOSPEC |
2024 | : __HYPERCALL_5PARAM |
2025 | diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c |
2026 | index 53cace2ec0e2..054e27671df9 100644 |
2027 | --- a/arch/x86/power/cpu.c |
2028 | +++ b/arch/x86/power/cpu.c |
2029 | @@ -82,12 +82,8 @@ static void __save_processor_state(struct saved_context *ctxt) |
2030 | /* |
2031 | * descriptor tables |
2032 | */ |
2033 | -#ifdef CONFIG_X86_32 |
2034 | store_idt(&ctxt->idt); |
2035 | -#else |
2036 | -/* CONFIG_X86_64 */ |
2037 | - store_idt((struct desc_ptr *)&ctxt->idt_limit); |
2038 | -#endif |
2039 | + |
2040 | /* |
2041 | * We save it here, but restore it only in the hibernate case. |
2042 | * For ACPI S3 resume, this is loaded via 'early_gdt_desc' in 64-bit |
2043 | @@ -103,22 +99,18 @@ static void __save_processor_state(struct saved_context *ctxt) |
2044 | /* |
2045 | * segment registers |
2046 | */ |
2047 | -#ifdef CONFIG_X86_32 |
2048 | - savesegment(es, ctxt->es); |
2049 | - savesegment(fs, ctxt->fs); |
2050 | +#ifdef CONFIG_X86_32_LAZY_GS |
2051 | savesegment(gs, ctxt->gs); |
2052 | - savesegment(ss, ctxt->ss); |
2053 | -#else |
2054 | -/* CONFIG_X86_64 */ |
2055 | - asm volatile ("movw %%ds, %0" : "=m" (ctxt->ds)); |
2056 | - asm volatile ("movw %%es, %0" : "=m" (ctxt->es)); |
2057 | - asm volatile ("movw %%fs, %0" : "=m" (ctxt->fs)); |
2058 | - asm volatile ("movw %%gs, %0" : "=m" (ctxt->gs)); |
2059 | - asm volatile ("movw %%ss, %0" : "=m" (ctxt->ss)); |
2060 | +#endif |
2061 | +#ifdef CONFIG_X86_64 |
2062 | + savesegment(gs, ctxt->gs); |
2063 | + savesegment(fs, ctxt->fs); |
2064 | + savesegment(ds, ctxt->ds); |
2065 | + savesegment(es, ctxt->es); |
2066 | |
2067 | rdmsrl(MSR_FS_BASE, ctxt->fs_base); |
2068 | - rdmsrl(MSR_GS_BASE, ctxt->gs_base); |
2069 | - rdmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); |
2070 | + rdmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base); |
2071 | + rdmsrl(MSR_KERNEL_GS_BASE, ctxt->usermode_gs_base); |
2072 | mtrr_save_fixed_ranges(NULL); |
2073 | |
2074 | rdmsrl(MSR_EFER, ctxt->efer); |
2075 | @@ -178,6 +170,9 @@ static void fix_processor_context(void) |
2076 | write_gdt_entry(desc, GDT_ENTRY_TSS, &tss, DESC_TSS); |
2077 | |
2078 | syscall_init(); /* This sets MSR_*STAR and related */ |
2079 | +#else |
2080 | + if (boot_cpu_has(X86_FEATURE_SEP)) |
2081 | + enable_sep_cpu(); |
2082 | #endif |
2083 | load_TR_desc(); /* This does ltr */ |
2084 | load_mm_ldt(current->active_mm); /* This does lldt */ |
2085 | @@ -186,9 +181,12 @@ static void fix_processor_context(void) |
2086 | } |
2087 | |
2088 | /** |
2089 | - * __restore_processor_state - restore the contents of CPU registers saved |
2090 | - * by __save_processor_state() |
2091 | - * @ctxt - structure to load the registers contents from |
2092 | + * __restore_processor_state - restore the contents of CPU registers saved |
2093 | + * by __save_processor_state() |
2094 | + * @ctxt - structure to load the registers contents from |
2095 | + * |
2096 | + * The asm code that gets us here will have restored a usable GDT, although |
2097 | + * it will be pointing to the wrong alias. |
2098 | */ |
2099 | static void notrace __restore_processor_state(struct saved_context *ctxt) |
2100 | { |
2101 | @@ -211,46 +209,52 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) |
2102 | write_cr2(ctxt->cr2); |
2103 | write_cr0(ctxt->cr0); |
2104 | |
2105 | + /* Restore the IDT. */ |
2106 | + load_idt(&ctxt->idt); |
2107 | + |
2108 | /* |
2109 | - * now restore the descriptor tables to their proper values |
2110 | - * ltr is done i fix_processor_context(). |
2111 | + * Just in case the asm code got us here with the SS, DS, or ES |
2112 | + * out of sync with the GDT, update them. |
2113 | */ |
2114 | -#ifdef CONFIG_X86_32 |
2115 | - load_idt(&ctxt->idt); |
2116 | + loadsegment(ss, __KERNEL_DS); |
2117 | + loadsegment(ds, __USER_DS); |
2118 | + loadsegment(es, __USER_DS); |
2119 | + |
2120 | + /* |
2121 | + * Restore percpu access. Percpu access can happen in exception |
2122 | + * handlers or in complicated helpers like load_gs_index(). |
2123 | + */ |
2124 | +#ifdef CONFIG_X86_64 |
2125 | + wrmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base); |
2126 | #else |
2127 | -/* CONFIG_X86_64 */ |
2128 | - load_idt((const struct desc_ptr *)&ctxt->idt_limit); |
2129 | + loadsegment(fs, __KERNEL_PERCPU); |
2130 | + loadsegment(gs, __KERNEL_STACK_CANARY); |
2131 | #endif |
2132 | |
2133 | + /* Restore the TSS, RO GDT, LDT, and usermode-relevant MSRs. */ |
2134 | + fix_processor_context(); |
2135 | + |
2136 | /* |
2137 | - * segment registers |
2138 | + * Now that we have descriptor tables fully restored and working |
2139 | + * exception handling, restore the usermode segments. |
2140 | */ |
2141 | -#ifdef CONFIG_X86_32 |
2142 | +#ifdef CONFIG_X86_64 |
2143 | + loadsegment(ds, ctxt->es); |
2144 | loadsegment(es, ctxt->es); |
2145 | loadsegment(fs, ctxt->fs); |
2146 | - loadsegment(gs, ctxt->gs); |
2147 | - loadsegment(ss, ctxt->ss); |
2148 | + load_gs_index(ctxt->gs); |
2149 | |
2150 | /* |
2151 | - * sysenter MSRs |
2152 | + * Restore FSBASE and GSBASE after restoring the selectors, since |
2153 | + * restoring the selectors clobbers the bases. Keep in mind |
2154 | + * that MSR_KERNEL_GS_BASE is horribly misnamed. |
2155 | */ |
2156 | - if (boot_cpu_has(X86_FEATURE_SEP)) |
2157 | - enable_sep_cpu(); |
2158 | -#else |
2159 | -/* CONFIG_X86_64 */ |
2160 | - asm volatile ("movw %0, %%ds" :: "r" (ctxt->ds)); |
2161 | - asm volatile ("movw %0, %%es" :: "r" (ctxt->es)); |
2162 | - asm volatile ("movw %0, %%fs" :: "r" (ctxt->fs)); |
2163 | - load_gs_index(ctxt->gs); |
2164 | - asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss)); |
2165 | - |
2166 | wrmsrl(MSR_FS_BASE, ctxt->fs_base); |
2167 | - wrmsrl(MSR_GS_BASE, ctxt->gs_base); |
2168 | - wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); |
2169 | + wrmsrl(MSR_KERNEL_GS_BASE, ctxt->usermode_gs_base); |
2170 | +#elif defined(CONFIG_X86_32_LAZY_GS) |
2171 | + loadsegment(gs, ctxt->gs); |
2172 | #endif |
2173 | |
2174 | - fix_processor_context(); |
2175 | - |
2176 | do_fpu_end(); |
2177 | x86_platform.restore_sched_clock_state(); |
2178 | mtrr_bp_restore(); |
2179 | diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c |
2180 | index 7538d802b65a..483593068139 100644 |
2181 | --- a/arch/xtensa/kernel/stacktrace.c |
2182 | +++ b/arch/xtensa/kernel/stacktrace.c |
2183 | @@ -272,10 +272,14 @@ static int return_address_cb(struct stackframe *frame, void *data) |
2184 | return 1; |
2185 | } |
2186 | |
2187 | +/* |
2188 | + * level == 0 is for the return address from the caller of this function, |
2189 | + * not from this function itself. |
2190 | + */ |
2191 | unsigned long return_address(unsigned level) |
2192 | { |
2193 | struct return_addr_data r = { |
2194 | - .skip = level + 1, |
2195 | + .skip = level, |
2196 | }; |
2197 | walk_stackframe(stack_pointer(NULL), return_address_cb, &r); |
2198 | return r.addr; |
2199 | diff --git a/block/bio.c b/block/bio.c |
2200 | index 68972e3d3f5c..4c18a68913de 100644 |
2201 | --- a/block/bio.c |
2202 | +++ b/block/bio.c |
2203 | @@ -1214,8 +1214,11 @@ struct bio *bio_copy_user_iov(struct request_queue *q, |
2204 | } |
2205 | } |
2206 | |
2207 | - if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes) |
2208 | + if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes) { |
2209 | + if (!map_data) |
2210 | + __free_page(page); |
2211 | break; |
2212 | + } |
2213 | |
2214 | len -= bytes; |
2215 | offset = 0; |
2216 | diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig |
2217 | index 8453a49471d7..f4ae000eb285 100644 |
2218 | --- a/drivers/char/Kconfig |
2219 | +++ b/drivers/char/Kconfig |
2220 | @@ -377,7 +377,7 @@ config XILINX_HWICAP |
2221 | |
2222 | config R3964 |
2223 | tristate "Siemens R3964 line discipline" |
2224 | - depends on TTY |
2225 | + depends on TTY && BROKEN |
2226 | ---help--- |
2227 | This driver allows synchronous communication with devices using the |
2228 | Siemens R3964 packet protocol. Unless you are dealing with special |
2229 | diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
2230 | index 737f0f6f4075..45ea2718c65d 100644 |
2231 | --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
2232 | +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
2233 | @@ -959,6 +959,8 @@ static void bnxt_tpa_start(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, |
2234 | tpa_info = &rxr->rx_tpa[agg_id]; |
2235 | |
2236 | if (unlikely(cons != rxr->rx_next_cons)) { |
2237 | + netdev_warn(bp->dev, "TPA cons %x != expected cons %x\n", |
2238 | + cons, rxr->rx_next_cons); |
2239 | bnxt_sched_reset(bp, rxr); |
2240 | return; |
2241 | } |
2242 | @@ -1377,14 +1379,16 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons, |
2243 | } |
2244 | |
2245 | cons = rxcmp->rx_cmp_opaque; |
2246 | - rx_buf = &rxr->rx_buf_ring[cons]; |
2247 | - data = rx_buf->data; |
2248 | if (unlikely(cons != rxr->rx_next_cons)) { |
2249 | int rc1 = bnxt_discard_rx(bp, bnapi, raw_cons, rxcmp); |
2250 | |
2251 | + netdev_warn(bp->dev, "RX cons %x != expected cons %x\n", |
2252 | + cons, rxr->rx_next_cons); |
2253 | bnxt_sched_reset(bp, rxr); |
2254 | return rc1; |
2255 | } |
2256 | + rx_buf = &rxr->rx_buf_ring[cons]; |
2257 | + data = rx_buf->data; |
2258 | prefetch(data); |
2259 | |
2260 | agg_bufs = (le32_to_cpu(rxcmp->rx_cmp_misc_v1) & RX_CMP_AGG_BUFS) >> |
2261 | @@ -1400,11 +1404,17 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons, |
2262 | |
2263 | rx_buf->data = NULL; |
2264 | if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L2_ERRORS) { |
2265 | + u32 rx_err = le32_to_cpu(rxcmp1->rx_cmp_cfa_code_errors_v2); |
2266 | + |
2267 | bnxt_reuse_rx_data(rxr, cons, data); |
2268 | if (agg_bufs) |
2269 | bnxt_reuse_rx_agg_bufs(bnapi, cp_cons, agg_bufs); |
2270 | |
2271 | rc = -EIO; |
2272 | + if (rx_err & RX_CMPL_ERRORS_BUFFER_ERROR_MASK) { |
2273 | + netdev_warn(bp->dev, "RX buffer error %x\n", rx_err); |
2274 | + bnxt_sched_reset(bp, rxr); |
2275 | + } |
2276 | goto next_rx; |
2277 | } |
2278 | |
2279 | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c |
2280 | index 029e856f72a0..dc809c2ea413 100644 |
2281 | --- a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c |
2282 | +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c |
2283 | @@ -45,7 +45,9 @@ int mlx5e_create_tir(struct mlx5_core_dev *mdev, |
2284 | if (err) |
2285 | return err; |
2286 | |
2287 | + mutex_lock(&mdev->mlx5e_res.td.list_lock); |
2288 | list_add(&tir->list, &mdev->mlx5e_res.td.tirs_list); |
2289 | + mutex_unlock(&mdev->mlx5e_res.td.list_lock); |
2290 | |
2291 | return 0; |
2292 | } |
2293 | @@ -53,8 +55,10 @@ int mlx5e_create_tir(struct mlx5_core_dev *mdev, |
2294 | void mlx5e_destroy_tir(struct mlx5_core_dev *mdev, |
2295 | struct mlx5e_tir *tir) |
2296 | { |
2297 | + mutex_lock(&mdev->mlx5e_res.td.list_lock); |
2298 | mlx5_core_destroy_tir(mdev, tir->tirn); |
2299 | list_del(&tir->list); |
2300 | + mutex_unlock(&mdev->mlx5e_res.td.list_lock); |
2301 | } |
2302 | |
2303 | static int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn, |
2304 | @@ -114,6 +118,7 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev) |
2305 | } |
2306 | |
2307 | INIT_LIST_HEAD(&mdev->mlx5e_res.td.tirs_list); |
2308 | + mutex_init(&mdev->mlx5e_res.td.list_lock); |
2309 | |
2310 | return 0; |
2311 | |
2312 | @@ -151,6 +156,7 @@ int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5_core_dev *mdev) |
2313 | |
2314 | MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1); |
2315 | |
2316 | + mutex_lock(&mdev->mlx5e_res.td.list_lock); |
2317 | list_for_each_entry(tir, &mdev->mlx5e_res.td.tirs_list, list) { |
2318 | err = mlx5_core_modify_tir(mdev, tir->tirn, in, inlen); |
2319 | if (err) |
2320 | @@ -159,6 +165,7 @@ int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5_core_dev *mdev) |
2321 | |
2322 | out: |
2323 | kvfree(in); |
2324 | + mutex_unlock(&mdev->mlx5e_res.td.list_lock); |
2325 | |
2326 | return err; |
2327 | } |
2328 | diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c |
2329 | index 16e5c8cd104d..d51ad140f46d 100644 |
2330 | --- a/drivers/net/usb/qmi_wwan.c |
2331 | +++ b/drivers/net/usb/qmi_wwan.c |
2332 | @@ -890,6 +890,7 @@ static const struct usb_device_id products[] = { |
2333 | {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ |
2334 | {QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */ |
2335 | {QMI_FIXED_INTF(0x2001, 0x7e35, 4)}, /* D-Link DWM-222 */ |
2336 | + {QMI_FIXED_INTF(0x2020, 0x2031, 4)}, /* Olicard 600 */ |
2337 | {QMI_FIXED_INTF(0x2020, 0x2033, 4)}, /* BroadMobi BM806U */ |
2338 | {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ |
2339 | {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ |
2340 | diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c |
2341 | index dedb12083d86..6663b76934ad 100644 |
2342 | --- a/drivers/pci/quirks.c |
2343 | +++ b/drivers/pci/quirks.c |
2344 | @@ -3866,6 +3866,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9128, |
2345 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c14 */ |
2346 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9130, |
2347 | quirk_dma_func1_alias); |
2348 | +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9170, |
2349 | + quirk_dma_func1_alias); |
2350 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c47 + c57 */ |
2351 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9172, |
2352 | quirk_dma_func1_alias); |
2353 | diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig |
2354 | index 95103054c0e4..fdd2860cb9bd 100644 |
2355 | --- a/drivers/tty/Kconfig |
2356 | +++ b/drivers/tty/Kconfig |
2357 | @@ -455,4 +455,27 @@ config MIPS_EJTAG_FDC_KGDB_CHAN |
2358 | help |
2359 | FDC channel number to use for KGDB. |
2360 | |
2361 | +config LDISC_AUTOLOAD |
2362 | + bool "Automatically load TTY Line Disciplines" |
2363 | + default y |
2364 | + help |
2365 | + Historically the kernel has always automatically loaded any |
2366 | + line discipline that is in a kernel module when a user asks |
2367 | + for it to be loaded with the TIOCSETD ioctl, or through other |
2368 | + means. This is not always the best thing to do on systems |
2369 | + where you know you will not be using some of the more |
2370 | + "ancient" line disciplines, so prevent the kernel from doing |
2371 | + this unless the request is coming from a process with the |
2372 | + CAP_SYS_MODULE permissions. |
2373 | + |
2374 | + Say 'Y' here if you trust your userspace users to do the right |
2375 | + thing, or if you have only provided the line disciplines that |
2376 | + you know you will be using, or if you wish to continue to use |
2377 | + the traditional method of on-demand loading of these modules |
2378 | + by any user. |
2379 | + |
2380 | + This functionality can be changed at runtime with the |
2381 | + dev.tty.ldisc_autoload sysctl, this configuration option will |
2382 | + only set the default value of this functionality. |
2383 | + |
2384 | endif # TTY |
2385 | diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c |
2386 | index 19fe1e8fc124..15e0116e1232 100644 |
2387 | --- a/drivers/tty/tty_io.c |
2388 | +++ b/drivers/tty/tty_io.c |
2389 | @@ -520,6 +520,8 @@ void proc_clear_tty(struct task_struct *p) |
2390 | tty_kref_put(tty); |
2391 | } |
2392 | |
2393 | +extern void tty_sysctl_init(void); |
2394 | + |
2395 | /** |
2396 | * proc_set_tty - set the controlling terminal |
2397 | * |
2398 | @@ -3705,6 +3707,7 @@ void console_sysfs_notify(void) |
2399 | */ |
2400 | int __init tty_init(void) |
2401 | { |
2402 | + tty_sysctl_init(); |
2403 | cdev_init(&tty_cdev, &tty_fops); |
2404 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || |
2405 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) |
2406 | diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c |
2407 | index 4ab518d43758..3eb3f2a03bbb 100644 |
2408 | --- a/drivers/tty/tty_ldisc.c |
2409 | +++ b/drivers/tty/tty_ldisc.c |
2410 | @@ -155,6 +155,13 @@ static void put_ldops(struct tty_ldisc_ops *ldops) |
2411 | * takes tty_ldiscs_lock to guard against ldisc races |
2412 | */ |
2413 | |
2414 | +#if defined(CONFIG_LDISC_AUTOLOAD) |
2415 | + #define INITIAL_AUTOLOAD_STATE 1 |
2416 | +#else |
2417 | + #define INITIAL_AUTOLOAD_STATE 0 |
2418 | +#endif |
2419 | +static int tty_ldisc_autoload = INITIAL_AUTOLOAD_STATE; |
2420 | + |
2421 | static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc) |
2422 | { |
2423 | struct tty_ldisc *ld; |
2424 | @@ -169,6 +176,8 @@ static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc) |
2425 | */ |
2426 | ldops = get_ldops(disc); |
2427 | if (IS_ERR(ldops)) { |
2428 | + if (!capable(CAP_SYS_MODULE) && !tty_ldisc_autoload) |
2429 | + return ERR_PTR(-EPERM); |
2430 | request_module("tty-ldisc-%d", disc); |
2431 | ldops = get_ldops(disc); |
2432 | if (IS_ERR(ldops)) |
2433 | @@ -774,3 +783,41 @@ void tty_ldisc_deinit(struct tty_struct *tty) |
2434 | tty_ldisc_put(tty->ldisc); |
2435 | tty->ldisc = NULL; |
2436 | } |
2437 | + |
2438 | +static int zero; |
2439 | +static int one = 1; |
2440 | +static struct ctl_table tty_table[] = { |
2441 | + { |
2442 | + .procname = "ldisc_autoload", |
2443 | + .data = &tty_ldisc_autoload, |
2444 | + .maxlen = sizeof(tty_ldisc_autoload), |
2445 | + .mode = 0644, |
2446 | + .proc_handler = proc_dointvec, |
2447 | + .extra1 = &zero, |
2448 | + .extra2 = &one, |
2449 | + }, |
2450 | + { } |
2451 | +}; |
2452 | + |
2453 | +static struct ctl_table tty_dir_table[] = { |
2454 | + { |
2455 | + .procname = "tty", |
2456 | + .mode = 0555, |
2457 | + .child = tty_table, |
2458 | + }, |
2459 | + { } |
2460 | +}; |
2461 | + |
2462 | +static struct ctl_table tty_root_table[] = { |
2463 | + { |
2464 | + .procname = "dev", |
2465 | + .mode = 0555, |
2466 | + .child = tty_dir_table, |
2467 | + }, |
2468 | + { } |
2469 | +}; |
2470 | + |
2471 | +void tty_sysctl_init(void) |
2472 | +{ |
2473 | + register_sysctl_table(tty_root_table); |
2474 | +} |
2475 | diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c |
2476 | index 8977f40ea441..2f09294c5946 100644 |
2477 | --- a/drivers/virtio/virtio_ring.c |
2478 | +++ b/drivers/virtio/virtio_ring.c |
2479 | @@ -1040,6 +1040,8 @@ struct virtqueue *vring_create_virtqueue( |
2480 | GFP_KERNEL|__GFP_NOWARN|__GFP_ZERO); |
2481 | if (queue) |
2482 | break; |
2483 | + if (!may_reduce_num) |
2484 | + return NULL; |
2485 | } |
2486 | |
2487 | if (!num) |
2488 | diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c |
2489 | index 242584a0d3b5..a67143c579aa 100644 |
2490 | --- a/fs/btrfs/ioctl.c |
2491 | +++ b/fs/btrfs/ioctl.c |
2492 | @@ -385,6 +385,16 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) |
2493 | if (!capable(CAP_SYS_ADMIN)) |
2494 | return -EPERM; |
2495 | |
2496 | + /* |
2497 | + * If the fs is mounted with nologreplay, which requires it to be |
2498 | + * mounted in RO mode as well, we can not allow discard on free space |
2499 | + * inside block groups, because log trees refer to extents that are not |
2500 | + * pinned in a block group's free space cache (pinning the extents is |
2501 | + * precisely the first phase of replaying a log tree). |
2502 | + */ |
2503 | + if (btrfs_test_opt(fs_info, NOLOGREPLAY)) |
2504 | + return -EROFS; |
2505 | + |
2506 | rcu_read_lock(); |
2507 | list_for_each_entry_rcu(device, &fs_info->fs_devices->devices, |
2508 | dev_list) { |
2509 | diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h |
2510 | index fb790b8449c1..333e42cf08de 100644 |
2511 | --- a/include/linux/bitrev.h |
2512 | +++ b/include/linux/bitrev.h |
2513 | @@ -31,32 +31,32 @@ static inline u32 __bitrev32(u32 x) |
2514 | |
2515 | #define __constant_bitrev32(x) \ |
2516 | ({ \ |
2517 | - u32 __x = x; \ |
2518 | - __x = (__x >> 16) | (__x << 16); \ |
2519 | - __x = ((__x & (u32)0xFF00FF00UL) >> 8) | ((__x & (u32)0x00FF00FFUL) << 8); \ |
2520 | - __x = ((__x & (u32)0xF0F0F0F0UL) >> 4) | ((__x & (u32)0x0F0F0F0FUL) << 4); \ |
2521 | - __x = ((__x & (u32)0xCCCCCCCCUL) >> 2) | ((__x & (u32)0x33333333UL) << 2); \ |
2522 | - __x = ((__x & (u32)0xAAAAAAAAUL) >> 1) | ((__x & (u32)0x55555555UL) << 1); \ |
2523 | - __x; \ |
2524 | + u32 ___x = x; \ |
2525 | + ___x = (___x >> 16) | (___x << 16); \ |
2526 | + ___x = ((___x & (u32)0xFF00FF00UL) >> 8) | ((___x & (u32)0x00FF00FFUL) << 8); \ |
2527 | + ___x = ((___x & (u32)0xF0F0F0F0UL) >> 4) | ((___x & (u32)0x0F0F0F0FUL) << 4); \ |
2528 | + ___x = ((___x & (u32)0xCCCCCCCCUL) >> 2) | ((___x & (u32)0x33333333UL) << 2); \ |
2529 | + ___x = ((___x & (u32)0xAAAAAAAAUL) >> 1) | ((___x & (u32)0x55555555UL) << 1); \ |
2530 | + ___x; \ |
2531 | }) |
2532 | |
2533 | #define __constant_bitrev16(x) \ |
2534 | ({ \ |
2535 | - u16 __x = x; \ |
2536 | - __x = (__x >> 8) | (__x << 8); \ |
2537 | - __x = ((__x & (u16)0xF0F0U) >> 4) | ((__x & (u16)0x0F0FU) << 4); \ |
2538 | - __x = ((__x & (u16)0xCCCCU) >> 2) | ((__x & (u16)0x3333U) << 2); \ |
2539 | - __x = ((__x & (u16)0xAAAAU) >> 1) | ((__x & (u16)0x5555U) << 1); \ |
2540 | - __x; \ |
2541 | + u16 ___x = x; \ |
2542 | + ___x = (___x >> 8) | (___x << 8); \ |
2543 | + ___x = ((___x & (u16)0xF0F0U) >> 4) | ((___x & (u16)0x0F0FU) << 4); \ |
2544 | + ___x = ((___x & (u16)0xCCCCU) >> 2) | ((___x & (u16)0x3333U) << 2); \ |
2545 | + ___x = ((___x & (u16)0xAAAAU) >> 1) | ((___x & (u16)0x5555U) << 1); \ |
2546 | + ___x; \ |
2547 | }) |
2548 | |
2549 | #define __constant_bitrev8(x) \ |
2550 | ({ \ |
2551 | - u8 __x = x; \ |
2552 | - __x = (__x >> 4) | (__x << 4); \ |
2553 | - __x = ((__x & (u8)0xCCU) >> 2) | ((__x & (u8)0x33U) << 2); \ |
2554 | - __x = ((__x & (u8)0xAAU) >> 1) | ((__x & (u8)0x55U) << 1); \ |
2555 | - __x; \ |
2556 | + u8 ___x = x; \ |
2557 | + ___x = (___x >> 4) | (___x << 4); \ |
2558 | + ___x = ((___x & (u8)0xCCU) >> 2) | ((___x & (u8)0x33U) << 2); \ |
2559 | + ___x = ((___x & (u8)0xAAU) >> 1) | ((___x & (u8)0x55U) << 1); \ |
2560 | + ___x; \ |
2561 | }) |
2562 | |
2563 | #define bitrev32(x) \ |
2564 | diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h |
2565 | index 859fd209603a..509e99076c57 100644 |
2566 | --- a/include/linux/mlx5/driver.h |
2567 | +++ b/include/linux/mlx5/driver.h |
2568 | @@ -578,6 +578,8 @@ enum mlx5_pci_status { |
2569 | }; |
2570 | |
2571 | struct mlx5_td { |
2572 | + /* protects tirs list changes while tirs refresh */ |
2573 | + struct mutex list_lock; |
2574 | struct list_head tirs_list; |
2575 | u32 tdn; |
2576 | }; |
2577 | diff --git a/include/linux/string.h b/include/linux/string.h |
2578 | index 60042e5e88ff..42eed573ebb6 100644 |
2579 | --- a/include/linux/string.h |
2580 | +++ b/include/linux/string.h |
2581 | @@ -111,6 +111,9 @@ extern void * memscan(void *,int,__kernel_size_t); |
2582 | #ifndef __HAVE_ARCH_MEMCMP |
2583 | extern int memcmp(const void *,const void *,__kernel_size_t); |
2584 | #endif |
2585 | +#ifndef __HAVE_ARCH_BCMP |
2586 | +extern int bcmp(const void *,const void *,__kernel_size_t); |
2587 | +#endif |
2588 | #ifndef __HAVE_ARCH_MEMCHR |
2589 | extern void * memchr(const void *,int,__kernel_size_t); |
2590 | #endif |
2591 | diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h |
2592 | index e8d36938f09a..b38c1871b735 100644 |
2593 | --- a/include/linux/virtio_ring.h |
2594 | +++ b/include/linux/virtio_ring.h |
2595 | @@ -62,7 +62,7 @@ struct virtqueue; |
2596 | /* |
2597 | * Creates a virtqueue and allocates the descriptor ring. If |
2598 | * may_reduce_num is set, then this may allocate a smaller ring than |
2599 | - * expected. The caller should query virtqueue_get_ring_size to learn |
2600 | + * expected. The caller should query virtqueue_get_vring_size to learn |
2601 | * the actual size of the ring. |
2602 | */ |
2603 | struct virtqueue *vring_create_virtqueue(unsigned int index, |
2604 | diff --git a/include/net/ip.h b/include/net/ip.h |
2605 | index f06cd30bb44c..a3c1b9dfc9a1 100644 |
2606 | --- a/include/net/ip.h |
2607 | +++ b/include/net/ip.h |
2608 | @@ -580,7 +580,7 @@ int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp, |
2609 | unsigned char __user *data, int optlen); |
2610 | void ip_options_undo(struct ip_options *opt); |
2611 | void ip_forward_options(struct sk_buff *skb); |
2612 | -int ip_options_rcv_srr(struct sk_buff *skb); |
2613 | +int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev); |
2614 | |
2615 | /* |
2616 | * Functions provided by ip_sockglue.c |
2617 | diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h |
2618 | index c05db6ff2515..0cdafe3935a6 100644 |
2619 | --- a/include/net/net_namespace.h |
2620 | +++ b/include/net/net_namespace.h |
2621 | @@ -53,6 +53,7 @@ struct net { |
2622 | */ |
2623 | spinlock_t rules_mod_lock; |
2624 | |
2625 | + u32 hash_mix; |
2626 | atomic64_t cookie_gen; |
2627 | |
2628 | struct list_head list; /* list of network namespaces */ |
2629 | diff --git a/include/net/netns/hash.h b/include/net/netns/hash.h |
2630 | index 69a6715d9f3f..a347b2f9e748 100644 |
2631 | --- a/include/net/netns/hash.h |
2632 | +++ b/include/net/netns/hash.h |
2633 | @@ -1,21 +1,10 @@ |
2634 | #ifndef __NET_NS_HASH_H__ |
2635 | #define __NET_NS_HASH_H__ |
2636 | |
2637 | -#include <asm/cache.h> |
2638 | - |
2639 | -struct net; |
2640 | +#include <net/net_namespace.h> |
2641 | |
2642 | static inline u32 net_hash_mix(const struct net *net) |
2643 | { |
2644 | -#ifdef CONFIG_NET_NS |
2645 | - /* |
2646 | - * shift this right to eliminate bits, that are |
2647 | - * always zeroed |
2648 | - */ |
2649 | - |
2650 | - return (u32)(((unsigned long)net) >> L1_CACHE_SHIFT); |
2651 | -#else |
2652 | - return 0; |
2653 | -#endif |
2654 | + return net->hash_mix; |
2655 | } |
2656 | #endif |
2657 | diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c |
2658 | index 9e745cc0726d..9f13667ccb9c 100644 |
2659 | --- a/kernel/irq/chip.c |
2660 | +++ b/kernel/irq/chip.c |
2661 | @@ -1142,6 +1142,10 @@ int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info) |
2662 | int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on) |
2663 | { |
2664 | data = data->parent_data; |
2665 | + |
2666 | + if (data->chip->flags & IRQCHIP_SKIP_SET_WAKE) |
2667 | + return 0; |
2668 | + |
2669 | if (data->chip->irq_set_wake) |
2670 | return data->chip->irq_set_wake(data, on); |
2671 | |
2672 | diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c |
2673 | index 0c91d72f3e8f..1c630d94f86b 100644 |
2674 | --- a/kernel/sched/fair.c |
2675 | +++ b/kernel/sched/fair.c |
2676 | @@ -6634,10 +6634,10 @@ static void update_cfs_rq_h_load(struct cfs_rq *cfs_rq) |
2677 | if (cfs_rq->last_h_load_update == now) |
2678 | return; |
2679 | |
2680 | - cfs_rq->h_load_next = NULL; |
2681 | + WRITE_ONCE(cfs_rq->h_load_next, NULL); |
2682 | for_each_sched_entity(se) { |
2683 | cfs_rq = cfs_rq_of(se); |
2684 | - cfs_rq->h_load_next = se; |
2685 | + WRITE_ONCE(cfs_rq->h_load_next, se); |
2686 | if (cfs_rq->last_h_load_update == now) |
2687 | break; |
2688 | } |
2689 | @@ -6647,7 +6647,7 @@ static void update_cfs_rq_h_load(struct cfs_rq *cfs_rq) |
2690 | cfs_rq->last_h_load_update = now; |
2691 | } |
2692 | |
2693 | - while ((se = cfs_rq->h_load_next) != NULL) { |
2694 | + while ((se = READ_ONCE(cfs_rq->h_load_next)) != NULL) { |
2695 | load = cfs_rq->h_load; |
2696 | load = div64_ul(load * se->avg.load_avg, |
2697 | cfs_rq_load_avg(cfs_rq) + 1); |
2698 | diff --git a/lib/string.c b/lib/string.c |
2699 | index ed83562a53ae..1cd9757291b1 100644 |
2700 | --- a/lib/string.c |
2701 | +++ b/lib/string.c |
2702 | @@ -772,6 +772,26 @@ __visible int memcmp(const void *cs, const void *ct, size_t count) |
2703 | EXPORT_SYMBOL(memcmp); |
2704 | #endif |
2705 | |
2706 | +#ifndef __HAVE_ARCH_BCMP |
2707 | +/** |
2708 | + * bcmp - returns 0 if and only if the buffers have identical contents. |
2709 | + * @a: pointer to first buffer. |
2710 | + * @b: pointer to second buffer. |
2711 | + * @len: size of buffers. |
2712 | + * |
2713 | + * The sign or magnitude of a non-zero return value has no particular |
2714 | + * meaning, and architectures may implement their own more efficient bcmp(). So |
2715 | + * while this particular implementation is a simple (tail) call to memcmp, do |
2716 | + * not rely on anything but whether the return value is zero or non-zero. |
2717 | + */ |
2718 | +#undef bcmp |
2719 | +int bcmp(const void *a, const void *b, size_t len) |
2720 | +{ |
2721 | + return memcmp(a, b, len); |
2722 | +} |
2723 | +EXPORT_SYMBOL(bcmp); |
2724 | +#endif |
2725 | + |
2726 | #ifndef __HAVE_ARCH_MEMSCAN |
2727 | /** |
2728 | * memscan - Find a character in an area of memory. |
2729 | diff --git a/net/core/ethtool.c b/net/core/ethtool.c |
2730 | index a8a9938aeceb..20ae57fbe009 100644 |
2731 | --- a/net/core/ethtool.c |
2732 | +++ b/net/core/ethtool.c |
2733 | @@ -1801,17 +1801,22 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) |
2734 | |
2735 | gstrings.len = ret; |
2736 | |
2737 | - data = kcalloc(gstrings.len, ETH_GSTRING_LEN, GFP_USER); |
2738 | - if (!data) |
2739 | - return -ENOMEM; |
2740 | + if (gstrings.len) { |
2741 | + data = kcalloc(gstrings.len, ETH_GSTRING_LEN, GFP_USER); |
2742 | + if (!data) |
2743 | + return -ENOMEM; |
2744 | |
2745 | - __ethtool_get_strings(dev, gstrings.string_set, data); |
2746 | + __ethtool_get_strings(dev, gstrings.string_set, data); |
2747 | + } else { |
2748 | + data = NULL; |
2749 | + } |
2750 | |
2751 | ret = -EFAULT; |
2752 | if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) |
2753 | goto out; |
2754 | useraddr += sizeof(gstrings); |
2755 | - if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN)) |
2756 | + if (gstrings.len && |
2757 | + copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN)) |
2758 | goto out; |
2759 | ret = 0; |
2760 | |
2761 | @@ -1899,17 +1904,21 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) |
2762 | return -EFAULT; |
2763 | |
2764 | stats.n_stats = n_stats; |
2765 | - data = kmalloc(n_stats * sizeof(u64), GFP_USER); |
2766 | - if (!data) |
2767 | - return -ENOMEM; |
2768 | + if (n_stats) { |
2769 | + data = kmalloc(n_stats * sizeof(u64), GFP_USER); |
2770 | + if (!data) |
2771 | + return -ENOMEM; |
2772 | |
2773 | - ops->get_ethtool_stats(dev, &stats, data); |
2774 | + ops->get_ethtool_stats(dev, &stats, data); |
2775 | + } else { |
2776 | + data = NULL; |
2777 | + } |
2778 | |
2779 | ret = -EFAULT; |
2780 | if (copy_to_user(useraddr, &stats, sizeof(stats))) |
2781 | goto out; |
2782 | useraddr += sizeof(stats); |
2783 | - if (copy_to_user(useraddr, data, stats.n_stats * sizeof(u64))) |
2784 | + if (n_stats && copy_to_user(useraddr, data, n_stats * sizeof(u64))) |
2785 | goto out; |
2786 | ret = 0; |
2787 | |
2788 | @@ -1938,19 +1947,23 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr) |
2789 | return -EFAULT; |
2790 | |
2791 | stats.n_stats = n_stats; |
2792 | - data = kmalloc_array(n_stats, sizeof(u64), GFP_USER); |
2793 | - if (!data) |
2794 | - return -ENOMEM; |
2795 | + if (n_stats) { |
2796 | + data = kmalloc_array(n_stats, sizeof(u64), GFP_USER); |
2797 | + if (!data) |
2798 | + return -ENOMEM; |
2799 | |
2800 | - mutex_lock(&phydev->lock); |
2801 | - phydev->drv->get_stats(phydev, &stats, data); |
2802 | - mutex_unlock(&phydev->lock); |
2803 | + mutex_lock(&phydev->lock); |
2804 | + phydev->drv->get_stats(phydev, &stats, data); |
2805 | + mutex_unlock(&phydev->lock); |
2806 | + } else { |
2807 | + data = NULL; |
2808 | + } |
2809 | |
2810 | ret = -EFAULT; |
2811 | if (copy_to_user(useraddr, &stats, sizeof(stats))) |
2812 | goto out; |
2813 | useraddr += sizeof(stats); |
2814 | - if (copy_to_user(useraddr, data, stats.n_stats * sizeof(u64))) |
2815 | + if (n_stats && copy_to_user(useraddr, data, n_stats * sizeof(u64))) |
2816 | goto out; |
2817 | ret = 0; |
2818 | |
2819 | diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c |
2820 | index 04fd04ccaa04..4509dec7bd1c 100644 |
2821 | --- a/net/core/net_namespace.c |
2822 | +++ b/net/core/net_namespace.c |
2823 | @@ -282,6 +282,7 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) |
2824 | |
2825 | atomic_set(&net->count, 1); |
2826 | atomic_set(&net->passive, 1); |
2827 | + get_random_bytes(&net->hash_mix, sizeof(u32)); |
2828 | net->dev_base_seq = 1; |
2829 | net->user_ns = user_ns; |
2830 | idr_init(&net->netns_ids); |
2831 | diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c |
2832 | index bcadca26523b..ce0ce1401f28 100644 |
2833 | --- a/net/ipv4/ip_input.c |
2834 | +++ b/net/ipv4/ip_input.c |
2835 | @@ -259,11 +259,10 @@ int ip_local_deliver(struct sk_buff *skb) |
2836 | ip_local_deliver_finish); |
2837 | } |
2838 | |
2839 | -static inline bool ip_rcv_options(struct sk_buff *skb) |
2840 | +static inline bool ip_rcv_options(struct sk_buff *skb, struct net_device *dev) |
2841 | { |
2842 | struct ip_options *opt; |
2843 | const struct iphdr *iph; |
2844 | - struct net_device *dev = skb->dev; |
2845 | |
2846 | /* It looks as overkill, because not all |
2847 | IP options require packet mangling. |
2848 | @@ -299,7 +298,7 @@ static inline bool ip_rcv_options(struct sk_buff *skb) |
2849 | } |
2850 | } |
2851 | |
2852 | - if (ip_options_rcv_srr(skb)) |
2853 | + if (ip_options_rcv_srr(skb, dev)) |
2854 | goto drop; |
2855 | } |
2856 | |
2857 | @@ -361,7 +360,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) |
2858 | } |
2859 | #endif |
2860 | |
2861 | - if (iph->ihl > 5 && ip_rcv_options(skb)) |
2862 | + if (iph->ihl > 5 && ip_rcv_options(skb, dev)) |
2863 | goto drop; |
2864 | |
2865 | rt = skb_rtable(skb); |
2866 | diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c |
2867 | index 4cd3b5ad9cee..570cdb547234 100644 |
2868 | --- a/net/ipv4/ip_options.c |
2869 | +++ b/net/ipv4/ip_options.c |
2870 | @@ -614,7 +614,7 @@ void ip_forward_options(struct sk_buff *skb) |
2871 | } |
2872 | } |
2873 | |
2874 | -int ip_options_rcv_srr(struct sk_buff *skb) |
2875 | +int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev) |
2876 | { |
2877 | struct ip_options *opt = &(IPCB(skb)->opt); |
2878 | int srrspace, srrptr; |
2879 | @@ -649,7 +649,7 @@ int ip_options_rcv_srr(struct sk_buff *skb) |
2880 | |
2881 | orefdst = skb->_skb_refdst; |
2882 | skb_dst_set(skb, NULL); |
2883 | - err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev); |
2884 | + err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, dev); |
2885 | rt2 = skb_rtable(skb); |
2886 | if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { |
2887 | skb_dst_drop(skb); |
2888 | diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c |
2889 | index a08cedf9d286..910ef01759e7 100644 |
2890 | --- a/net/ipv4/tcp_dctcp.c |
2891 | +++ b/net/ipv4/tcp_dctcp.c |
2892 | @@ -66,11 +66,6 @@ static unsigned int dctcp_alpha_on_init __read_mostly = DCTCP_MAX_ALPHA; |
2893 | module_param(dctcp_alpha_on_init, uint, 0644); |
2894 | MODULE_PARM_DESC(dctcp_alpha_on_init, "parameter for initial alpha value"); |
2895 | |
2896 | -static unsigned int dctcp_clamp_alpha_on_loss __read_mostly; |
2897 | -module_param(dctcp_clamp_alpha_on_loss, uint, 0644); |
2898 | -MODULE_PARM_DESC(dctcp_clamp_alpha_on_loss, |
2899 | - "parameter for clamping alpha on loss"); |
2900 | - |
2901 | static struct tcp_congestion_ops dctcp_reno; |
2902 | |
2903 | static void dctcp_reset(const struct tcp_sock *tp, struct dctcp *ca) |
2904 | @@ -211,21 +206,23 @@ static void dctcp_update_alpha(struct sock *sk, u32 flags) |
2905 | } |
2906 | } |
2907 | |
2908 | -static void dctcp_state(struct sock *sk, u8 new_state) |
2909 | +static void dctcp_react_to_loss(struct sock *sk) |
2910 | { |
2911 | - if (dctcp_clamp_alpha_on_loss && new_state == TCP_CA_Loss) { |
2912 | - struct dctcp *ca = inet_csk_ca(sk); |
2913 | + struct dctcp *ca = inet_csk_ca(sk); |
2914 | + struct tcp_sock *tp = tcp_sk(sk); |
2915 | |
2916 | - /* If this extension is enabled, we clamp dctcp_alpha to |
2917 | - * max on packet loss; the motivation is that dctcp_alpha |
2918 | - * is an indicator to the extend of congestion and packet |
2919 | - * loss is an indicator of extreme congestion; setting |
2920 | - * this in practice turned out to be beneficial, and |
2921 | - * effectively assumes total congestion which reduces the |
2922 | - * window by half. |
2923 | - */ |
2924 | - ca->dctcp_alpha = DCTCP_MAX_ALPHA; |
2925 | - } |
2926 | + ca->loss_cwnd = tp->snd_cwnd; |
2927 | + tp->snd_ssthresh = max(tp->snd_cwnd >> 1U, 2U); |
2928 | +} |
2929 | + |
2930 | +static void dctcp_state(struct sock *sk, u8 new_state) |
2931 | +{ |
2932 | + if (new_state == TCP_CA_Recovery && |
2933 | + new_state != inet_csk(sk)->icsk_ca_state) |
2934 | + dctcp_react_to_loss(sk); |
2935 | + /* We handle RTO in dctcp_cwnd_event to ensure that we perform only |
2936 | + * one loss-adjustment per RTT. |
2937 | + */ |
2938 | } |
2939 | |
2940 | static void dctcp_cwnd_event(struct sock *sk, enum tcp_ca_event ev) |
2941 | @@ -237,6 +234,9 @@ static void dctcp_cwnd_event(struct sock *sk, enum tcp_ca_event ev) |
2942 | case CA_EVENT_ECN_NO_CE: |
2943 | dctcp_ce_state_1_to_0(sk); |
2944 | break; |
2945 | + case CA_EVENT_LOSS: |
2946 | + dctcp_react_to_loss(sk); |
2947 | + break; |
2948 | default: |
2949 | /* Don't care for the rest. */ |
2950 | break; |
2951 | diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c |
2952 | index b723987761be..11407dd6bc7c 100644 |
2953 | --- a/net/ipv6/ip6_output.c |
2954 | +++ b/net/ipv6/ip6_output.c |
2955 | @@ -592,7 +592,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, |
2956 | inet6_sk(skb->sk) : NULL; |
2957 | struct ipv6hdr *tmp_hdr; |
2958 | struct frag_hdr *fh; |
2959 | - unsigned int mtu, hlen, left, len; |
2960 | + unsigned int mtu, hlen, left, len, nexthdr_offset; |
2961 | int hroom, troom; |
2962 | __be32 frag_id; |
2963 | int ptr, offset = 0, err = 0; |
2964 | @@ -603,6 +603,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, |
2965 | goto fail; |
2966 | hlen = err; |
2967 | nexthdr = *prevhdr; |
2968 | + nexthdr_offset = prevhdr - skb_network_header(skb); |
2969 | |
2970 | mtu = ip6_skb_dst_mtu(skb); |
2971 | |
2972 | @@ -637,6 +638,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, |
2973 | (err = skb_checksum_help(skb))) |
2974 | goto fail; |
2975 | |
2976 | + prevhdr = skb_network_header(skb) + nexthdr_offset; |
2977 | hroom = LL_RESERVED_SPACE(rt->dst.dev); |
2978 | if (skb_has_frag_list(skb)) { |
2979 | int first_len = skb_pagelen(skb); |
2980 | diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c |
2981 | index f89516d04150..42f363661d25 100644 |
2982 | --- a/net/ipv6/ip6_tunnel.c |
2983 | +++ b/net/ipv6/ip6_tunnel.c |
2984 | @@ -634,7 +634,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
2985 | IPPROTO_IPIP, |
2986 | RT_TOS(eiph->tos), 0); |
2987 | if (IS_ERR(rt) || |
2988 | - rt->dst.dev->type != ARPHRD_TUNNEL) { |
2989 | + rt->dst.dev->type != ARPHRD_TUNNEL6) { |
2990 | if (!IS_ERR(rt)) |
2991 | ip_rt_put(rt); |
2992 | goto out; |
2993 | @@ -644,7 +644,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
2994 | ip_rt_put(rt); |
2995 | if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, |
2996 | skb2->dev) || |
2997 | - skb_dst(skb2)->dev->type != ARPHRD_TUNNEL) |
2998 | + skb_dst(skb2)->dev->type != ARPHRD_TUNNEL6) |
2999 | goto out; |
3000 | } |
3001 | |
3002 | diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c |
3003 | index c9c6a5e829ab..be74eee0e8ff 100644 |
3004 | --- a/net/ipv6/sit.c |
3005 | +++ b/net/ipv6/sit.c |
3006 | @@ -661,6 +661,10 @@ static int ipip6_rcv(struct sk_buff *skb) |
3007 | !net_eq(tunnel->net, dev_net(tunnel->dev)))) |
3008 | goto out; |
3009 | |
3010 | + /* skb can be uncloned in iptunnel_pull_header, so |
3011 | + * old iph is no longer valid |
3012 | + */ |
3013 | + iph = (const struct iphdr *)skb_mac_header(skb); |
3014 | err = IP_ECN_decapsulate(iph, skb); |
3015 | if (unlikely(err)) { |
3016 | if (log_ecn_error) |
3017 | diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c |
3018 | index 553d0ad4a2fa..2f3cd09ee0df 100644 |
3019 | --- a/net/kcm/kcmsock.c |
3020 | +++ b/net/kcm/kcmsock.c |
3021 | @@ -2058,14 +2058,14 @@ static int __init kcm_init(void) |
3022 | if (err) |
3023 | goto fail; |
3024 | |
3025 | - err = sock_register(&kcm_family_ops); |
3026 | - if (err) |
3027 | - goto sock_register_fail; |
3028 | - |
3029 | err = register_pernet_device(&kcm_net_ops); |
3030 | if (err) |
3031 | goto net_ops_fail; |
3032 | |
3033 | + err = sock_register(&kcm_family_ops); |
3034 | + if (err) |
3035 | + goto sock_register_fail; |
3036 | + |
3037 | err = kcm_proc_init(); |
3038 | if (err) |
3039 | goto proc_init_fail; |
3040 | @@ -2073,12 +2073,12 @@ static int __init kcm_init(void) |
3041 | return 0; |
3042 | |
3043 | proc_init_fail: |
3044 | - unregister_pernet_device(&kcm_net_ops); |
3045 | - |
3046 | -net_ops_fail: |
3047 | sock_unregister(PF_KCM); |
3048 | |
3049 | sock_register_fail: |
3050 | + unregister_pernet_device(&kcm_net_ops); |
3051 | + |
3052 | +net_ops_fail: |
3053 | proto_unregister(&kcm_proto); |
3054 | |
3055 | fail: |
3056 | @@ -2094,8 +2094,8 @@ fail: |
3057 | static void __exit kcm_exit(void) |
3058 | { |
3059 | kcm_proc_exit(); |
3060 | - unregister_pernet_device(&kcm_net_ops); |
3061 | sock_unregister(PF_KCM); |
3062 | + unregister_pernet_device(&kcm_net_ops); |
3063 | proto_unregister(&kcm_proto); |
3064 | destroy_workqueue(kcm_wq); |
3065 | |
3066 | diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c |
3067 | index 3bd4d5d0c346..50ea76180afa 100644 |
3068 | --- a/net/openvswitch/flow_netlink.c |
3069 | +++ b/net/openvswitch/flow_netlink.c |
3070 | @@ -1853,14 +1853,14 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, |
3071 | |
3072 | struct sw_flow_actions *acts; |
3073 | int new_acts_size; |
3074 | - int req_size = NLA_ALIGN(attr_len); |
3075 | + size_t req_size = NLA_ALIGN(attr_len); |
3076 | int next_offset = offsetof(struct sw_flow_actions, actions) + |
3077 | (*sfa)->actions_len; |
3078 | |
3079 | if (req_size <= (ksize(*sfa) - next_offset)) |
3080 | goto out; |
3081 | |
3082 | - new_acts_size = ksize(*sfa) * 2; |
3083 | + new_acts_size = max(next_offset + req_size, ksize(*sfa) * 2); |
3084 | |
3085 | if (new_acts_size > MAX_ACTIONS_BUFSIZE) { |
3086 | if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size) { |
3087 | diff --git a/net/rds/tcp.c b/net/rds/tcp.c |
3088 | index d36effbf7614..2daba5316caa 100644 |
3089 | --- a/net/rds/tcp.c |
3090 | +++ b/net/rds/tcp.c |
3091 | @@ -527,7 +527,7 @@ static void rds_tcp_kill_sock(struct net *net) |
3092 | list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { |
3093 | struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net); |
3094 | |
3095 | - if (net != c_net || !tc->t_sock) |
3096 | + if (net != c_net) |
3097 | continue; |
3098 | if (!list_has_conn(&tmp_list, tc->t_cpath->cp_conn)) { |
3099 | list_move_tail(&tc->t_tcp_node, &tmp_list); |
3100 | diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c |
3101 | index 8ea8217db960..d6af93a24aa0 100644 |
3102 | --- a/net/sctp/protocol.c |
3103 | +++ b/net/sctp/protocol.c |
3104 | @@ -600,6 +600,7 @@ out: |
3105 | static int sctp_v4_addr_to_user(struct sctp_sock *sp, union sctp_addr *addr) |
3106 | { |
3107 | /* No address mapping for V4 sockets */ |
3108 | + memset(addr->v4.sin_zero, 0, sizeof(addr->v4.sin_zero)); |
3109 | return sizeof(struct sockaddr_in); |
3110 | } |
3111 | |
3112 | diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c |
3113 | index 965473d4129c..09491b27092e 100644 |
3114 | --- a/sound/core/seq/seq_clientmgr.c |
3115 | +++ b/sound/core/seq/seq_clientmgr.c |
3116 | @@ -1249,7 +1249,7 @@ static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client, |
3117 | |
3118 | /* fill the info fields */ |
3119 | if (client_info->name[0]) |
3120 | - strlcpy(client->name, client_info->name, sizeof(client->name)); |
3121 | + strscpy(client->name, client_info->name, sizeof(client->name)); |
3122 | |
3123 | client->filter = client_info->filter; |
3124 | client->event_lost = client_info->event_lost; |
3125 | @@ -1527,7 +1527,7 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg) |
3126 | /* set queue name */ |
3127 | if (!info->name[0]) |
3128 | snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue); |
3129 | - strlcpy(q->name, info->name, sizeof(q->name)); |
3130 | + strscpy(q->name, info->name, sizeof(q->name)); |
3131 | snd_use_lock_free(&q->use_lock); |
3132 | |
3133 | return 0; |
3134 | @@ -1589,7 +1589,7 @@ static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client, |
3135 | queuefree(q); |
3136 | return -EPERM; |
3137 | } |
3138 | - strlcpy(q->name, info->name, sizeof(q->name)); |
3139 | + strscpy(q->name, info->name, sizeof(q->name)); |
3140 | queuefree(q); |
3141 | |
3142 | return 0; |
3143 | diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c |
3144 | index 23ab0d169c11..fa64cc2b1729 100644 |
3145 | --- a/sound/soc/fsl/fsl_esai.c |
3146 | +++ b/sound/soc/fsl/fsl_esai.c |
3147 | @@ -59,6 +59,8 @@ struct fsl_esai { |
3148 | u32 fifo_depth; |
3149 | u32 slot_width; |
3150 | u32 slots; |
3151 | + u32 tx_mask; |
3152 | + u32 rx_mask; |
3153 | u32 hck_rate[2]; |
3154 | u32 sck_rate[2]; |
3155 | bool hck_dir[2]; |
3156 | @@ -359,21 +361,13 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, |
3157 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, |
3158 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); |
3159 | |
3160 | - regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, |
3161 | - ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); |
3162 | - regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, |
3163 | - ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask)); |
3164 | - |
3165 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, |
3166 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); |
3167 | |
3168 | - regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, |
3169 | - ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); |
3170 | - regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, |
3171 | - ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); |
3172 | - |
3173 | esai_priv->slot_width = slot_width; |
3174 | esai_priv->slots = slots; |
3175 | + esai_priv->tx_mask = tx_mask; |
3176 | + esai_priv->rx_mask = rx_mask; |
3177 | |
3178 | return 0; |
3179 | } |
3180 | @@ -594,6 +588,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, |
3181 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
3182 | u8 i, channels = substream->runtime->channels; |
3183 | u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); |
3184 | + u32 mask; |
3185 | |
3186 | switch (cmd) { |
3187 | case SNDRV_PCM_TRIGGER_START: |
3188 | @@ -606,15 +601,38 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, |
3189 | for (i = 0; tx && i < channels; i++) |
3190 | regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0); |
3191 | |
3192 | + /* |
3193 | + * When set the TE/RE in the end of enablement flow, there |
3194 | + * will be channel swap issue for multi data line case. |
3195 | + * In order to workaround this issue, we switch the bit |
3196 | + * enablement sequence to below sequence |
3197 | + * 1) clear the xSMB & xSMA: which is done in probe and |
3198 | + * stop state. |
3199 | + * 2) set TE/RE |
3200 | + * 3) set xSMB |
3201 | + * 4) set xSMA: xSMA is the last one in this flow, which |
3202 | + * will trigger esai to start. |
3203 | + */ |
3204 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), |
3205 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, |
3206 | tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); |
3207 | + mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask; |
3208 | + |
3209 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), |
3210 | + ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask)); |
3211 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), |
3212 | + ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask)); |
3213 | + |
3214 | break; |
3215 | case SNDRV_PCM_TRIGGER_SUSPEND: |
3216 | case SNDRV_PCM_TRIGGER_STOP: |
3217 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
3218 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), |
3219 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0); |
3220 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), |
3221 | + ESAI_xSMA_xS_MASK, 0); |
3222 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), |
3223 | + ESAI_xSMB_xS_MASK, 0); |
3224 | |
3225 | /* Disable and reset FIFO */ |
3226 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), |
3227 | @@ -904,6 +922,15 @@ static int fsl_esai_probe(struct platform_device *pdev) |
3228 | return ret; |
3229 | } |
3230 | |
3231 | + esai_priv->tx_mask = 0xFFFFFFFF; |
3232 | + esai_priv->rx_mask = 0xFFFFFFFF; |
3233 | + |
3234 | + /* Clear the TSMA, TSMB, RSMA, RSMB */ |
3235 | + regmap_write(esai_priv->regmap, REG_ESAI_TSMA, 0); |
3236 | + regmap_write(esai_priv->regmap, REG_ESAI_TSMB, 0); |
3237 | + regmap_write(esai_priv->regmap, REG_ESAI_RSMA, 0); |
3238 | + regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0); |
3239 | + |
3240 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component, |
3241 | &fsl_esai_dai, 1); |
3242 | if (ret) { |