1 |
commit: cf0d78b576a8493230af436a1bcf0c6d71c3f370 |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Aug 31 15:44:02 2022 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Aug 31 15:44:02 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=cf0d78b5 |
7 |
|
8 |
Linux patch 5.19.6 |
9 |
|
10 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1005_linux-5.19.6.patch | 6485 +++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 6489 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 4172ad7c..3deab328 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -63,6 +63,10 @@ Patch: 1004_linux-5.19.5.patch |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 5.19.5 |
23 |
|
24 |
+Patch: 1005_linux-5.19.6.patch |
25 |
+From: http://www.kernel.org |
26 |
+Desc: Linux 5.19.6 |
27 |
+ |
28 |
Patch: 1500_XATTR_USER_PREFIX.patch |
29 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
30 |
Desc: Support for namespace user.pax.* on tmpfs. |
31 |
|
32 |
diff --git a/1005_linux-5.19.6.patch b/1005_linux-5.19.6.patch |
33 |
new file mode 100644 |
34 |
index 00000000..c5d4f0ee |
35 |
--- /dev/null |
36 |
+++ b/1005_linux-5.19.6.patch |
37 |
@@ -0,0 +1,6485 @@ |
38 |
+diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu |
39 |
+index bcc974d276dc4..3cda940108f63 100644 |
40 |
+--- a/Documentation/ABI/testing/sysfs-devices-system-cpu |
41 |
++++ b/Documentation/ABI/testing/sysfs-devices-system-cpu |
42 |
+@@ -527,6 +527,7 @@ What: /sys/devices/system/cpu/vulnerabilities |
43 |
+ /sys/devices/system/cpu/vulnerabilities/tsx_async_abort |
44 |
+ /sys/devices/system/cpu/vulnerabilities/itlb_multihit |
45 |
+ /sys/devices/system/cpu/vulnerabilities/mmio_stale_data |
46 |
++ /sys/devices/system/cpu/vulnerabilities/retbleed |
47 |
+ Date: January 2018 |
48 |
+ Contact: Linux kernel mailing list <linux-kernel@×××××××××××.org> |
49 |
+ Description: Information about CPU vulnerabilities |
50 |
+diff --git a/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst b/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst |
51 |
+index 9393c50b5afc9..c98fd11907cc8 100644 |
52 |
+--- a/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst |
53 |
++++ b/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst |
54 |
+@@ -230,6 +230,20 @@ The possible values in this file are: |
55 |
+ * - 'Mitigation: Clear CPU buffers' |
56 |
+ - The processor is vulnerable and the CPU buffer clearing mitigation is |
57 |
+ enabled. |
58 |
++ * - 'Unknown: No mitigations' |
59 |
++ - The processor vulnerability status is unknown because it is |
60 |
++ out of Servicing period. Mitigation is not attempted. |
61 |
++ |
62 |
++Definitions: |
63 |
++------------ |
64 |
++ |
65 |
++Servicing period: The process of providing functional and security updates to |
66 |
++Intel processors or platforms, utilizing the Intel Platform Update (IPU) |
67 |
++process or other similar mechanisms. |
68 |
++ |
69 |
++End of Servicing Updates (ESU): ESU is the date at which Intel will no |
70 |
++longer provide Servicing, such as through IPU or other similar update |
71 |
++processes. ESU dates will typically be aligned to end of quarter. |
72 |
+ |
73 |
+ If the processor is vulnerable then the following information is appended to |
74 |
+ the above information: |
75 |
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt |
76 |
+index e4fe443bea77d..1b38d0f70677e 100644 |
77 |
+--- a/Documentation/admin-guide/kernel-parameters.txt |
78 |
++++ b/Documentation/admin-guide/kernel-parameters.txt |
79 |
+@@ -5260,6 +5260,8 @@ |
80 |
+ rodata= [KNL] |
81 |
+ on Mark read-only kernel memory as read-only (default). |
82 |
+ off Leave read-only kernel memory writable for debugging. |
83 |
++ full Mark read-only kernel memory and aliases as read-only |
84 |
++ [arm64] |
85 |
+ |
86 |
+ rockchip.usb_uart |
87 |
+ Enable the uart passthrough on the designated usb port |
88 |
+diff --git a/Documentation/admin-guide/sysctl/net.rst b/Documentation/admin-guide/sysctl/net.rst |
89 |
+index fcd650bdbc7e2..01d9858197832 100644 |
90 |
+--- a/Documentation/admin-guide/sysctl/net.rst |
91 |
++++ b/Documentation/admin-guide/sysctl/net.rst |
92 |
+@@ -271,7 +271,7 @@ poll cycle or the number of packets processed reaches netdev_budget. |
93 |
+ netdev_max_backlog |
94 |
+ ------------------ |
95 |
+ |
96 |
+-Maximum number of packets, queued on the INPUT side, when the interface |
97 |
++Maximum number of packets, queued on the INPUT side, when the interface |
98 |
+ receives packets faster than kernel can process them. |
99 |
+ |
100 |
+ netdev_rss_key |
101 |
+diff --git a/Makefile b/Makefile |
102 |
+index 1c4f1ecb93488..cb68101ea070a 100644 |
103 |
+--- a/Makefile |
104 |
++++ b/Makefile |
105 |
+@@ -1,7 +1,7 @@ |
106 |
+ # SPDX-License-Identifier: GPL-2.0 |
107 |
+ VERSION = 5 |
108 |
+ PATCHLEVEL = 19 |
109 |
+-SUBLEVEL = 5 |
110 |
++SUBLEVEL = 6 |
111 |
+ EXTRAVERSION = |
112 |
+ NAME = Superb Owl |
113 |
+ |
114 |
+diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h |
115 |
+index 9bb1873f52951..6f86b7ab6c28f 100644 |
116 |
+--- a/arch/arm64/include/asm/fpsimd.h |
117 |
++++ b/arch/arm64/include/asm/fpsimd.h |
118 |
+@@ -153,7 +153,7 @@ struct vl_info { |
119 |
+ |
120 |
+ #ifdef CONFIG_ARM64_SVE |
121 |
+ |
122 |
+-extern void sve_alloc(struct task_struct *task); |
123 |
++extern void sve_alloc(struct task_struct *task, bool flush); |
124 |
+ extern void fpsimd_release_task(struct task_struct *task); |
125 |
+ extern void fpsimd_sync_to_sve(struct task_struct *task); |
126 |
+ extern void fpsimd_force_sync_to_sve(struct task_struct *task); |
127 |
+@@ -256,7 +256,7 @@ size_t sve_state_size(struct task_struct const *task); |
128 |
+ |
129 |
+ #else /* ! CONFIG_ARM64_SVE */ |
130 |
+ |
131 |
+-static inline void sve_alloc(struct task_struct *task) { } |
132 |
++static inline void sve_alloc(struct task_struct *task, bool flush) { } |
133 |
+ static inline void fpsimd_release_task(struct task_struct *task) { } |
134 |
+ static inline void sve_sync_to_fpsimd(struct task_struct *task) { } |
135 |
+ static inline void sve_sync_from_fpsimd_zeropad(struct task_struct *task) { } |
136 |
+diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h |
137 |
+index 6437df6617009..f4af547ef54ca 100644 |
138 |
+--- a/arch/arm64/include/asm/setup.h |
139 |
++++ b/arch/arm64/include/asm/setup.h |
140 |
+@@ -3,6 +3,8 @@ |
141 |
+ #ifndef __ARM64_ASM_SETUP_H |
142 |
+ #define __ARM64_ASM_SETUP_H |
143 |
+ |
144 |
++#include <linux/string.h> |
145 |
++ |
146 |
+ #include <uapi/asm/setup.h> |
147 |
+ |
148 |
+ void *get_early_fdt_ptr(void); |
149 |
+@@ -14,4 +16,19 @@ void early_fdt_map(u64 dt_phys); |
150 |
+ extern phys_addr_t __fdt_pointer __initdata; |
151 |
+ extern u64 __cacheline_aligned boot_args[4]; |
152 |
+ |
153 |
++static inline bool arch_parse_debug_rodata(char *arg) |
154 |
++{ |
155 |
++ extern bool rodata_enabled; |
156 |
++ extern bool rodata_full; |
157 |
++ |
158 |
++ if (arg && !strcmp(arg, "full")) { |
159 |
++ rodata_enabled = true; |
160 |
++ rodata_full = true; |
161 |
++ return true; |
162 |
++ } |
163 |
++ |
164 |
++ return false; |
165 |
++} |
166 |
++#define arch_parse_debug_rodata arch_parse_debug_rodata |
167 |
++ |
168 |
+ #endif |
169 |
+diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c |
170 |
+index 6b92989f4cc27..b374e258f705f 100644 |
171 |
+--- a/arch/arm64/kernel/cpu_errata.c |
172 |
++++ b/arch/arm64/kernel/cpu_errata.c |
173 |
+@@ -208,6 +208,8 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = { |
174 |
+ #ifdef CONFIG_ARM64_ERRATUM_1286807 |
175 |
+ { |
176 |
+ ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 0), |
177 |
++ }, |
178 |
++ { |
179 |
+ /* Kryo4xx Gold (rcpe to rfpe) => (r0p0 to r3p0) */ |
180 |
+ ERRATA_MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xe), |
181 |
+ }, |
182 |
+diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c |
183 |
+index aecf3071efddd..52f7ffdffbcb9 100644 |
184 |
+--- a/arch/arm64/kernel/fpsimd.c |
185 |
++++ b/arch/arm64/kernel/fpsimd.c |
186 |
+@@ -716,10 +716,12 @@ size_t sve_state_size(struct task_struct const *task) |
187 |
+ * do_sve_acc() case, there is no ABI requirement to hide stale data |
188 |
+ * written previously be task. |
189 |
+ */ |
190 |
+-void sve_alloc(struct task_struct *task) |
191 |
++void sve_alloc(struct task_struct *task, bool flush) |
192 |
+ { |
193 |
+ if (task->thread.sve_state) { |
194 |
+- memset(task->thread.sve_state, 0, sve_state_size(task)); |
195 |
++ if (flush) |
196 |
++ memset(task->thread.sve_state, 0, |
197 |
++ sve_state_size(task)); |
198 |
+ return; |
199 |
+ } |
200 |
+ |
201 |
+@@ -1389,7 +1391,7 @@ void do_sve_acc(unsigned long esr, struct pt_regs *regs) |
202 |
+ return; |
203 |
+ } |
204 |
+ |
205 |
+- sve_alloc(current); |
206 |
++ sve_alloc(current, true); |
207 |
+ if (!current->thread.sve_state) { |
208 |
+ force_sig(SIGKILL); |
209 |
+ return; |
210 |
+@@ -1440,7 +1442,7 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs) |
211 |
+ return; |
212 |
+ } |
213 |
+ |
214 |
+- sve_alloc(current); |
215 |
++ sve_alloc(current, false); |
216 |
+ sme_alloc(current); |
217 |
+ if (!current->thread.sve_state || !current->thread.za_state) { |
218 |
+ force_sig(SIGKILL); |
219 |
+@@ -1461,17 +1463,6 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs) |
220 |
+ fpsimd_bind_task_to_cpu(); |
221 |
+ } |
222 |
+ |
223 |
+- /* |
224 |
+- * If SVE was not already active initialise the SVE registers, |
225 |
+- * any non-shared state between the streaming and regular SVE |
226 |
+- * registers is architecturally guaranteed to be zeroed when |
227 |
+- * we enter streaming mode. We do not need to initialize ZA |
228 |
+- * since ZA must be disabled at this point and enabling ZA is |
229 |
+- * architecturally defined to zero ZA. |
230 |
+- */ |
231 |
+- if (system_supports_sve() && !test_thread_flag(TIF_SVE)) |
232 |
+- sve_init_regs(); |
233 |
+- |
234 |
+ put_cpu_fpsimd_context(); |
235 |
+ } |
236 |
+ |
237 |
+diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c |
238 |
+index 21da83187a602..eb7c08dfb8348 100644 |
239 |
+--- a/arch/arm64/kernel/ptrace.c |
240 |
++++ b/arch/arm64/kernel/ptrace.c |
241 |
+@@ -882,7 +882,7 @@ static int sve_set_common(struct task_struct *target, |
242 |
+ * state and ensure there's storage. |
243 |
+ */ |
244 |
+ if (target->thread.svcr != old_svcr) |
245 |
+- sve_alloc(target); |
246 |
++ sve_alloc(target, true); |
247 |
+ } |
248 |
+ |
249 |
+ /* Registers: FPSIMD-only case */ |
250 |
+@@ -912,7 +912,7 @@ static int sve_set_common(struct task_struct *target, |
251 |
+ goto out; |
252 |
+ } |
253 |
+ |
254 |
+- sve_alloc(target); |
255 |
++ sve_alloc(target, true); |
256 |
+ if (!target->thread.sve_state) { |
257 |
+ ret = -ENOMEM; |
258 |
+ clear_tsk_thread_flag(target, TIF_SVE); |
259 |
+@@ -1082,7 +1082,7 @@ static int za_set(struct task_struct *target, |
260 |
+ |
261 |
+ /* Ensure there is some SVE storage for streaming mode */ |
262 |
+ if (!target->thread.sve_state) { |
263 |
+- sve_alloc(target); |
264 |
++ sve_alloc(target, false); |
265 |
+ if (!target->thread.sve_state) { |
266 |
+ clear_thread_flag(TIF_SME); |
267 |
+ ret = -ENOMEM; |
268 |
+diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c |
269 |
+index b0980fbb6bc7f..8bb631bf9464c 100644 |
270 |
+--- a/arch/arm64/kernel/signal.c |
271 |
++++ b/arch/arm64/kernel/signal.c |
272 |
+@@ -307,7 +307,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) |
273 |
+ fpsimd_flush_task_state(current); |
274 |
+ /* From now, fpsimd_thread_switch() won't touch thread.sve_state */ |
275 |
+ |
276 |
+- sve_alloc(current); |
277 |
++ sve_alloc(current, true); |
278 |
+ if (!current->thread.sve_state) { |
279 |
+ clear_thread_flag(TIF_SVE); |
280 |
+ return -ENOMEM; |
281 |
+@@ -922,6 +922,16 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, |
282 |
+ |
283 |
+ /* Signal handlers are invoked with ZA and streaming mode disabled */ |
284 |
+ if (system_supports_sme()) { |
285 |
++ /* |
286 |
++ * If we were in streaming mode the saved register |
287 |
++ * state was SVE but we will exit SM and use the |
288 |
++ * FPSIMD register state - flush the saved FPSIMD |
289 |
++ * register state in case it gets loaded. |
290 |
++ */ |
291 |
++ if (current->thread.svcr & SVCR_SM_MASK) |
292 |
++ memset(¤t->thread.uw.fpsimd_state, 0, |
293 |
++ sizeof(current->thread.uw.fpsimd_state)); |
294 |
++ |
295 |
+ current->thread.svcr &= ~(SVCR_ZA_MASK | |
296 |
+ SVCR_SM_MASK); |
297 |
+ sme_smstop(); |
298 |
+diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c |
299 |
+index 626ec32873c6c..1de896e4d3347 100644 |
300 |
+--- a/arch/arm64/mm/mmu.c |
301 |
++++ b/arch/arm64/mm/mmu.c |
302 |
+@@ -625,24 +625,6 @@ static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end, |
303 |
+ vm_area_add_early(vma); |
304 |
+ } |
305 |
+ |
306 |
+-static int __init parse_rodata(char *arg) |
307 |
+-{ |
308 |
+- int ret = strtobool(arg, &rodata_enabled); |
309 |
+- if (!ret) { |
310 |
+- rodata_full = false; |
311 |
+- return 0; |
312 |
+- } |
313 |
+- |
314 |
+- /* permit 'full' in addition to boolean options */ |
315 |
+- if (strcmp(arg, "full")) |
316 |
+- return -EINVAL; |
317 |
+- |
318 |
+- rodata_enabled = true; |
319 |
+- rodata_full = true; |
320 |
+- return 0; |
321 |
+-} |
322 |
+-early_param("rodata", parse_rodata); |
323 |
+- |
324 |
+ #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 |
325 |
+ static int __init map_entry_trampoline(void) |
326 |
+ { |
327 |
+diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig |
328 |
+index fa400055b2d50..cd2b3fe156724 100644 |
329 |
+--- a/arch/parisc/Kconfig |
330 |
++++ b/arch/parisc/Kconfig |
331 |
+@@ -147,10 +147,10 @@ menu "Processor type and features" |
332 |
+ |
333 |
+ choice |
334 |
+ prompt "Processor type" |
335 |
+- default PA7000 |
336 |
++ default PA7000 if "$(ARCH)" = "parisc" |
337 |
+ |
338 |
+ config PA7000 |
339 |
+- bool "PA7000/PA7100" |
340 |
++ bool "PA7000/PA7100" if "$(ARCH)" = "parisc" |
341 |
+ help |
342 |
+ This is the processor type of your CPU. This information is |
343 |
+ used for optimizing purposes. In order to compile a kernel |
344 |
+@@ -161,21 +161,21 @@ config PA7000 |
345 |
+ which is required on some machines. |
346 |
+ |
347 |
+ config PA7100LC |
348 |
+- bool "PA7100LC" |
349 |
++ bool "PA7100LC" if "$(ARCH)" = "parisc" |
350 |
+ help |
351 |
+ Select this option for the PCX-L processor, as used in the |
352 |
+ 712, 715/64, 715/80, 715/100, 715/100XC, 725/100, 743, 748, |
353 |
+ D200, D210, D300, D310 and E-class |
354 |
+ |
355 |
+ config PA7200 |
356 |
+- bool "PA7200" |
357 |
++ bool "PA7200" if "$(ARCH)" = "parisc" |
358 |
+ help |
359 |
+ Select this option for the PCX-T' processor, as used in the |
360 |
+ C100, C110, J100, J110, J210XC, D250, D260, D350, D360, |
361 |
+ K100, K200, K210, K220, K400, K410 and K420 |
362 |
+ |
363 |
+ config PA7300LC |
364 |
+- bool "PA7300LC" |
365 |
++ bool "PA7300LC" if "$(ARCH)" = "parisc" |
366 |
+ help |
367 |
+ Select this option for the PCX-L2 processor, as used in the |
368 |
+ 744, A180, B132L, B160L, B180L, C132L, C160L, C180L, |
369 |
+@@ -225,17 +225,8 @@ config MLONGCALLS |
370 |
+ Enabling this option will probably slow down your kernel. |
371 |
+ |
372 |
+ config 64BIT |
373 |
+- bool "64-bit kernel" |
374 |
++ def_bool "$(ARCH)" = "parisc64" |
375 |
+ depends on PA8X00 |
376 |
+- help |
377 |
+- Enable this if you want to support 64bit kernel on PA-RISC platform. |
378 |
+- |
379 |
+- At the moment, only people willing to use more than 2GB of RAM, |
380 |
+- or having a 64bit-only capable PA-RISC machine should say Y here. |
381 |
+- |
382 |
+- Since there is no 64bit userland on PA-RISC, there is no point to |
383 |
+- enable this option otherwise. The 64bit kernel is significantly bigger |
384 |
+- and slower than the 32bit one. |
385 |
+ |
386 |
+ choice |
387 |
+ prompt "Kernel page size" |
388 |
+diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c |
389 |
+index bac581b5ecfc5..e8a4d77cff53a 100644 |
390 |
+--- a/arch/parisc/kernel/unaligned.c |
391 |
++++ b/arch/parisc/kernel/unaligned.c |
392 |
+@@ -93,7 +93,7 @@ |
393 |
+ #define R1(i) (((i)>>21)&0x1f) |
394 |
+ #define R2(i) (((i)>>16)&0x1f) |
395 |
+ #define R3(i) ((i)&0x1f) |
396 |
+-#define FR3(i) ((((i)<<1)&0x1f)|(((i)>>6)&1)) |
397 |
++#define FR3(i) ((((i)&0x1f)<<1)|(((i)>>6)&1)) |
398 |
+ #define IM(i,n) (((i)>>1&((1<<(n-1))-1))|((i)&1?((0-1L)<<(n-1)):0)) |
399 |
+ #define IM5_2(i) IM((i)>>16,5) |
400 |
+ #define IM5_3(i) IM((i),5) |
401 |
+diff --git a/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts b/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts |
402 |
+index 044982a11df50..f3f87ed2007f3 100644 |
403 |
+--- a/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts |
404 |
++++ b/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts |
405 |
+@@ -84,12 +84,10 @@ |
406 |
+ |
407 |
+ phy1: ethernet-phy@9 { |
408 |
+ reg = <9>; |
409 |
+- ti,fifo-depth = <0x1>; |
410 |
+ }; |
411 |
+ |
412 |
+ phy0: ethernet-phy@8 { |
413 |
+ reg = <8>; |
414 |
+- ti,fifo-depth = <0x1>; |
415 |
+ }; |
416 |
+ }; |
417 |
+ |
418 |
+@@ -102,7 +100,6 @@ |
419 |
+ disable-wp; |
420 |
+ cap-sd-highspeed; |
421 |
+ cap-mmc-highspeed; |
422 |
+- card-detect-delay = <200>; |
423 |
+ mmc-ddr-1_8v; |
424 |
+ mmc-hs200-1_8v; |
425 |
+ sd-uhs-sdr12; |
426 |
+diff --git a/arch/riscv/boot/dts/microchip/mpfs-polarberry.dts b/arch/riscv/boot/dts/microchip/mpfs-polarberry.dts |
427 |
+index 82c93c8f5c17e..c87cc2d8fe29f 100644 |
428 |
+--- a/arch/riscv/boot/dts/microchip/mpfs-polarberry.dts |
429 |
++++ b/arch/riscv/boot/dts/microchip/mpfs-polarberry.dts |
430 |
+@@ -54,12 +54,10 @@ |
431 |
+ |
432 |
+ phy1: ethernet-phy@5 { |
433 |
+ reg = <5>; |
434 |
+- ti,fifo-depth = <0x01>; |
435 |
+ }; |
436 |
+ |
437 |
+ phy0: ethernet-phy@4 { |
438 |
+ reg = <4>; |
439 |
+- ti,fifo-depth = <0x01>; |
440 |
+ }; |
441 |
+ }; |
442 |
+ |
443 |
+@@ -72,7 +70,6 @@ |
444 |
+ disable-wp; |
445 |
+ cap-sd-highspeed; |
446 |
+ cap-mmc-highspeed; |
447 |
+- card-detect-delay = <200>; |
448 |
+ mmc-ddr-1_8v; |
449 |
+ mmc-hs200-1_8v; |
450 |
+ sd-uhs-sdr12; |
451 |
+diff --git a/arch/riscv/boot/dts/microchip/mpfs.dtsi b/arch/riscv/boot/dts/microchip/mpfs.dtsi |
452 |
+index 496d3b7642bd1..9f5bce1488d93 100644 |
453 |
+--- a/arch/riscv/boot/dts/microchip/mpfs.dtsi |
454 |
++++ b/arch/riscv/boot/dts/microchip/mpfs.dtsi |
455 |
+@@ -169,7 +169,7 @@ |
456 |
+ cache-size = <2097152>; |
457 |
+ cache-unified; |
458 |
+ interrupt-parent = <&plic>; |
459 |
+- interrupts = <1>, <2>, <3>; |
460 |
++ interrupts = <1>, <3>, <4>, <2>; |
461 |
+ }; |
462 |
+ |
463 |
+ clint: clint@2000000 { |
464 |
+@@ -446,9 +446,8 @@ |
465 |
+ ranges = <0x3000000 0x0 0x8000000 0x20 0x8000000 0x0 0x80000000>; |
466 |
+ msi-parent = <&pcie>; |
467 |
+ msi-controller; |
468 |
+- microchip,axi-m-atr0 = <0x10 0x0>; |
469 |
+ status = "disabled"; |
470 |
+- pcie_intc: legacy-interrupt-controller { |
471 |
++ pcie_intc: interrupt-controller { |
472 |
+ #address-cells = <0>; |
473 |
+ #interrupt-cells = <1>; |
474 |
+ interrupt-controller; |
475 |
+diff --git a/arch/riscv/include/asm/signal.h b/arch/riscv/include/asm/signal.h |
476 |
+new file mode 100644 |
477 |
+index 0000000000000..532c29ef03769 |
478 |
+--- /dev/null |
479 |
++++ b/arch/riscv/include/asm/signal.h |
480 |
+@@ -0,0 +1,12 @@ |
481 |
++/* SPDX-License-Identifier: GPL-2.0-only */ |
482 |
++ |
483 |
++#ifndef __ASM_SIGNAL_H |
484 |
++#define __ASM_SIGNAL_H |
485 |
++ |
486 |
++#include <uapi/asm/signal.h> |
487 |
++#include <uapi/asm/ptrace.h> |
488 |
++ |
489 |
++asmlinkage __visible |
490 |
++void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags); |
491 |
++ |
492 |
++#endif |
493 |
+diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h |
494 |
+index 78933ac04995b..67322f878e0d7 100644 |
495 |
+--- a/arch/riscv/include/asm/thread_info.h |
496 |
++++ b/arch/riscv/include/asm/thread_info.h |
497 |
+@@ -42,6 +42,8 @@ |
498 |
+ |
499 |
+ #ifndef __ASSEMBLY__ |
500 |
+ |
501 |
++extern long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE / sizeof(long)]; |
502 |
++ |
503 |
+ #include <asm/processor.h> |
504 |
+ #include <asm/csr.h> |
505 |
+ |
506 |
+diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c |
507 |
+index 38b05ca6fe669..5a2de6b6f8822 100644 |
508 |
+--- a/arch/riscv/kernel/signal.c |
509 |
++++ b/arch/riscv/kernel/signal.c |
510 |
+@@ -15,6 +15,7 @@ |
511 |
+ |
512 |
+ #include <asm/ucontext.h> |
513 |
+ #include <asm/vdso.h> |
514 |
++#include <asm/signal.h> |
515 |
+ #include <asm/signal32.h> |
516 |
+ #include <asm/switch_to.h> |
517 |
+ #include <asm/csr.h> |
518 |
+diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c |
519 |
+index 39d0f8bba4b40..635e6ec269380 100644 |
520 |
+--- a/arch/riscv/kernel/traps.c |
521 |
++++ b/arch/riscv/kernel/traps.c |
522 |
+@@ -20,9 +20,10 @@ |
523 |
+ |
524 |
+ #include <asm/asm-prototypes.h> |
525 |
+ #include <asm/bug.h> |
526 |
++#include <asm/csr.h> |
527 |
+ #include <asm/processor.h> |
528 |
+ #include <asm/ptrace.h> |
529 |
+-#include <asm/csr.h> |
530 |
++#include <asm/thread_info.h> |
531 |
+ |
532 |
+ int show_unhandled_signals = 1; |
533 |
+ |
534 |
+diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c |
535 |
+index 89949b9f3cf88..d5119e039d855 100644 |
536 |
+--- a/arch/s390/kernel/process.c |
537 |
++++ b/arch/s390/kernel/process.c |
538 |
+@@ -91,6 +91,18 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) |
539 |
+ |
540 |
+ memcpy(dst, src, arch_task_struct_size); |
541 |
+ dst->thread.fpu.regs = dst->thread.fpu.fprs; |
542 |
++ |
543 |
++ /* |
544 |
++ * Don't transfer over the runtime instrumentation or the guarded |
545 |
++ * storage control block pointers. These fields are cleared here instead |
546 |
++ * of in copy_thread() to avoid premature freeing of associated memory |
547 |
++ * on fork() failure. Wait to clear the RI flag because ->stack still |
548 |
++ * refers to the source thread. |
549 |
++ */ |
550 |
++ dst->thread.ri_cb = NULL; |
551 |
++ dst->thread.gs_cb = NULL; |
552 |
++ dst->thread.gs_bc_cb = NULL; |
553 |
++ |
554 |
+ return 0; |
555 |
+ } |
556 |
+ |
557 |
+@@ -150,13 +162,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) |
558 |
+ frame->childregs.flags = 0; |
559 |
+ if (new_stackp) |
560 |
+ frame->childregs.gprs[15] = new_stackp; |
561 |
+- |
562 |
+- /* Don't copy runtime instrumentation info */ |
563 |
+- p->thread.ri_cb = NULL; |
564 |
++ /* |
565 |
++ * Clear the runtime instrumentation flag after the above childregs |
566 |
++ * copy. The CB pointer was already cleared in arch_dup_task_struct(). |
567 |
++ */ |
568 |
+ frame->childregs.psw.mask &= ~PSW_MASK_RI; |
569 |
+- /* Don't copy guarded storage control block */ |
570 |
+- p->thread.gs_cb = NULL; |
571 |
+- p->thread.gs_bc_cb = NULL; |
572 |
+ |
573 |
+ /* Set a new TLS ? */ |
574 |
+ if (clone_flags & CLONE_SETTLS) { |
575 |
+diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c |
576 |
+index e173b6187ad56..516d232e66d9d 100644 |
577 |
+--- a/arch/s390/mm/fault.c |
578 |
++++ b/arch/s390/mm/fault.c |
579 |
+@@ -379,7 +379,9 @@ static inline vm_fault_t do_exception(struct pt_regs *regs, int access) |
580 |
+ flags = FAULT_FLAG_DEFAULT; |
581 |
+ if (user_mode(regs)) |
582 |
+ flags |= FAULT_FLAG_USER; |
583 |
+- if (access == VM_WRITE || is_write) |
584 |
++ if (is_write) |
585 |
++ access = VM_WRITE; |
586 |
++ if (access == VM_WRITE) |
587 |
+ flags |= FAULT_FLAG_WRITE; |
588 |
+ mmap_read_lock(mm); |
589 |
+ |
590 |
+diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h |
591 |
+index 4910bf230d7b4..62208ec04ca4b 100644 |
592 |
+--- a/arch/x86/boot/compressed/misc.h |
593 |
++++ b/arch/x86/boot/compressed/misc.h |
594 |
+@@ -132,7 +132,17 @@ void snp_set_page_private(unsigned long paddr); |
595 |
+ void snp_set_page_shared(unsigned long paddr); |
596 |
+ void sev_prep_identity_maps(unsigned long top_level_pgt); |
597 |
+ #else |
598 |
+-static inline void sev_enable(struct boot_params *bp) { } |
599 |
++static inline void sev_enable(struct boot_params *bp) |
600 |
++{ |
601 |
++ /* |
602 |
++ * bp->cc_blob_address should only be set by boot/compressed kernel. |
603 |
++ * Initialize it to 0 unconditionally (thus here in this stub too) to |
604 |
++ * ensure that uninitialized values from buggy bootloaders aren't |
605 |
++ * propagated. |
606 |
++ */ |
607 |
++ if (bp) |
608 |
++ bp->cc_blob_address = 0; |
609 |
++} |
610 |
+ static inline void sev_es_shutdown_ghcb(void) { } |
611 |
+ static inline bool sev_es_check_ghcb_fault(unsigned long address) |
612 |
+ { |
613 |
+diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c |
614 |
+index 52f989f6acc28..c93930d5ccbd0 100644 |
615 |
+--- a/arch/x86/boot/compressed/sev.c |
616 |
++++ b/arch/x86/boot/compressed/sev.c |
617 |
+@@ -276,6 +276,14 @@ void sev_enable(struct boot_params *bp) |
618 |
+ struct msr m; |
619 |
+ bool snp; |
620 |
+ |
621 |
++ /* |
622 |
++ * bp->cc_blob_address should only be set by boot/compressed kernel. |
623 |
++ * Initialize it to 0 to ensure that uninitialized values from |
624 |
++ * buggy bootloaders aren't propagated. |
625 |
++ */ |
626 |
++ if (bp) |
627 |
++ bp->cc_blob_address = 0; |
628 |
++ |
629 |
+ /* |
630 |
+ * Setup/preliminary detection of SNP. This will be sanity-checked |
631 |
+ * against CPUID/MSR values later. |
632 |
+diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S |
633 |
+index 682338e7e2a38..4dd19819053a5 100644 |
634 |
+--- a/arch/x86/entry/entry_64_compat.S |
635 |
++++ b/arch/x86/entry/entry_64_compat.S |
636 |
+@@ -311,7 +311,7 @@ SYM_CODE_START(entry_INT80_compat) |
637 |
+ * Interrupts are off on entry. |
638 |
+ */ |
639 |
+ ASM_CLAC /* Do this early to minimize exposure */ |
640 |
+- SWAPGS |
641 |
++ ALTERNATIVE "swapgs", "", X86_FEATURE_XENPV |
642 |
+ |
643 |
+ /* |
644 |
+ * User tracing code (ptrace or signal handlers) might assume that |
645 |
+diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c |
646 |
+index ba60427caa6d3..9b48d957d2b3f 100644 |
647 |
+--- a/arch/x86/events/intel/ds.c |
648 |
++++ b/arch/x86/events/intel/ds.c |
649 |
+@@ -291,6 +291,7 @@ static u64 load_latency_data(struct perf_event *event, u64 status) |
650 |
+ static u64 store_latency_data(struct perf_event *event, u64 status) |
651 |
+ { |
652 |
+ union intel_x86_pebs_dse dse; |
653 |
++ union perf_mem_data_src src; |
654 |
+ u64 val; |
655 |
+ |
656 |
+ dse.val = status; |
657 |
+@@ -304,7 +305,14 @@ static u64 store_latency_data(struct perf_event *event, u64 status) |
658 |
+ |
659 |
+ val |= P(BLK, NA); |
660 |
+ |
661 |
+- return val; |
662 |
++ /* |
663 |
++ * the pebs_data_source table is only for loads |
664 |
++ * so override the mem_op to say STORE instead |
665 |
++ */ |
666 |
++ src.val = val; |
667 |
++ src.mem_op = P(OP,STORE); |
668 |
++ |
669 |
++ return src.val; |
670 |
+ } |
671 |
+ |
672 |
+ struct pebs_record_core { |
673 |
+@@ -822,7 +830,7 @@ struct event_constraint intel_glm_pebs_event_constraints[] = { |
674 |
+ |
675 |
+ struct event_constraint intel_grt_pebs_event_constraints[] = { |
676 |
+ /* Allow all events as PEBS with no flags */ |
677 |
+- INTEL_HYBRID_LAT_CONSTRAINT(0x5d0, 0xf), |
678 |
++ INTEL_HYBRID_LAT_CONSTRAINT(0x5d0, 0x3), |
679 |
+ INTEL_HYBRID_LAT_CONSTRAINT(0x6d0, 0xf), |
680 |
+ EVENT_CONSTRAINT_END |
681 |
+ }; |
682 |
+diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c |
683 |
+index 4f70fb6c2c1eb..47fca6a7a8bcd 100644 |
684 |
+--- a/arch/x86/events/intel/lbr.c |
685 |
++++ b/arch/x86/events/intel/lbr.c |
686 |
+@@ -1097,6 +1097,14 @@ static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event) |
687 |
+ |
688 |
+ if (static_cpu_has(X86_FEATURE_ARCH_LBR)) { |
689 |
+ reg->config = mask; |
690 |
++ |
691 |
++ /* |
692 |
++ * The Arch LBR HW can retrieve the common branch types |
693 |
++ * from the LBR_INFO. It doesn't require the high overhead |
694 |
++ * SW disassemble. |
695 |
++ * Enable the branch type by default for the Arch LBR. |
696 |
++ */ |
697 |
++ reg->reg |= X86_BR_TYPE_SAVE; |
698 |
+ return 0; |
699 |
+ } |
700 |
+ |
701 |
+diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c |
702 |
+index ce440011cc4e4..1ef4f7861e2ec 100644 |
703 |
+--- a/arch/x86/events/intel/uncore_snb.c |
704 |
++++ b/arch/x86/events/intel/uncore_snb.c |
705 |
+@@ -841,6 +841,22 @@ int snb_pci2phy_map_init(int devid) |
706 |
+ return 0; |
707 |
+ } |
708 |
+ |
709 |
++static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event) |
710 |
++{ |
711 |
++ struct hw_perf_event *hwc = &event->hw; |
712 |
++ |
713 |
++ /* |
714 |
++ * SNB IMC counters are 32-bit and are laid out back to back |
715 |
++ * in MMIO space. Therefore we must use a 32-bit accessor function |
716 |
++ * using readq() from uncore_mmio_read_counter() causes problems |
717 |
++ * because it is reading 64-bit at a time. This is okay for the |
718 |
++ * uncore_perf_event_update() function because it drops the upper |
719 |
++ * 32-bits but not okay for plain uncore_read_counter() as invoked |
720 |
++ * in uncore_pmu_event_start(). |
721 |
++ */ |
722 |
++ return (u64)readl(box->io_addr + hwc->event_base); |
723 |
++} |
724 |
++ |
725 |
+ static struct pmu snb_uncore_imc_pmu = { |
726 |
+ .task_ctx_nr = perf_invalid_context, |
727 |
+ .event_init = snb_uncore_imc_event_init, |
728 |
+@@ -860,7 +876,7 @@ static struct intel_uncore_ops snb_uncore_imc_ops = { |
729 |
+ .disable_event = snb_uncore_imc_disable_event, |
730 |
+ .enable_event = snb_uncore_imc_enable_event, |
731 |
+ .hw_config = snb_uncore_imc_hw_config, |
732 |
+- .read_counter = uncore_mmio_read_counter, |
733 |
++ .read_counter = snb_uncore_imc_read_counter, |
734 |
+ }; |
735 |
+ |
736 |
+ static struct intel_uncore_type snb_uncore_imc = { |
737 |
+diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h |
738 |
+index ede8990f3e416..ccbb838f995c8 100644 |
739 |
+--- a/arch/x86/include/asm/cpufeatures.h |
740 |
++++ b/arch/x86/include/asm/cpufeatures.h |
741 |
+@@ -456,7 +456,8 @@ |
742 |
+ #define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */ |
743 |
+ #define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */ |
744 |
+ #define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */ |
745 |
+-#define X86_BUG_RETBLEED X86_BUG(26) /* CPU is affected by RETBleed */ |
746 |
+-#define X86_BUG_EIBRS_PBRSB X86_BUG(27) /* EIBRS is vulnerable to Post Barrier RSB Predictions */ |
747 |
++#define X86_BUG_MMIO_UNKNOWN X86_BUG(26) /* CPU is too old and its MMIO Stale Data status is unknown */ |
748 |
++#define X86_BUG_RETBLEED X86_BUG(27) /* CPU is affected by RETBleed */ |
749 |
++#define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* EIBRS is vulnerable to Post Barrier RSB Predictions */ |
750 |
+ |
751 |
+ #endif /* _ASM_X86_CPUFEATURES_H */ |
752 |
+diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h |
753 |
+index d3a3cc6772ee1..c31083d77e09c 100644 |
754 |
+--- a/arch/x86/include/asm/nospec-branch.h |
755 |
++++ b/arch/x86/include/asm/nospec-branch.h |
756 |
+@@ -35,33 +35,56 @@ |
757 |
+ #define RSB_CLEAR_LOOPS 32 /* To forcibly overwrite all entries */ |
758 |
+ |
759 |
+ /* |
760 |
++ * Common helper for __FILL_RETURN_BUFFER and __FILL_ONE_RETURN. |
761 |
++ */ |
762 |
++#define __FILL_RETURN_SLOT \ |
763 |
++ ANNOTATE_INTRA_FUNCTION_CALL; \ |
764 |
++ call 772f; \ |
765 |
++ int3; \ |
766 |
++772: |
767 |
++ |
768 |
++/* |
769 |
++ * Stuff the entire RSB. |
770 |
++ * |
771 |
+ * Google experimented with loop-unrolling and this turned out to be |
772 |
+ * the optimal version - two calls, each with their own speculation |
773 |
+ * trap should their return address end up getting used, in a loop. |
774 |
+ */ |
775 |
+-#define __FILL_RETURN_BUFFER(reg, nr, sp) \ |
776 |
+- mov $(nr/2), reg; \ |
777 |
+-771: \ |
778 |
+- ANNOTATE_INTRA_FUNCTION_CALL; \ |
779 |
+- call 772f; \ |
780 |
+-773: /* speculation trap */ \ |
781 |
+- UNWIND_HINT_EMPTY; \ |
782 |
+- pause; \ |
783 |
+- lfence; \ |
784 |
+- jmp 773b; \ |
785 |
+-772: \ |
786 |
+- ANNOTATE_INTRA_FUNCTION_CALL; \ |
787 |
+- call 774f; \ |
788 |
+-775: /* speculation trap */ \ |
789 |
+- UNWIND_HINT_EMPTY; \ |
790 |
+- pause; \ |
791 |
+- lfence; \ |
792 |
+- jmp 775b; \ |
793 |
+-774: \ |
794 |
+- add $(BITS_PER_LONG/8) * 2, sp; \ |
795 |
+- dec reg; \ |
796 |
+- jnz 771b; \ |
797 |
+- /* barrier for jnz misprediction */ \ |
798 |
++#ifdef CONFIG_X86_64 |
799 |
++#define __FILL_RETURN_BUFFER(reg, nr) \ |
800 |
++ mov $(nr/2), reg; \ |
801 |
++771: \ |
802 |
++ __FILL_RETURN_SLOT \ |
803 |
++ __FILL_RETURN_SLOT \ |
804 |
++ add $(BITS_PER_LONG/8) * 2, %_ASM_SP; \ |
805 |
++ dec reg; \ |
806 |
++ jnz 771b; \ |
807 |
++ /* barrier for jnz misprediction */ \ |
808 |
++ lfence; |
809 |
++#else |
810 |
++/* |
811 |
++ * i386 doesn't unconditionally have LFENCE, as such it can't |
812 |
++ * do a loop. |
813 |
++ */ |
814 |
++#define __FILL_RETURN_BUFFER(reg, nr) \ |
815 |
++ .rept nr; \ |
816 |
++ __FILL_RETURN_SLOT; \ |
817 |
++ .endr; \ |
818 |
++ add $(BITS_PER_LONG/8) * nr, %_ASM_SP; |
819 |
++#endif |
820 |
++ |
821 |
++/* |
822 |
++ * Stuff a single RSB slot. |
823 |
++ * |
824 |
++ * To mitigate Post-Barrier RSB speculation, one CALL instruction must be |
825 |
++ * forced to retire before letting a RET instruction execute. |
826 |
++ * |
827 |
++ * On PBRSB-vulnerable CPUs, it is not safe for a RET to be executed |
828 |
++ * before this point. |
829 |
++ */ |
830 |
++#define __FILL_ONE_RETURN \ |
831 |
++ __FILL_RETURN_SLOT \ |
832 |
++ add $(BITS_PER_LONG/8), %_ASM_SP; \ |
833 |
+ lfence; |
834 |
+ |
835 |
+ #ifdef __ASSEMBLY__ |
836 |
+@@ -120,28 +143,15 @@ |
837 |
+ #endif |
838 |
+ .endm |
839 |
+ |
840 |
+-.macro ISSUE_UNBALANCED_RET_GUARD |
841 |
+- ANNOTATE_INTRA_FUNCTION_CALL |
842 |
+- call .Lunbalanced_ret_guard_\@ |
843 |
+- int3 |
844 |
+-.Lunbalanced_ret_guard_\@: |
845 |
+- add $(BITS_PER_LONG/8), %_ASM_SP |
846 |
+- lfence |
847 |
+-.endm |
848 |
+- |
849 |
+ /* |
850 |
+ * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP |
851 |
+ * monstrosity above, manually. |
852 |
+ */ |
853 |
+-.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2 |
854 |
+-.ifb \ftr2 |
855 |
+- ALTERNATIVE "jmp .Lskip_rsb_\@", "", \ftr |
856 |
+-.else |
857 |
+- ALTERNATIVE_2 "jmp .Lskip_rsb_\@", "", \ftr, "jmp .Lunbalanced_\@", \ftr2 |
858 |
+-.endif |
859 |
+- __FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP) |
860 |
+-.Lunbalanced_\@: |
861 |
+- ISSUE_UNBALANCED_RET_GUARD |
862 |
++.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2=ALT_NOT(X86_FEATURE_ALWAYS) |
863 |
++ ALTERNATIVE_2 "jmp .Lskip_rsb_\@", \ |
864 |
++ __stringify(__FILL_RETURN_BUFFER(\reg,\nr)), \ftr, \ |
865 |
++ __stringify(__FILL_ONE_RETURN), \ftr2 |
866 |
++ |
867 |
+ .Lskip_rsb_\@: |
868 |
+ .endm |
869 |
+ |
870 |
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c |
871 |
+index 510d85261132b..da7c361f47e0d 100644 |
872 |
+--- a/arch/x86/kernel/cpu/bugs.c |
873 |
++++ b/arch/x86/kernel/cpu/bugs.c |
874 |
+@@ -433,7 +433,8 @@ static void __init mmio_select_mitigation(void) |
875 |
+ u64 ia32_cap; |
876 |
+ |
877 |
+ if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) || |
878 |
+- cpu_mitigations_off()) { |
879 |
++ boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN) || |
880 |
++ cpu_mitigations_off()) { |
881 |
+ mmio_mitigation = MMIO_MITIGATION_OFF; |
882 |
+ return; |
883 |
+ } |
884 |
+@@ -538,6 +539,8 @@ out: |
885 |
+ pr_info("TAA: %s\n", taa_strings[taa_mitigation]); |
886 |
+ if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) |
887 |
+ pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]); |
888 |
++ else if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN)) |
889 |
++ pr_info("MMIO Stale Data: Unknown: No mitigations\n"); |
890 |
+ } |
891 |
+ |
892 |
+ static void __init md_clear_select_mitigation(void) |
893 |
+@@ -2275,6 +2278,9 @@ static ssize_t tsx_async_abort_show_state(char *buf) |
894 |
+ |
895 |
+ static ssize_t mmio_stale_data_show_state(char *buf) |
896 |
+ { |
897 |
++ if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN)) |
898 |
++ return sysfs_emit(buf, "Unknown: No mitigations\n"); |
899 |
++ |
900 |
+ if (mmio_mitigation == MMIO_MITIGATION_OFF) |
901 |
+ return sysfs_emit(buf, "%s\n", mmio_strings[mmio_mitigation]); |
902 |
+ |
903 |
+@@ -2421,6 +2427,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr |
904 |
+ return srbds_show_state(buf); |
905 |
+ |
906 |
+ case X86_BUG_MMIO_STALE_DATA: |
907 |
++ case X86_BUG_MMIO_UNKNOWN: |
908 |
+ return mmio_stale_data_show_state(buf); |
909 |
+ |
910 |
+ case X86_BUG_RETBLEED: |
911 |
+@@ -2480,7 +2487,10 @@ ssize_t cpu_show_srbds(struct device *dev, struct device_attribute *attr, char * |
912 |
+ |
913 |
+ ssize_t cpu_show_mmio_stale_data(struct device *dev, struct device_attribute *attr, char *buf) |
914 |
+ { |
915 |
+- return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_STALE_DATA); |
916 |
++ if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN)) |
917 |
++ return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_UNKNOWN); |
918 |
++ else |
919 |
++ return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_STALE_DATA); |
920 |
+ } |
921 |
+ |
922 |
+ ssize_t cpu_show_retbleed(struct device *dev, struct device_attribute *attr, char *buf) |
923 |
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c |
924 |
+index 64a73f415f036..3e508f2390983 100644 |
925 |
+--- a/arch/x86/kernel/cpu/common.c |
926 |
++++ b/arch/x86/kernel/cpu/common.c |
927 |
+@@ -1135,7 +1135,8 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c) |
928 |
+ #define NO_SWAPGS BIT(6) |
929 |
+ #define NO_ITLB_MULTIHIT BIT(7) |
930 |
+ #define NO_SPECTRE_V2 BIT(8) |
931 |
+-#define NO_EIBRS_PBRSB BIT(9) |
932 |
++#define NO_MMIO BIT(9) |
933 |
++#define NO_EIBRS_PBRSB BIT(10) |
934 |
+ |
935 |
+ #define VULNWL(vendor, family, model, whitelist) \ |
936 |
+ X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, whitelist) |
937 |
+@@ -1158,6 +1159,11 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { |
938 |
+ VULNWL(VORTEX, 6, X86_MODEL_ANY, NO_SPECULATION), |
939 |
+ |
940 |
+ /* Intel Family 6 */ |
941 |
++ VULNWL_INTEL(TIGERLAKE, NO_MMIO), |
942 |
++ VULNWL_INTEL(TIGERLAKE_L, NO_MMIO), |
943 |
++ VULNWL_INTEL(ALDERLAKE, NO_MMIO), |
944 |
++ VULNWL_INTEL(ALDERLAKE_L, NO_MMIO), |
945 |
++ |
946 |
+ VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION | NO_ITLB_MULTIHIT), |
947 |
+ VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION | NO_ITLB_MULTIHIT), |
948 |
+ VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT), |
949 |
+@@ -1176,9 +1182,9 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { |
950 |
+ VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), |
951 |
+ VULNWL_INTEL(ATOM_AIRMONT_NP, NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), |
952 |
+ |
953 |
+- VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), |
954 |
+- VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), |
955 |
+- VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB), |
956 |
++ VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), |
957 |
++ VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), |
958 |
++ VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB), |
959 |
+ |
960 |
+ /* |
961 |
+ * Technically, swapgs isn't serializing on AMD (despite it previously |
962 |
+@@ -1193,18 +1199,18 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { |
963 |
+ VULNWL_INTEL(ATOM_TREMONT_D, NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB), |
964 |
+ |
965 |
+ /* AMD Family 0xf - 0x12 */ |
966 |
+- VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
967 |
+- VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
968 |
+- VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
969 |
+- VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
970 |
++ VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), |
971 |
++ VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), |
972 |
++ VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), |
973 |
++ VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), |
974 |
+ |
975 |
+ /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ |
976 |
+- VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
977 |
+- VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
978 |
++ VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), |
979 |
++ VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), |
980 |
+ |
981 |
+ /* Zhaoxin Family 7 */ |
982 |
+- VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS), |
983 |
+- VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS), |
984 |
++ VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO), |
985 |
++ VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO), |
986 |
+ {} |
987 |
+ }; |
988 |
+ |
989 |
+@@ -1358,10 +1364,16 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) |
990 |
+ * Affected CPU list is generally enough to enumerate the vulnerability, |
991 |
+ * but for virtualization case check for ARCH_CAP MSR bits also, VMM may |
992 |
+ * not want the guest to enumerate the bug. |
993 |
++ * |
994 |
++ * Set X86_BUG_MMIO_UNKNOWN for CPUs that are neither in the blacklist, |
995 |
++ * nor in the whitelist and also don't enumerate MSR ARCH_CAP MMIO bits. |
996 |
+ */ |
997 |
+- if (cpu_matches(cpu_vuln_blacklist, MMIO) && |
998 |
+- !arch_cap_mmio_immune(ia32_cap)) |
999 |
+- setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA); |
1000 |
++ if (!arch_cap_mmio_immune(ia32_cap)) { |
1001 |
++ if (cpu_matches(cpu_vuln_blacklist, MMIO)) |
1002 |
++ setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA); |
1003 |
++ else if (!cpu_matches(cpu_vuln_whitelist, NO_MMIO)) |
1004 |
++ setup_force_cpu_bug(X86_BUG_MMIO_UNKNOWN); |
1005 |
++ } |
1006 |
+ |
1007 |
+ if (!cpu_has(c, X86_FEATURE_BTC_NO)) { |
1008 |
+ if (cpu_matches(cpu_vuln_blacklist, RETBLEED) || (ia32_cap & ARCH_CAP_RSBA)) |
1009 |
+diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c |
1010 |
+index 63dc626627a03..4f84c3f11af5b 100644 |
1011 |
+--- a/arch/x86/kernel/sev.c |
1012 |
++++ b/arch/x86/kernel/sev.c |
1013 |
+@@ -701,7 +701,13 @@ e_term: |
1014 |
+ void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, |
1015 |
+ unsigned int npages) |
1016 |
+ { |
1017 |
+- if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) |
1018 |
++ /* |
1019 |
++ * This can be invoked in early boot while running identity mapped, so |
1020 |
++ * use an open coded check for SNP instead of using cc_platform_has(). |
1021 |
++ * This eliminates worries about jump tables or checking boot_cpu_data |
1022 |
++ * in the cc_platform_has() function. |
1023 |
++ */ |
1024 |
++ if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED)) |
1025 |
+ return; |
1026 |
+ |
1027 |
+ /* |
1028 |
+@@ -717,7 +723,13 @@ void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long padd |
1029 |
+ void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, |
1030 |
+ unsigned int npages) |
1031 |
+ { |
1032 |
+- if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) |
1033 |
++ /* |
1034 |
++ * This can be invoked in early boot while running identity mapped, so |
1035 |
++ * use an open coded check for SNP instead of using cc_platform_has(). |
1036 |
++ * This eliminates worries about jump tables or checking boot_cpu_data |
1037 |
++ * in the cc_platform_has() function. |
1038 |
++ */ |
1039 |
++ if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED)) |
1040 |
+ return; |
1041 |
+ |
1042 |
+ /* Invalidate the memory pages before they are marked shared in the RMP table. */ |
1043 |
+diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c |
1044 |
+index 38185aedf7d16..0ea57da929407 100644 |
1045 |
+--- a/arch/x86/kernel/unwind_orc.c |
1046 |
++++ b/arch/x86/kernel/unwind_orc.c |
1047 |
+@@ -93,22 +93,27 @@ static struct orc_entry *orc_find(unsigned long ip); |
1048 |
+ static struct orc_entry *orc_ftrace_find(unsigned long ip) |
1049 |
+ { |
1050 |
+ struct ftrace_ops *ops; |
1051 |
+- unsigned long caller; |
1052 |
++ unsigned long tramp_addr, offset; |
1053 |
+ |
1054 |
+ ops = ftrace_ops_trampoline(ip); |
1055 |
+ if (!ops) |
1056 |
+ return NULL; |
1057 |
+ |
1058 |
++ /* Set tramp_addr to the start of the code copied by the trampoline */ |
1059 |
+ if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) |
1060 |
+- caller = (unsigned long)ftrace_regs_call; |
1061 |
++ tramp_addr = (unsigned long)ftrace_regs_caller; |
1062 |
+ else |
1063 |
+- caller = (unsigned long)ftrace_call; |
1064 |
++ tramp_addr = (unsigned long)ftrace_caller; |
1065 |
++ |
1066 |
++ /* Now place tramp_addr to the location within the trampoline ip is at */ |
1067 |
++ offset = ip - ops->trampoline; |
1068 |
++ tramp_addr += offset; |
1069 |
+ |
1070 |
+ /* Prevent unlikely recursion */ |
1071 |
+- if (ip == caller) |
1072 |
++ if (ip == tramp_addr) |
1073 |
+ return NULL; |
1074 |
+ |
1075 |
+- return orc_find(caller); |
1076 |
++ return orc_find(tramp_addr); |
1077 |
+ } |
1078 |
+ #else |
1079 |
+ static struct orc_entry *orc_ftrace_find(unsigned long ip) |
1080 |
+diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c |
1081 |
+index d5ef64ddd35e9..66a209f7eb86d 100644 |
1082 |
+--- a/arch/x86/mm/pat/memtype.c |
1083 |
++++ b/arch/x86/mm/pat/memtype.c |
1084 |
+@@ -62,6 +62,7 @@ |
1085 |
+ |
1086 |
+ static bool __read_mostly pat_bp_initialized; |
1087 |
+ static bool __read_mostly pat_disabled = !IS_ENABLED(CONFIG_X86_PAT); |
1088 |
++static bool __initdata pat_force_disabled = !IS_ENABLED(CONFIG_X86_PAT); |
1089 |
+ static bool __read_mostly pat_bp_enabled; |
1090 |
+ static bool __read_mostly pat_cm_initialized; |
1091 |
+ |
1092 |
+@@ -86,6 +87,7 @@ void pat_disable(const char *msg_reason) |
1093 |
+ static int __init nopat(char *str) |
1094 |
+ { |
1095 |
+ pat_disable("PAT support disabled via boot option."); |
1096 |
++ pat_force_disabled = true; |
1097 |
+ return 0; |
1098 |
+ } |
1099 |
+ early_param("nopat", nopat); |
1100 |
+@@ -272,7 +274,7 @@ static void pat_ap_init(u64 pat) |
1101 |
+ wrmsrl(MSR_IA32_CR_PAT, pat); |
1102 |
+ } |
1103 |
+ |
1104 |
+-void init_cache_modes(void) |
1105 |
++void __init init_cache_modes(void) |
1106 |
+ { |
1107 |
+ u64 pat = 0; |
1108 |
+ |
1109 |
+@@ -313,6 +315,12 @@ void init_cache_modes(void) |
1110 |
+ */ |
1111 |
+ pat = PAT(0, WB) | PAT(1, WT) | PAT(2, UC_MINUS) | PAT(3, UC) | |
1112 |
+ PAT(4, WB) | PAT(5, WT) | PAT(6, UC_MINUS) | PAT(7, UC); |
1113 |
++ } else if (!pat_force_disabled && cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) { |
1114 |
++ /* |
1115 |
++ * Clearly PAT is enabled underneath. Allow pat_enabled() to |
1116 |
++ * reflect this. |
1117 |
++ */ |
1118 |
++ pat_bp_enabled = true; |
1119 |
+ } |
1120 |
+ |
1121 |
+ __init_cache_modes(pat); |
1122 |
+diff --git a/block/blk-mq.c b/block/blk-mq.c |
1123 |
+index 1eb13d57a946f..0a299941c622e 100644 |
1124 |
+--- a/block/blk-mq.c |
1125 |
++++ b/block/blk-mq.c |
1126 |
+@@ -1925,7 +1925,8 @@ out: |
1127 |
+ /* If we didn't flush the entire list, we could have told the driver |
1128 |
+ * there was more coming, but that turned out to be a lie. |
1129 |
+ */ |
1130 |
+- if ((!list_empty(list) || errors) && q->mq_ops->commit_rqs && queued) |
1131 |
++ if ((!list_empty(list) || errors || needs_resource || |
1132 |
++ ret == BLK_STS_DEV_RESOURCE) && q->mq_ops->commit_rqs && queued) |
1133 |
+ q->mq_ops->commit_rqs(hctx); |
1134 |
+ /* |
1135 |
+ * Any items that need requeuing? Stuff them into hctx->dispatch, |
1136 |
+@@ -2678,6 +2679,7 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx, |
1137 |
+ list_del_init(&rq->queuelist); |
1138 |
+ ret = blk_mq_request_issue_directly(rq, list_empty(list)); |
1139 |
+ if (ret != BLK_STS_OK) { |
1140 |
++ errors++; |
1141 |
+ if (ret == BLK_STS_RESOURCE || |
1142 |
+ ret == BLK_STS_DEV_RESOURCE) { |
1143 |
+ blk_mq_request_bypass_insert(rq, false, |
1144 |
+@@ -2685,7 +2687,6 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx, |
1145 |
+ break; |
1146 |
+ } |
1147 |
+ blk_mq_end_request(rq, ret); |
1148 |
+- errors++; |
1149 |
+ } else |
1150 |
+ queued++; |
1151 |
+ } |
1152 |
+diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c |
1153 |
+index d8b2dfcd59b5f..83a430ad22556 100644 |
1154 |
+--- a/drivers/acpi/processor_thermal.c |
1155 |
++++ b/drivers/acpi/processor_thermal.c |
1156 |
+@@ -151,7 +151,7 @@ void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy) |
1157 |
+ unsigned int cpu; |
1158 |
+ |
1159 |
+ for_each_cpu(cpu, policy->related_cpus) { |
1160 |
+- struct acpi_processor *pr = per_cpu(processors, policy->cpu); |
1161 |
++ struct acpi_processor *pr = per_cpu(processors, cpu); |
1162 |
+ |
1163 |
+ if (pr) |
1164 |
+ freq_qos_remove_request(&pr->thermal_req); |
1165 |
+diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c |
1166 |
+index d044418294f94..7981a25983764 100644 |
1167 |
+--- a/drivers/android/binder_alloc.c |
1168 |
++++ b/drivers/android/binder_alloc.c |
1169 |
+@@ -395,12 +395,15 @@ static struct binder_buffer *binder_alloc_new_buf_locked( |
1170 |
+ size_t size, data_offsets_size; |
1171 |
+ int ret; |
1172 |
+ |
1173 |
++ mmap_read_lock(alloc->vma_vm_mm); |
1174 |
+ if (!binder_alloc_get_vma(alloc)) { |
1175 |
++ mmap_read_unlock(alloc->vma_vm_mm); |
1176 |
+ binder_alloc_debug(BINDER_DEBUG_USER_ERROR, |
1177 |
+ "%d: binder_alloc_buf, no vma\n", |
1178 |
+ alloc->pid); |
1179 |
+ return ERR_PTR(-ESRCH); |
1180 |
+ } |
1181 |
++ mmap_read_unlock(alloc->vma_vm_mm); |
1182 |
+ |
1183 |
+ data_offsets_size = ALIGN(data_size, sizeof(void *)) + |
1184 |
+ ALIGN(offsets_size, sizeof(void *)); |
1185 |
+@@ -922,17 +925,25 @@ void binder_alloc_print_pages(struct seq_file *m, |
1186 |
+ * Make sure the binder_alloc is fully initialized, otherwise we might |
1187 |
+ * read inconsistent state. |
1188 |
+ */ |
1189 |
+- if (binder_alloc_get_vma(alloc) != NULL) { |
1190 |
+- for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) { |
1191 |
+- page = &alloc->pages[i]; |
1192 |
+- if (!page->page_ptr) |
1193 |
+- free++; |
1194 |
+- else if (list_empty(&page->lru)) |
1195 |
+- active++; |
1196 |
+- else |
1197 |
+- lru++; |
1198 |
+- } |
1199 |
++ |
1200 |
++ mmap_read_lock(alloc->vma_vm_mm); |
1201 |
++ if (binder_alloc_get_vma(alloc) == NULL) { |
1202 |
++ mmap_read_unlock(alloc->vma_vm_mm); |
1203 |
++ goto uninitialized; |
1204 |
+ } |
1205 |
++ |
1206 |
++ mmap_read_unlock(alloc->vma_vm_mm); |
1207 |
++ for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) { |
1208 |
++ page = &alloc->pages[i]; |
1209 |
++ if (!page->page_ptr) |
1210 |
++ free++; |
1211 |
++ else if (list_empty(&page->lru)) |
1212 |
++ active++; |
1213 |
++ else |
1214 |
++ lru++; |
1215 |
++ } |
1216 |
++ |
1217 |
++uninitialized: |
1218 |
+ mutex_unlock(&alloc->mutex); |
1219 |
+ seq_printf(m, " pages: %d:%d:%d\n", active, lru, free); |
1220 |
+ seq_printf(m, " pages high watermark: %zu\n", alloc->pages_high); |
1221 |
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c |
1222 |
+index 084f9b8a0ba3c..a59910ef948e9 100644 |
1223 |
+--- a/drivers/block/loop.c |
1224 |
++++ b/drivers/block/loop.c |
1225 |
+@@ -979,6 +979,11 @@ loop_set_status_from_info(struct loop_device *lo, |
1226 |
+ |
1227 |
+ lo->lo_offset = info->lo_offset; |
1228 |
+ lo->lo_sizelimit = info->lo_sizelimit; |
1229 |
++ |
1230 |
++ /* loff_t vars have been assigned __u64 */ |
1231 |
++ if (lo->lo_offset < 0 || lo->lo_sizelimit < 0) |
1232 |
++ return -EOVERFLOW; |
1233 |
++ |
1234 |
+ memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); |
1235 |
+ lo->lo_file_name[LO_NAME_SIZE-1] = 0; |
1236 |
+ lo->lo_flags = info->lo_flags; |
1237 |
+diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c |
1238 |
+index b8549c61ff2ce..b144be41290e3 100644 |
1239 |
+--- a/drivers/block/zram/zram_drv.c |
1240 |
++++ b/drivers/block/zram/zram_drv.c |
1241 |
+@@ -1144,14 +1144,15 @@ static ssize_t bd_stat_show(struct device *dev, |
1242 |
+ static ssize_t debug_stat_show(struct device *dev, |
1243 |
+ struct device_attribute *attr, char *buf) |
1244 |
+ { |
1245 |
+- int version = 2; |
1246 |
++ int version = 1; |
1247 |
+ struct zram *zram = dev_to_zram(dev); |
1248 |
+ ssize_t ret; |
1249 |
+ |
1250 |
+ down_read(&zram->init_lock); |
1251 |
+ ret = scnprintf(buf, PAGE_SIZE, |
1252 |
+- "version: %d\n%8llu\n", |
1253 |
++ "version: %d\n%8llu %8llu\n", |
1254 |
+ version, |
1255 |
++ (u64)atomic64_read(&zram->stats.writestall), |
1256 |
+ (u64)atomic64_read(&zram->stats.miss_free)); |
1257 |
+ up_read(&zram->init_lock); |
1258 |
+ |
1259 |
+@@ -1367,6 +1368,7 @@ static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, |
1260 |
+ } |
1261 |
+ kunmap_atomic(mem); |
1262 |
+ |
1263 |
++compress_again: |
1264 |
+ zstrm = zcomp_stream_get(zram->comp); |
1265 |
+ src = kmap_atomic(page); |
1266 |
+ ret = zcomp_compress(zstrm, src, &comp_len); |
1267 |
+@@ -1375,20 +1377,39 @@ static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, |
1268 |
+ if (unlikely(ret)) { |
1269 |
+ zcomp_stream_put(zram->comp); |
1270 |
+ pr_err("Compression failed! err=%d\n", ret); |
1271 |
++ zs_free(zram->mem_pool, handle); |
1272 |
+ return ret; |
1273 |
+ } |
1274 |
+ |
1275 |
+ if (comp_len >= huge_class_size) |
1276 |
+ comp_len = PAGE_SIZE; |
1277 |
+- |
1278 |
+- handle = zs_malloc(zram->mem_pool, comp_len, |
1279 |
+- __GFP_KSWAPD_RECLAIM | |
1280 |
+- __GFP_NOWARN | |
1281 |
+- __GFP_HIGHMEM | |
1282 |
+- __GFP_MOVABLE); |
1283 |
+- |
1284 |
+- if (unlikely(!handle)) { |
1285 |
++ /* |
1286 |
++ * handle allocation has 2 paths: |
1287 |
++ * a) fast path is executed with preemption disabled (for |
1288 |
++ * per-cpu streams) and has __GFP_DIRECT_RECLAIM bit clear, |
1289 |
++ * since we can't sleep; |
1290 |
++ * b) slow path enables preemption and attempts to allocate |
1291 |
++ * the page with __GFP_DIRECT_RECLAIM bit set. we have to |
1292 |
++ * put per-cpu compression stream and, thus, to re-do |
1293 |
++ * the compression once handle is allocated. |
1294 |
++ * |
1295 |
++ * if we have a 'non-null' handle here then we are coming |
1296 |
++ * from the slow path and handle has already been allocated. |
1297 |
++ */ |
1298 |
++ if (!handle) |
1299 |
++ handle = zs_malloc(zram->mem_pool, comp_len, |
1300 |
++ __GFP_KSWAPD_RECLAIM | |
1301 |
++ __GFP_NOWARN | |
1302 |
++ __GFP_HIGHMEM | |
1303 |
++ __GFP_MOVABLE); |
1304 |
++ if (!handle) { |
1305 |
+ zcomp_stream_put(zram->comp); |
1306 |
++ atomic64_inc(&zram->stats.writestall); |
1307 |
++ handle = zs_malloc(zram->mem_pool, comp_len, |
1308 |
++ GFP_NOIO | __GFP_HIGHMEM | |
1309 |
++ __GFP_MOVABLE); |
1310 |
++ if (handle) |
1311 |
++ goto compress_again; |
1312 |
+ return -ENOMEM; |
1313 |
+ } |
1314 |
+ |
1315 |
+@@ -1946,6 +1967,7 @@ static int zram_add(void) |
1316 |
+ if (ZRAM_LOGICAL_BLOCK_SIZE == PAGE_SIZE) |
1317 |
+ blk_queue_max_write_zeroes_sectors(zram->disk->queue, UINT_MAX); |
1318 |
+ |
1319 |
++ blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, zram->disk->queue); |
1320 |
+ ret = device_add_disk(NULL, zram->disk, zram_disk_groups); |
1321 |
+ if (ret) |
1322 |
+ goto out_cleanup_disk; |
1323 |
+diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h |
1324 |
+index 158c91e548501..80c3b43b4828f 100644 |
1325 |
+--- a/drivers/block/zram/zram_drv.h |
1326 |
++++ b/drivers/block/zram/zram_drv.h |
1327 |
+@@ -81,6 +81,7 @@ struct zram_stats { |
1328 |
+ atomic64_t huge_pages_since; /* no. of huge pages since zram set up */ |
1329 |
+ atomic64_t pages_stored; /* no. of pages currently stored */ |
1330 |
+ atomic_long_t max_used_pages; /* no. of maximum pages stored */ |
1331 |
++ atomic64_t writestall; /* no. of write slow paths */ |
1332 |
+ atomic64_t miss_free; /* no. of missed free */ |
1333 |
+ #ifdef CONFIG_ZRAM_WRITEBACK |
1334 |
+ atomic64_t bd_count; /* no. of pages in backing device */ |
1335 |
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c |
1336 |
+index d9f57a20a8bc5..29ebc9e51305a 100644 |
1337 |
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c |
1338 |
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c |
1339 |
+@@ -377,12 +377,8 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) |
1340 |
+ f2g = &gfx_v10_3_kfd2kgd; |
1341 |
+ break; |
1342 |
+ case IP_VERSION(10, 3, 6): |
1343 |
+- gfx_target_version = 100306; |
1344 |
+- if (!vf) |
1345 |
+- f2g = &gfx_v10_3_kfd2kgd; |
1346 |
+- break; |
1347 |
+ case IP_VERSION(10, 3, 7): |
1348 |
+- gfx_target_version = 100307; |
1349 |
++ gfx_target_version = 100306; |
1350 |
+ if (!vf) |
1351 |
+ f2g = &gfx_v10_3_kfd2kgd; |
1352 |
+ break; |
1353 |
+diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c |
1354 |
+index 05076e530e7d4..e29175e4b44ce 100644 |
1355 |
+--- a/drivers/gpu/drm/nouveau/nouveau_bo.c |
1356 |
++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c |
1357 |
+@@ -820,6 +820,15 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, |
1358 |
+ if (ret == 0) { |
1359 |
+ ret = nouveau_fence_new(chan, false, &fence); |
1360 |
+ if (ret == 0) { |
1361 |
++ /* TODO: figure out a better solution here |
1362 |
++ * |
1363 |
++ * wait on the fence here explicitly as going through |
1364 |
++ * ttm_bo_move_accel_cleanup somehow doesn't seem to do it. |
1365 |
++ * |
1366 |
++ * Without this the operation can timeout and we'll fallback to a |
1367 |
++ * software copy, which might take several minutes to finish. |
1368 |
++ */ |
1369 |
++ nouveau_fence_wait(fence, false, false); |
1370 |
+ ret = ttm_bo_move_accel_cleanup(bo, |
1371 |
+ &fence->base, |
1372 |
+ evict, false, |
1373 |
+diff --git a/drivers/md/md.c b/drivers/md/md.c |
1374 |
+index 522b3d6b8c46b..91e7e80fce489 100644 |
1375 |
+--- a/drivers/md/md.c |
1376 |
++++ b/drivers/md/md.c |
1377 |
+@@ -6244,11 +6244,11 @@ static void mddev_detach(struct mddev *mddev) |
1378 |
+ static void __md_stop(struct mddev *mddev) |
1379 |
+ { |
1380 |
+ struct md_personality *pers = mddev->pers; |
1381 |
++ md_bitmap_destroy(mddev); |
1382 |
+ mddev_detach(mddev); |
1383 |
+ /* Ensure ->event_work is done */ |
1384 |
+ if (mddev->event_work.func) |
1385 |
+ flush_workqueue(md_misc_wq); |
1386 |
+- md_bitmap_destroy(mddev); |
1387 |
+ spin_lock(&mddev->lock); |
1388 |
+ mddev->pers = NULL; |
1389 |
+ spin_unlock(&mddev->lock); |
1390 |
+@@ -6266,6 +6266,7 @@ void md_stop(struct mddev *mddev) |
1391 |
+ /* stop the array and free an attached data structures. |
1392 |
+ * This is called from dm-raid |
1393 |
+ */ |
1394 |
++ __md_stop_writes(mddev); |
1395 |
+ __md_stop(mddev); |
1396 |
+ bioset_exit(&mddev->bio_set); |
1397 |
+ bioset_exit(&mddev->sync_set); |
1398 |
+diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c |
1399 |
+index d7fb33c078e81..1f0120cbe9e80 100644 |
1400 |
+--- a/drivers/net/bonding/bond_3ad.c |
1401 |
++++ b/drivers/net/bonding/bond_3ad.c |
1402 |
+@@ -2007,30 +2007,24 @@ void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout) |
1403 |
+ */ |
1404 |
+ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) |
1405 |
+ { |
1406 |
+- /* check that the bond is not initialized yet */ |
1407 |
+- if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr), |
1408 |
+- bond->dev->dev_addr)) { |
1409 |
+- |
1410 |
+- BOND_AD_INFO(bond).aggregator_identifier = 0; |
1411 |
+- |
1412 |
+- BOND_AD_INFO(bond).system.sys_priority = |
1413 |
+- bond->params.ad_actor_sys_prio; |
1414 |
+- if (is_zero_ether_addr(bond->params.ad_actor_system)) |
1415 |
+- BOND_AD_INFO(bond).system.sys_mac_addr = |
1416 |
+- *((struct mac_addr *)bond->dev->dev_addr); |
1417 |
+- else |
1418 |
+- BOND_AD_INFO(bond).system.sys_mac_addr = |
1419 |
+- *((struct mac_addr *)bond->params.ad_actor_system); |
1420 |
++ BOND_AD_INFO(bond).aggregator_identifier = 0; |
1421 |
++ BOND_AD_INFO(bond).system.sys_priority = |
1422 |
++ bond->params.ad_actor_sys_prio; |
1423 |
++ if (is_zero_ether_addr(bond->params.ad_actor_system)) |
1424 |
++ BOND_AD_INFO(bond).system.sys_mac_addr = |
1425 |
++ *((struct mac_addr *)bond->dev->dev_addr); |
1426 |
++ else |
1427 |
++ BOND_AD_INFO(bond).system.sys_mac_addr = |
1428 |
++ *((struct mac_addr *)bond->params.ad_actor_system); |
1429 |
+ |
1430 |
+- /* initialize how many times this module is called in one |
1431 |
+- * second (should be about every 100ms) |
1432 |
+- */ |
1433 |
+- ad_ticks_per_sec = tick_resolution; |
1434 |
++ /* initialize how many times this module is called in one |
1435 |
++ * second (should be about every 100ms) |
1436 |
++ */ |
1437 |
++ ad_ticks_per_sec = tick_resolution; |
1438 |
+ |
1439 |
+- bond_3ad_initiate_agg_selection(bond, |
1440 |
+- AD_AGGREGATOR_SELECTION_TIMER * |
1441 |
+- ad_ticks_per_sec); |
1442 |
+- } |
1443 |
++ bond_3ad_initiate_agg_selection(bond, |
1444 |
++ AD_AGGREGATOR_SELECTION_TIMER * |
1445 |
++ ad_ticks_per_sec); |
1446 |
+ } |
1447 |
+ |
1448 |
+ /** |
1449 |
+diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c |
1450 |
+index 12a599d5e61a4..c771797fd902f 100644 |
1451 |
+--- a/drivers/net/dsa/microchip/ksz8795.c |
1452 |
++++ b/drivers/net/dsa/microchip/ksz8795.c |
1453 |
+@@ -898,17 +898,6 @@ static void ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) |
1454 |
+ } |
1455 |
+ } |
1456 |
+ |
1457 |
+-static enum dsa_tag_protocol ksz8_get_tag_protocol(struct dsa_switch *ds, |
1458 |
+- int port, |
1459 |
+- enum dsa_tag_protocol mp) |
1460 |
+-{ |
1461 |
+- struct ksz_device *dev = ds->priv; |
1462 |
+- |
1463 |
+- /* ksz88x3 uses the same tag schema as KSZ9893 */ |
1464 |
+- return ksz_is_ksz88x3(dev) ? |
1465 |
+- DSA_TAG_PROTO_KSZ9893 : DSA_TAG_PROTO_KSZ8795; |
1466 |
+-} |
1467 |
+- |
1468 |
+ static u32 ksz8_sw_get_phy_flags(struct dsa_switch *ds, int port) |
1469 |
+ { |
1470 |
+ /* Silicon Errata Sheet (DS80000830A): |
1471 |
+@@ -969,11 +958,9 @@ static void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port) |
1472 |
+ } |
1473 |
+ } |
1474 |
+ |
1475 |
+-static int ksz8_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag, |
1476 |
++static int ksz8_port_vlan_filtering(struct ksz_device *dev, int port, bool flag, |
1477 |
+ struct netlink_ext_ack *extack) |
1478 |
+ { |
1479 |
+- struct ksz_device *dev = ds->priv; |
1480 |
+- |
1481 |
+ if (ksz_is_ksz88x3(dev)) |
1482 |
+ return -ENOTSUPP; |
1483 |
+ |
1484 |
+@@ -998,12 +985,11 @@ static void ksz8_port_enable_pvid(struct ksz_device *dev, int port, bool state) |
1485 |
+ } |
1486 |
+ } |
1487 |
+ |
1488 |
+-static int ksz8_port_vlan_add(struct dsa_switch *ds, int port, |
1489 |
++static int ksz8_port_vlan_add(struct ksz_device *dev, int port, |
1490 |
+ const struct switchdev_obj_port_vlan *vlan, |
1491 |
+ struct netlink_ext_ack *extack) |
1492 |
+ { |
1493 |
+ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; |
1494 |
+- struct ksz_device *dev = ds->priv; |
1495 |
+ struct ksz_port *p = &dev->ports[port]; |
1496 |
+ u16 data, new_pvid = 0; |
1497 |
+ u8 fid, member, valid; |
1498 |
+@@ -1071,10 +1057,9 @@ static int ksz8_port_vlan_add(struct dsa_switch *ds, int port, |
1499 |
+ return 0; |
1500 |
+ } |
1501 |
+ |
1502 |
+-static int ksz8_port_vlan_del(struct dsa_switch *ds, int port, |
1503 |
++static int ksz8_port_vlan_del(struct ksz_device *dev, int port, |
1504 |
+ const struct switchdev_obj_port_vlan *vlan) |
1505 |
+ { |
1506 |
+- struct ksz_device *dev = ds->priv; |
1507 |
+ u16 data, pvid; |
1508 |
+ u8 fid, member, valid; |
1509 |
+ |
1510 |
+@@ -1104,12 +1089,10 @@ static int ksz8_port_vlan_del(struct dsa_switch *ds, int port, |
1511 |
+ return 0; |
1512 |
+ } |
1513 |
+ |
1514 |
+-static int ksz8_port_mirror_add(struct dsa_switch *ds, int port, |
1515 |
++static int ksz8_port_mirror_add(struct ksz_device *dev, int port, |
1516 |
+ struct dsa_mall_mirror_tc_entry *mirror, |
1517 |
+ bool ingress, struct netlink_ext_ack *extack) |
1518 |
+ { |
1519 |
+- struct ksz_device *dev = ds->priv; |
1520 |
+- |
1521 |
+ if (ingress) { |
1522 |
+ ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, true); |
1523 |
+ dev->mirror_rx |= BIT(port); |
1524 |
+@@ -1128,10 +1111,9 @@ static int ksz8_port_mirror_add(struct dsa_switch *ds, int port, |
1525 |
+ return 0; |
1526 |
+ } |
1527 |
+ |
1528 |
+-static void ksz8_port_mirror_del(struct dsa_switch *ds, int port, |
1529 |
++static void ksz8_port_mirror_del(struct ksz_device *dev, int port, |
1530 |
+ struct dsa_mall_mirror_tc_entry *mirror) |
1531 |
+ { |
1532 |
+- struct ksz_device *dev = ds->priv; |
1533 |
+ u8 data; |
1534 |
+ |
1535 |
+ if (mirror->ingress) { |
1536 |
+@@ -1272,7 +1254,7 @@ static void ksz8_config_cpu_port(struct dsa_switch *ds) |
1537 |
+ continue; |
1538 |
+ if (!ksz_is_ksz88x3(dev)) { |
1539 |
+ ksz_pread8(dev, i, regs[P_REMOTE_STATUS], &remote); |
1540 |
+- if (remote & PORT_FIBER_MODE) |
1541 |
++ if (remote & KSZ8_PORT_FIBER_MODE) |
1542 |
+ p->fiber = 1; |
1543 |
+ } |
1544 |
+ if (p->fiber) |
1545 |
+@@ -1371,13 +1353,9 @@ static int ksz8_setup(struct dsa_switch *ds) |
1546 |
+ return ksz8_handle_global_errata(ds); |
1547 |
+ } |
1548 |
+ |
1549 |
+-static void ksz8_get_caps(struct dsa_switch *ds, int port, |
1550 |
++static void ksz8_get_caps(struct ksz_device *dev, int port, |
1551 |
+ struct phylink_config *config) |
1552 |
+ { |
1553 |
+- struct ksz_device *dev = ds->priv; |
1554 |
+- |
1555 |
+- ksz_phylink_get_caps(ds, port, config); |
1556 |
+- |
1557 |
+ config->mac_capabilities = MAC_10 | MAC_100; |
1558 |
+ |
1559 |
+ /* Silicon Errata Sheet (DS80000830A): |
1560 |
+@@ -1394,12 +1372,12 @@ static void ksz8_get_caps(struct dsa_switch *ds, int port, |
1561 |
+ } |
1562 |
+ |
1563 |
+ static const struct dsa_switch_ops ksz8_switch_ops = { |
1564 |
+- .get_tag_protocol = ksz8_get_tag_protocol, |
1565 |
++ .get_tag_protocol = ksz_get_tag_protocol, |
1566 |
+ .get_phy_flags = ksz8_sw_get_phy_flags, |
1567 |
+ .setup = ksz8_setup, |
1568 |
+ .phy_read = ksz_phy_read16, |
1569 |
+ .phy_write = ksz_phy_write16, |
1570 |
+- .phylink_get_caps = ksz8_get_caps, |
1571 |
++ .phylink_get_caps = ksz_phylink_get_caps, |
1572 |
+ .phylink_mac_link_down = ksz_mac_link_down, |
1573 |
+ .port_enable = ksz_enable_port, |
1574 |
+ .get_strings = ksz_get_strings, |
1575 |
+@@ -1409,14 +1387,14 @@ static const struct dsa_switch_ops ksz8_switch_ops = { |
1576 |
+ .port_bridge_leave = ksz_port_bridge_leave, |
1577 |
+ .port_stp_state_set = ksz8_port_stp_state_set, |
1578 |
+ .port_fast_age = ksz_port_fast_age, |
1579 |
+- .port_vlan_filtering = ksz8_port_vlan_filtering, |
1580 |
+- .port_vlan_add = ksz8_port_vlan_add, |
1581 |
+- .port_vlan_del = ksz8_port_vlan_del, |
1582 |
++ .port_vlan_filtering = ksz_port_vlan_filtering, |
1583 |
++ .port_vlan_add = ksz_port_vlan_add, |
1584 |
++ .port_vlan_del = ksz_port_vlan_del, |
1585 |
+ .port_fdb_dump = ksz_port_fdb_dump, |
1586 |
+ .port_mdb_add = ksz_port_mdb_add, |
1587 |
+ .port_mdb_del = ksz_port_mdb_del, |
1588 |
+- .port_mirror_add = ksz8_port_mirror_add, |
1589 |
+- .port_mirror_del = ksz8_port_mirror_del, |
1590 |
++ .port_mirror_add = ksz_port_mirror_add, |
1591 |
++ .port_mirror_del = ksz_port_mirror_del, |
1592 |
+ }; |
1593 |
+ |
1594 |
+ static u32 ksz8_get_port_addr(int port, int offset) |
1595 |
+@@ -1424,51 +1402,6 @@ static u32 ksz8_get_port_addr(int port, int offset) |
1596 |
+ return PORT_CTRL_ADDR(port, offset); |
1597 |
+ } |
1598 |
+ |
1599 |
+-static int ksz8_switch_detect(struct ksz_device *dev) |
1600 |
+-{ |
1601 |
+- u8 id1, id2; |
1602 |
+- u16 id16; |
1603 |
+- int ret; |
1604 |
+- |
1605 |
+- /* read chip id */ |
1606 |
+- ret = ksz_read16(dev, REG_CHIP_ID0, &id16); |
1607 |
+- if (ret) |
1608 |
+- return ret; |
1609 |
+- |
1610 |
+- id1 = id16 >> 8; |
1611 |
+- id2 = id16 & SW_CHIP_ID_M; |
1612 |
+- |
1613 |
+- switch (id1) { |
1614 |
+- case KSZ87_FAMILY_ID: |
1615 |
+- if ((id2 != CHIP_ID_94 && id2 != CHIP_ID_95)) |
1616 |
+- return -ENODEV; |
1617 |
+- |
1618 |
+- if (id2 == CHIP_ID_95) { |
1619 |
+- u8 val; |
1620 |
+- |
1621 |
+- id2 = 0x95; |
1622 |
+- ksz_read8(dev, REG_PORT_STATUS_0, &val); |
1623 |
+- if (val & PORT_FIBER_MODE) |
1624 |
+- id2 = 0x65; |
1625 |
+- } else if (id2 == CHIP_ID_94) { |
1626 |
+- id2 = 0x94; |
1627 |
+- } |
1628 |
+- break; |
1629 |
+- case KSZ88_FAMILY_ID: |
1630 |
+- if (id2 != CHIP_ID_63) |
1631 |
+- return -ENODEV; |
1632 |
+- break; |
1633 |
+- default: |
1634 |
+- dev_err(dev->dev, "invalid family id: %d\n", id1); |
1635 |
+- return -ENODEV; |
1636 |
+- } |
1637 |
+- id16 &= ~0xff; |
1638 |
+- id16 |= id2; |
1639 |
+- dev->chip_id = id16; |
1640 |
+- |
1641 |
+- return 0; |
1642 |
+-} |
1643 |
+- |
1644 |
+ static int ksz8_switch_init(struct ksz_device *dev) |
1645 |
+ { |
1646 |
+ struct ksz8 *ksz8 = dev->priv; |
1647 |
+@@ -1521,8 +1454,13 @@ static const struct ksz_dev_ops ksz8_dev_ops = { |
1648 |
+ .r_mib_pkt = ksz8_r_mib_pkt, |
1649 |
+ .freeze_mib = ksz8_freeze_mib, |
1650 |
+ .port_init_cnt = ksz8_port_init_cnt, |
1651 |
++ .vlan_filtering = ksz8_port_vlan_filtering, |
1652 |
++ .vlan_add = ksz8_port_vlan_add, |
1653 |
++ .vlan_del = ksz8_port_vlan_del, |
1654 |
++ .mirror_add = ksz8_port_mirror_add, |
1655 |
++ .mirror_del = ksz8_port_mirror_del, |
1656 |
++ .get_caps = ksz8_get_caps, |
1657 |
+ .shutdown = ksz8_reset_switch, |
1658 |
+- .detect = ksz8_switch_detect, |
1659 |
+ .init = ksz8_switch_init, |
1660 |
+ .exit = ksz8_switch_exit, |
1661 |
+ }; |
1662 |
+diff --git a/drivers/net/dsa/microchip/ksz8795_reg.h b/drivers/net/dsa/microchip/ksz8795_reg.h |
1663 |
+index 4109433b6b6c2..b8f6ad7581bcd 100644 |
1664 |
+--- a/drivers/net/dsa/microchip/ksz8795_reg.h |
1665 |
++++ b/drivers/net/dsa/microchip/ksz8795_reg.h |
1666 |
+@@ -14,23 +14,10 @@ |
1667 |
+ #define KS_PRIO_M 0x3 |
1668 |
+ #define KS_PRIO_S 2 |
1669 |
+ |
1670 |
+-#define REG_CHIP_ID0 0x00 |
1671 |
+- |
1672 |
+-#define KSZ87_FAMILY_ID 0x87 |
1673 |
+-#define KSZ88_FAMILY_ID 0x88 |
1674 |
+- |
1675 |
+-#define REG_CHIP_ID1 0x01 |
1676 |
+- |
1677 |
+-#define SW_CHIP_ID_M 0xF0 |
1678 |
+-#define SW_CHIP_ID_S 4 |
1679 |
+ #define SW_REVISION_M 0x0E |
1680 |
+ #define SW_REVISION_S 1 |
1681 |
+ #define SW_START 0x01 |
1682 |
+ |
1683 |
+-#define CHIP_ID_94 0x60 |
1684 |
+-#define CHIP_ID_95 0x90 |
1685 |
+-#define CHIP_ID_63 0x30 |
1686 |
+- |
1687 |
+ #define KSZ8863_REG_SW_RESET 0x43 |
1688 |
+ |
1689 |
+ #define KSZ8863_GLOBAL_SOFTWARE_RESET BIT(4) |
1690 |
+@@ -217,8 +204,6 @@ |
1691 |
+ #define REG_PORT_4_STATUS_0 0x48 |
1692 |
+ |
1693 |
+ /* For KSZ8765. */ |
1694 |
+-#define PORT_FIBER_MODE BIT(7) |
1695 |
+- |
1696 |
+ #define PORT_REMOTE_ASYM_PAUSE BIT(5) |
1697 |
+ #define PORT_REMOTE_SYM_PAUSE BIT(4) |
1698 |
+ #define PORT_REMOTE_100BTX_FD BIT(3) |
1699 |
+@@ -322,7 +307,6 @@ |
1700 |
+ |
1701 |
+ #define REG_PORT_CTRL_5 0x05 |
1702 |
+ |
1703 |
+-#define REG_PORT_STATUS_0 0x08 |
1704 |
+ #define REG_PORT_STATUS_1 0x09 |
1705 |
+ #define REG_PORT_LINK_MD_CTRL 0x0A |
1706 |
+ #define REG_PORT_LINK_MD_RESULT 0x0B |
1707 |
+diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c |
1708 |
+index ebad795e4e95f..125124fdefbf4 100644 |
1709 |
+--- a/drivers/net/dsa/microchip/ksz9477.c |
1710 |
++++ b/drivers/net/dsa/microchip/ksz9477.c |
1711 |
+@@ -276,18 +276,6 @@ static void ksz9477_port_init_cnt(struct ksz_device *dev, int port) |
1712 |
+ mutex_unlock(&mib->cnt_mutex); |
1713 |
+ } |
1714 |
+ |
1715 |
+-static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds, |
1716 |
+- int port, |
1717 |
+- enum dsa_tag_protocol mp) |
1718 |
+-{ |
1719 |
+- enum dsa_tag_protocol proto = DSA_TAG_PROTO_KSZ9477; |
1720 |
+- struct ksz_device *dev = ds->priv; |
1721 |
+- |
1722 |
+- if (dev->features & IS_9893) |
1723 |
+- proto = DSA_TAG_PROTO_KSZ9893; |
1724 |
+- return proto; |
1725 |
+-} |
1726 |
+- |
1727 |
+ static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg) |
1728 |
+ { |
1729 |
+ struct ksz_device *dev = ds->priv; |
1730 |
+@@ -389,12 +377,10 @@ static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port) |
1731 |
+ } |
1732 |
+ } |
1733 |
+ |
1734 |
+-static int ksz9477_port_vlan_filtering(struct dsa_switch *ds, int port, |
1735 |
++static int ksz9477_port_vlan_filtering(struct ksz_device *dev, int port, |
1736 |
+ bool flag, |
1737 |
+ struct netlink_ext_ack *extack) |
1738 |
+ { |
1739 |
+- struct ksz_device *dev = ds->priv; |
1740 |
+- |
1741 |
+ if (flag) { |
1742 |
+ ksz_port_cfg(dev, port, REG_PORT_LUE_CTRL, |
1743 |
+ PORT_VLAN_LOOKUP_VID_0, true); |
1744 |
+@@ -408,11 +394,10 @@ static int ksz9477_port_vlan_filtering(struct dsa_switch *ds, int port, |
1745 |
+ return 0; |
1746 |
+ } |
1747 |
+ |
1748 |
+-static int ksz9477_port_vlan_add(struct dsa_switch *ds, int port, |
1749 |
++static int ksz9477_port_vlan_add(struct ksz_device *dev, int port, |
1750 |
+ const struct switchdev_obj_port_vlan *vlan, |
1751 |
+ struct netlink_ext_ack *extack) |
1752 |
+ { |
1753 |
+- struct ksz_device *dev = ds->priv; |
1754 |
+ u32 vlan_table[3]; |
1755 |
+ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; |
1756 |
+ int err; |
1757 |
+@@ -445,10 +430,9 @@ static int ksz9477_port_vlan_add(struct dsa_switch *ds, int port, |
1758 |
+ return 0; |
1759 |
+ } |
1760 |
+ |
1761 |
+-static int ksz9477_port_vlan_del(struct dsa_switch *ds, int port, |
1762 |
++static int ksz9477_port_vlan_del(struct ksz_device *dev, int port, |
1763 |
+ const struct switchdev_obj_port_vlan *vlan) |
1764 |
+ { |
1765 |
+- struct ksz_device *dev = ds->priv; |
1766 |
+ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; |
1767 |
+ u32 vlan_table[3]; |
1768 |
+ u16 pvid; |
1769 |
+@@ -835,11 +819,10 @@ exit: |
1770 |
+ return ret; |
1771 |
+ } |
1772 |
+ |
1773 |
+-static int ksz9477_port_mirror_add(struct dsa_switch *ds, int port, |
1774 |
++static int ksz9477_port_mirror_add(struct ksz_device *dev, int port, |
1775 |
+ struct dsa_mall_mirror_tc_entry *mirror, |
1776 |
+ bool ingress, struct netlink_ext_ack *extack) |
1777 |
+ { |
1778 |
+- struct ksz_device *dev = ds->priv; |
1779 |
+ u8 data; |
1780 |
+ int p; |
1781 |
+ |
1782 |
+@@ -875,10 +858,9 @@ static int ksz9477_port_mirror_add(struct dsa_switch *ds, int port, |
1783 |
+ return 0; |
1784 |
+ } |
1785 |
+ |
1786 |
+-static void ksz9477_port_mirror_del(struct dsa_switch *ds, int port, |
1787 |
++static void ksz9477_port_mirror_del(struct ksz_device *dev, int port, |
1788 |
+ struct dsa_mall_mirror_tc_entry *mirror) |
1789 |
+ { |
1790 |
+- struct ksz_device *dev = ds->priv; |
1791 |
+ bool in_use = false; |
1792 |
+ u8 data; |
1793 |
+ int p; |
1794 |
+@@ -1100,11 +1082,9 @@ static void ksz9477_phy_errata_setup(struct ksz_device *dev, int port) |
1795 |
+ ksz9477_port_mmd_write(dev, port, 0x1c, 0x20, 0xeeee); |
1796 |
+ } |
1797 |
+ |
1798 |
+-static void ksz9477_get_caps(struct dsa_switch *ds, int port, |
1799 |
++static void ksz9477_get_caps(struct ksz_device *dev, int port, |
1800 |
+ struct phylink_config *config) |
1801 |
+ { |
1802 |
+- ksz_phylink_get_caps(ds, port, config); |
1803 |
+- |
1804 |
+ config->mac_capabilities = MAC_10 | MAC_100 | MAC_1000FD | |
1805 |
+ MAC_ASYM_PAUSE | MAC_SYM_PAUSE; |
1806 |
+ } |
1807 |
+@@ -1329,12 +1309,12 @@ static int ksz9477_setup(struct dsa_switch *ds) |
1808 |
+ } |
1809 |
+ |
1810 |
+ static const struct dsa_switch_ops ksz9477_switch_ops = { |
1811 |
+- .get_tag_protocol = ksz9477_get_tag_protocol, |
1812 |
++ .get_tag_protocol = ksz_get_tag_protocol, |
1813 |
+ .setup = ksz9477_setup, |
1814 |
+ .phy_read = ksz9477_phy_read16, |
1815 |
+ .phy_write = ksz9477_phy_write16, |
1816 |
+ .phylink_mac_link_down = ksz_mac_link_down, |
1817 |
+- .phylink_get_caps = ksz9477_get_caps, |
1818 |
++ .phylink_get_caps = ksz_phylink_get_caps, |
1819 |
+ .port_enable = ksz_enable_port, |
1820 |
+ .get_strings = ksz_get_strings, |
1821 |
+ .get_ethtool_stats = ksz_get_ethtool_stats, |
1822 |
+@@ -1343,16 +1323,16 @@ static const struct dsa_switch_ops ksz9477_switch_ops = { |
1823 |
+ .port_bridge_leave = ksz_port_bridge_leave, |
1824 |
+ .port_stp_state_set = ksz9477_port_stp_state_set, |
1825 |
+ .port_fast_age = ksz_port_fast_age, |
1826 |
+- .port_vlan_filtering = ksz9477_port_vlan_filtering, |
1827 |
+- .port_vlan_add = ksz9477_port_vlan_add, |
1828 |
+- .port_vlan_del = ksz9477_port_vlan_del, |
1829 |
++ .port_vlan_filtering = ksz_port_vlan_filtering, |
1830 |
++ .port_vlan_add = ksz_port_vlan_add, |
1831 |
++ .port_vlan_del = ksz_port_vlan_del, |
1832 |
+ .port_fdb_dump = ksz9477_port_fdb_dump, |
1833 |
+ .port_fdb_add = ksz9477_port_fdb_add, |
1834 |
+ .port_fdb_del = ksz9477_port_fdb_del, |
1835 |
+ .port_mdb_add = ksz9477_port_mdb_add, |
1836 |
+ .port_mdb_del = ksz9477_port_mdb_del, |
1837 |
+- .port_mirror_add = ksz9477_port_mirror_add, |
1838 |
+- .port_mirror_del = ksz9477_port_mirror_del, |
1839 |
++ .port_mirror_add = ksz_port_mirror_add, |
1840 |
++ .port_mirror_del = ksz_port_mirror_del, |
1841 |
+ .get_stats64 = ksz_get_stats64, |
1842 |
+ .port_change_mtu = ksz9477_change_mtu, |
1843 |
+ .port_max_mtu = ksz9477_max_mtu, |
1844 |
+@@ -1363,14 +1343,15 @@ static u32 ksz9477_get_port_addr(int port, int offset) |
1845 |
+ return PORT_CTRL_ADDR(port, offset); |
1846 |
+ } |
1847 |
+ |
1848 |
+-static int ksz9477_switch_detect(struct ksz_device *dev) |
1849 |
++static int ksz9477_switch_init(struct ksz_device *dev) |
1850 |
+ { |
1851 |
+ u8 data8; |
1852 |
+- u8 id_hi; |
1853 |
+- u8 id_lo; |
1854 |
+- u32 id32; |
1855 |
+ int ret; |
1856 |
+ |
1857 |
++ dev->ds->ops = &ksz9477_switch_ops; |
1858 |
++ |
1859 |
++ dev->port_mask = (1 << dev->info->port_cnt) - 1; |
1860 |
++ |
1861 |
+ /* turn off SPI DO Edge select */ |
1862 |
+ ret = ksz_read8(dev, REG_SW_GLOBAL_SERIAL_CTRL_0, &data8); |
1863 |
+ if (ret) |
1864 |
+@@ -1381,10 +1362,6 @@ static int ksz9477_switch_detect(struct ksz_device *dev) |
1865 |
+ if (ret) |
1866 |
+ return ret; |
1867 |
+ |
1868 |
+- /* read chip id */ |
1869 |
+- ret = ksz_read32(dev, REG_CHIP_ID0__1, &id32); |
1870 |
+- if (ret) |
1871 |
+- return ret; |
1872 |
+ ret = ksz_read8(dev, REG_GLOBAL_OPTIONS, &data8); |
1873 |
+ if (ret) |
1874 |
+ return ret; |
1875 |
+@@ -1395,12 +1372,7 @@ static int ksz9477_switch_detect(struct ksz_device *dev) |
1876 |
+ /* Default capability is gigabit capable. */ |
1877 |
+ dev->features = GBIT_SUPPORT; |
1878 |
+ |
1879 |
+- dev_dbg(dev->dev, "Switch detect: ID=%08x%02x\n", id32, data8); |
1880 |
+- id_hi = (u8)(id32 >> 16); |
1881 |
+- id_lo = (u8)(id32 >> 8); |
1882 |
+- if ((id_lo & 0xf) == 3) { |
1883 |
+- /* Chip is from KSZ9893 design. */ |
1884 |
+- dev_info(dev->dev, "Found KSZ9893\n"); |
1885 |
++ if (dev->chip_id == KSZ9893_CHIP_ID) { |
1886 |
+ dev->features |= IS_9893; |
1887 |
+ |
1888 |
+ /* Chip does not support gigabit. */ |
1889 |
+@@ -1408,7 +1380,6 @@ static int ksz9477_switch_detect(struct ksz_device *dev) |
1890 |
+ dev->features &= ~GBIT_SUPPORT; |
1891 |
+ dev->phy_port_cnt = 2; |
1892 |
+ } else { |
1893 |
+- dev_info(dev->dev, "Found KSZ9477 or compatible\n"); |
1894 |
+ /* Chip uses new XMII register definitions. */ |
1895 |
+ dev->features |= NEW_XMII; |
1896 |
+ |
1897 |
+@@ -1416,21 +1387,6 @@ static int ksz9477_switch_detect(struct ksz_device *dev) |
1898 |
+ if (!(data8 & SW_GIGABIT_ABLE)) |
1899 |
+ dev->features &= ~GBIT_SUPPORT; |
1900 |
+ } |
1901 |
+- |
1902 |
+- /* Change chip id to known ones so it can be matched against them. */ |
1903 |
+- id32 = (id_hi << 16) | (id_lo << 8); |
1904 |
+- |
1905 |
+- dev->chip_id = id32; |
1906 |
+- |
1907 |
+- return 0; |
1908 |
+-} |
1909 |
+- |
1910 |
+-static int ksz9477_switch_init(struct ksz_device *dev) |
1911 |
+-{ |
1912 |
+- dev->ds->ops = &ksz9477_switch_ops; |
1913 |
+- |
1914 |
+- dev->port_mask = (1 << dev->info->port_cnt) - 1; |
1915 |
+- |
1916 |
+ return 0; |
1917 |
+ } |
1918 |
+ |
1919 |
+@@ -1449,8 +1405,13 @@ static const struct ksz_dev_ops ksz9477_dev_ops = { |
1920 |
+ .r_mib_stat64 = ksz_r_mib_stats64, |
1921 |
+ .freeze_mib = ksz9477_freeze_mib, |
1922 |
+ .port_init_cnt = ksz9477_port_init_cnt, |
1923 |
++ .vlan_filtering = ksz9477_port_vlan_filtering, |
1924 |
++ .vlan_add = ksz9477_port_vlan_add, |
1925 |
++ .vlan_del = ksz9477_port_vlan_del, |
1926 |
++ .mirror_add = ksz9477_port_mirror_add, |
1927 |
++ .mirror_del = ksz9477_port_mirror_del, |
1928 |
++ .get_caps = ksz9477_get_caps, |
1929 |
+ .shutdown = ksz9477_reset_switch, |
1930 |
+- .detect = ksz9477_switch_detect, |
1931 |
+ .init = ksz9477_switch_init, |
1932 |
+ .exit = ksz9477_switch_exit, |
1933 |
+ }; |
1934 |
+diff --git a/drivers/net/dsa/microchip/ksz9477_reg.h b/drivers/net/dsa/microchip/ksz9477_reg.h |
1935 |
+index 7a2c8d4767aff..077e35ab11b54 100644 |
1936 |
+--- a/drivers/net/dsa/microchip/ksz9477_reg.h |
1937 |
++++ b/drivers/net/dsa/microchip/ksz9477_reg.h |
1938 |
+@@ -25,7 +25,6 @@ |
1939 |
+ |
1940 |
+ #define REG_CHIP_ID2__1 0x0002 |
1941 |
+ |
1942 |
+-#define CHIP_ID_63 0x63 |
1943 |
+ #define CHIP_ID_66 0x66 |
1944 |
+ #define CHIP_ID_67 0x67 |
1945 |
+ #define CHIP_ID_77 0x77 |
1946 |
+diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c |
1947 |
+index 92a500e1ccd21..c9389880ad1fa 100644 |
1948 |
+--- a/drivers/net/dsa/microchip/ksz_common.c |
1949 |
++++ b/drivers/net/dsa/microchip/ksz_common.c |
1950 |
+@@ -453,9 +453,18 @@ void ksz_phylink_get_caps(struct dsa_switch *ds, int port, |
1951 |
+ if (dev->info->supports_rgmii[port]) |
1952 |
+ phy_interface_set_rgmii(config->supported_interfaces); |
1953 |
+ |
1954 |
+- if (dev->info->internal_phy[port]) |
1955 |
++ if (dev->info->internal_phy[port]) { |
1956 |
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, |
1957 |
+ config->supported_interfaces); |
1958 |
++ /* Compatibility for phylib's default interface type when the |
1959 |
++ * phy-mode property is absent |
1960 |
++ */ |
1961 |
++ __set_bit(PHY_INTERFACE_MODE_GMII, |
1962 |
++ config->supported_interfaces); |
1963 |
++ } |
1964 |
++ |
1965 |
++ if (dev->dev_ops->get_caps) |
1966 |
++ dev->dev_ops->get_caps(dev, port, config); |
1967 |
+ } |
1968 |
+ EXPORT_SYMBOL_GPL(ksz_phylink_get_caps); |
1969 |
+ |
1970 |
+@@ -930,6 +939,156 @@ void ksz_port_stp_state_set(struct dsa_switch *ds, int port, |
1971 |
+ } |
1972 |
+ EXPORT_SYMBOL_GPL(ksz_port_stp_state_set); |
1973 |
+ |
1974 |
++enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, |
1975 |
++ int port, enum dsa_tag_protocol mp) |
1976 |
++{ |
1977 |
++ struct ksz_device *dev = ds->priv; |
1978 |
++ enum dsa_tag_protocol proto = DSA_TAG_PROTO_NONE; |
1979 |
++ |
1980 |
++ if (dev->chip_id == KSZ8795_CHIP_ID || |
1981 |
++ dev->chip_id == KSZ8794_CHIP_ID || |
1982 |
++ dev->chip_id == KSZ8765_CHIP_ID) |
1983 |
++ proto = DSA_TAG_PROTO_KSZ8795; |
1984 |
++ |
1985 |
++ if (dev->chip_id == KSZ8830_CHIP_ID || |
1986 |
++ dev->chip_id == KSZ9893_CHIP_ID) |
1987 |
++ proto = DSA_TAG_PROTO_KSZ9893; |
1988 |
++ |
1989 |
++ if (dev->chip_id == KSZ9477_CHIP_ID || |
1990 |
++ dev->chip_id == KSZ9897_CHIP_ID || |
1991 |
++ dev->chip_id == KSZ9567_CHIP_ID) |
1992 |
++ proto = DSA_TAG_PROTO_KSZ9477; |
1993 |
++ |
1994 |
++ return proto; |
1995 |
++} |
1996 |
++EXPORT_SYMBOL_GPL(ksz_get_tag_protocol); |
1997 |
++ |
1998 |
++int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, |
1999 |
++ bool flag, struct netlink_ext_ack *extack) |
2000 |
++{ |
2001 |
++ struct ksz_device *dev = ds->priv; |
2002 |
++ |
2003 |
++ if (!dev->dev_ops->vlan_filtering) |
2004 |
++ return -EOPNOTSUPP; |
2005 |
++ |
2006 |
++ return dev->dev_ops->vlan_filtering(dev, port, flag, extack); |
2007 |
++} |
2008 |
++EXPORT_SYMBOL_GPL(ksz_port_vlan_filtering); |
2009 |
++ |
2010 |
++int ksz_port_vlan_add(struct dsa_switch *ds, int port, |
2011 |
++ const struct switchdev_obj_port_vlan *vlan, |
2012 |
++ struct netlink_ext_ack *extack) |
2013 |
++{ |
2014 |
++ struct ksz_device *dev = ds->priv; |
2015 |
++ |
2016 |
++ if (!dev->dev_ops->vlan_add) |
2017 |
++ return -EOPNOTSUPP; |
2018 |
++ |
2019 |
++ return dev->dev_ops->vlan_add(dev, port, vlan, extack); |
2020 |
++} |
2021 |
++EXPORT_SYMBOL_GPL(ksz_port_vlan_add); |
2022 |
++ |
2023 |
++int ksz_port_vlan_del(struct dsa_switch *ds, int port, |
2024 |
++ const struct switchdev_obj_port_vlan *vlan) |
2025 |
++{ |
2026 |
++ struct ksz_device *dev = ds->priv; |
2027 |
++ |
2028 |
++ if (!dev->dev_ops->vlan_del) |
2029 |
++ return -EOPNOTSUPP; |
2030 |
++ |
2031 |
++ return dev->dev_ops->vlan_del(dev, port, vlan); |
2032 |
++} |
2033 |
++EXPORT_SYMBOL_GPL(ksz_port_vlan_del); |
2034 |
++ |
2035 |
++int ksz_port_mirror_add(struct dsa_switch *ds, int port, |
2036 |
++ struct dsa_mall_mirror_tc_entry *mirror, |
2037 |
++ bool ingress, struct netlink_ext_ack *extack) |
2038 |
++{ |
2039 |
++ struct ksz_device *dev = ds->priv; |
2040 |
++ |
2041 |
++ if (!dev->dev_ops->mirror_add) |
2042 |
++ return -EOPNOTSUPP; |
2043 |
++ |
2044 |
++ return dev->dev_ops->mirror_add(dev, port, mirror, ingress, extack); |
2045 |
++} |
2046 |
++EXPORT_SYMBOL_GPL(ksz_port_mirror_add); |
2047 |
++ |
2048 |
++void ksz_port_mirror_del(struct dsa_switch *ds, int port, |
2049 |
++ struct dsa_mall_mirror_tc_entry *mirror) |
2050 |
++{ |
2051 |
++ struct ksz_device *dev = ds->priv; |
2052 |
++ |
2053 |
++ if (dev->dev_ops->mirror_del) |
2054 |
++ dev->dev_ops->mirror_del(dev, port, mirror); |
2055 |
++} |
2056 |
++EXPORT_SYMBOL_GPL(ksz_port_mirror_del); |
2057 |
++ |
2058 |
++static int ksz_switch_detect(struct ksz_device *dev) |
2059 |
++{ |
2060 |
++ u8 id1, id2; |
2061 |
++ u16 id16; |
2062 |
++ u32 id32; |
2063 |
++ int ret; |
2064 |
++ |
2065 |
++ /* read chip id */ |
2066 |
++ ret = ksz_read16(dev, REG_CHIP_ID0, &id16); |
2067 |
++ if (ret) |
2068 |
++ return ret; |
2069 |
++ |
2070 |
++ id1 = FIELD_GET(SW_FAMILY_ID_M, id16); |
2071 |
++ id2 = FIELD_GET(SW_CHIP_ID_M, id16); |
2072 |
++ |
2073 |
++ switch (id1) { |
2074 |
++ case KSZ87_FAMILY_ID: |
2075 |
++ if (id2 == KSZ87_CHIP_ID_95) { |
2076 |
++ u8 val; |
2077 |
++ |
2078 |
++ dev->chip_id = KSZ8795_CHIP_ID; |
2079 |
++ |
2080 |
++ ksz_read8(dev, KSZ8_PORT_STATUS_0, &val); |
2081 |
++ if (val & KSZ8_PORT_FIBER_MODE) |
2082 |
++ dev->chip_id = KSZ8765_CHIP_ID; |
2083 |
++ } else if (id2 == KSZ87_CHIP_ID_94) { |
2084 |
++ dev->chip_id = KSZ8794_CHIP_ID; |
2085 |
++ } else { |
2086 |
++ return -ENODEV; |
2087 |
++ } |
2088 |
++ break; |
2089 |
++ case KSZ88_FAMILY_ID: |
2090 |
++ if (id2 == KSZ88_CHIP_ID_63) |
2091 |
++ dev->chip_id = KSZ8830_CHIP_ID; |
2092 |
++ else |
2093 |
++ return -ENODEV; |
2094 |
++ break; |
2095 |
++ default: |
2096 |
++ ret = ksz_read32(dev, REG_CHIP_ID0, &id32); |
2097 |
++ if (ret) |
2098 |
++ return ret; |
2099 |
++ |
2100 |
++ dev->chip_rev = FIELD_GET(SW_REV_ID_M, id32); |
2101 |
++ id32 &= ~0xFF; |
2102 |
++ |
2103 |
++ switch (id32) { |
2104 |
++ case KSZ9477_CHIP_ID: |
2105 |
++ case KSZ9897_CHIP_ID: |
2106 |
++ case KSZ9893_CHIP_ID: |
2107 |
++ case KSZ9567_CHIP_ID: |
2108 |
++ case LAN9370_CHIP_ID: |
2109 |
++ case LAN9371_CHIP_ID: |
2110 |
++ case LAN9372_CHIP_ID: |
2111 |
++ case LAN9373_CHIP_ID: |
2112 |
++ case LAN9374_CHIP_ID: |
2113 |
++ dev->chip_id = id32; |
2114 |
++ break; |
2115 |
++ default: |
2116 |
++ dev_err(dev->dev, |
2117 |
++ "unsupported switch detected %x)\n", id32); |
2118 |
++ return -ENODEV; |
2119 |
++ } |
2120 |
++ } |
2121 |
++ return 0; |
2122 |
++} |
2123 |
++ |
2124 |
+ struct ksz_device *ksz_switch_alloc(struct device *base, void *priv) |
2125 |
+ { |
2126 |
+ struct dsa_switch *ds; |
2127 |
+@@ -986,10 +1145,9 @@ int ksz_switch_register(struct ksz_device *dev, |
2128 |
+ mutex_init(&dev->alu_mutex); |
2129 |
+ mutex_init(&dev->vlan_mutex); |
2130 |
+ |
2131 |
+- dev->dev_ops = ops; |
2132 |
+- |
2133 |
+- if (dev->dev_ops->detect(dev)) |
2134 |
+- return -EINVAL; |
2135 |
++ ret = ksz_switch_detect(dev); |
2136 |
++ if (ret) |
2137 |
++ return ret; |
2138 |
+ |
2139 |
+ info = ksz_lookup_info(dev->chip_id); |
2140 |
+ if (!info) |
2141 |
+@@ -998,10 +1156,15 @@ int ksz_switch_register(struct ksz_device *dev, |
2142 |
+ /* Update the compatible info with the probed one */ |
2143 |
+ dev->info = info; |
2144 |
+ |
2145 |
++ dev_info(dev->dev, "found switch: %s, rev %i\n", |
2146 |
++ dev->info->dev_name, dev->chip_rev); |
2147 |
++ |
2148 |
+ ret = ksz_check_device_id(dev); |
2149 |
+ if (ret) |
2150 |
+ return ret; |
2151 |
+ |
2152 |
++ dev->dev_ops = ops; |
2153 |
++ |
2154 |
+ ret = dev->dev_ops->init(dev); |
2155 |
+ if (ret) |
2156 |
+ return ret; |
2157 |
+diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h |
2158 |
+index 8500eaedad67a..10f9ef2dbf1ca 100644 |
2159 |
+--- a/drivers/net/dsa/microchip/ksz_common.h |
2160 |
++++ b/drivers/net/dsa/microchip/ksz_common.h |
2161 |
+@@ -90,6 +90,7 @@ struct ksz_device { |
2162 |
+ |
2163 |
+ /* chip specific data */ |
2164 |
+ u32 chip_id; |
2165 |
++ u8 chip_rev; |
2166 |
+ int cpu_port; /* port connected to CPU */ |
2167 |
+ int phy_port_cnt; |
2168 |
+ phy_interface_t compat_interface; |
2169 |
+@@ -179,10 +180,23 @@ struct ksz_dev_ops { |
2170 |
+ void (*r_mib_pkt)(struct ksz_device *dev, int port, u16 addr, |
2171 |
+ u64 *dropped, u64 *cnt); |
2172 |
+ void (*r_mib_stat64)(struct ksz_device *dev, int port); |
2173 |
++ int (*vlan_filtering)(struct ksz_device *dev, int port, |
2174 |
++ bool flag, struct netlink_ext_ack *extack); |
2175 |
++ int (*vlan_add)(struct ksz_device *dev, int port, |
2176 |
++ const struct switchdev_obj_port_vlan *vlan, |
2177 |
++ struct netlink_ext_ack *extack); |
2178 |
++ int (*vlan_del)(struct ksz_device *dev, int port, |
2179 |
++ const struct switchdev_obj_port_vlan *vlan); |
2180 |
++ int (*mirror_add)(struct ksz_device *dev, int port, |
2181 |
++ struct dsa_mall_mirror_tc_entry *mirror, |
2182 |
++ bool ingress, struct netlink_ext_ack *extack); |
2183 |
++ void (*mirror_del)(struct ksz_device *dev, int port, |
2184 |
++ struct dsa_mall_mirror_tc_entry *mirror); |
2185 |
++ void (*get_caps)(struct ksz_device *dev, int port, |
2186 |
++ struct phylink_config *config); |
2187 |
+ void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze); |
2188 |
+ void (*port_init_cnt)(struct ksz_device *dev, int port); |
2189 |
+ int (*shutdown)(struct ksz_device *dev); |
2190 |
+- int (*detect)(struct ksz_device *dev); |
2191 |
+ int (*init)(struct ksz_device *dev); |
2192 |
+ void (*exit)(struct ksz_device *dev); |
2193 |
+ }; |
2194 |
+@@ -231,6 +245,20 @@ int ksz_port_mdb_del(struct dsa_switch *ds, int port, |
2195 |
+ int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy); |
2196 |
+ void ksz_get_strings(struct dsa_switch *ds, int port, |
2197 |
+ u32 stringset, uint8_t *buf); |
2198 |
++enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, |
2199 |
++ int port, enum dsa_tag_protocol mp); |
2200 |
++int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, |
2201 |
++ bool flag, struct netlink_ext_ack *extack); |
2202 |
++int ksz_port_vlan_add(struct dsa_switch *ds, int port, |
2203 |
++ const struct switchdev_obj_port_vlan *vlan, |
2204 |
++ struct netlink_ext_ack *extack); |
2205 |
++int ksz_port_vlan_del(struct dsa_switch *ds, int port, |
2206 |
++ const struct switchdev_obj_port_vlan *vlan); |
2207 |
++int ksz_port_mirror_add(struct dsa_switch *ds, int port, |
2208 |
++ struct dsa_mall_mirror_tc_entry *mirror, |
2209 |
++ bool ingress, struct netlink_ext_ack *extack); |
2210 |
++void ksz_port_mirror_del(struct dsa_switch *ds, int port, |
2211 |
++ struct dsa_mall_mirror_tc_entry *mirror); |
2212 |
+ |
2213 |
+ /* Common register access functions */ |
2214 |
+ |
2215 |
+@@ -353,6 +381,23 @@ static inline void ksz_regmap_unlock(void *__mtx) |
2216 |
+ #define PORT_RX_ENABLE BIT(1) |
2217 |
+ #define PORT_LEARN_DISABLE BIT(0) |
2218 |
+ |
2219 |
++/* Switch ID Defines */ |
2220 |
++#define REG_CHIP_ID0 0x00 |
2221 |
++ |
2222 |
++#define SW_FAMILY_ID_M GENMASK(15, 8) |
2223 |
++#define KSZ87_FAMILY_ID 0x87 |
2224 |
++#define KSZ88_FAMILY_ID 0x88 |
2225 |
++ |
2226 |
++#define KSZ8_PORT_STATUS_0 0x08 |
2227 |
++#define KSZ8_PORT_FIBER_MODE BIT(7) |
2228 |
++ |
2229 |
++#define SW_CHIP_ID_M GENMASK(7, 4) |
2230 |
++#define KSZ87_CHIP_ID_94 0x6 |
2231 |
++#define KSZ87_CHIP_ID_95 0x9 |
2232 |
++#define KSZ88_CHIP_ID_63 0x3 |
2233 |
++ |
2234 |
++#define SW_REV_ID_M GENMASK(7, 4) |
2235 |
++ |
2236 |
+ /* Regmap tables generation */ |
2237 |
+ #define KSZ_SPI_OP_RD 3 |
2238 |
+ #define KSZ_SPI_OP_WR 2 |
2239 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
2240 |
+index cf9b00576ed36..964354536f9ce 100644 |
2241 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
2242 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
2243 |
+@@ -11183,10 +11183,7 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev, |
2244 |
+ if ((features & NETIF_F_NTUPLE) && !bnxt_rfs_capable(bp)) |
2245 |
+ features &= ~NETIF_F_NTUPLE; |
2246 |
+ |
2247 |
+- if (bp->flags & BNXT_FLAG_NO_AGG_RINGS) |
2248 |
+- features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW); |
2249 |
+- |
2250 |
+- if (!(bp->flags & BNXT_FLAG_TPA)) |
2251 |
++ if ((bp->flags & BNXT_FLAG_NO_AGG_RINGS) || bp->xdp_prog) |
2252 |
+ features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW); |
2253 |
+ |
2254 |
+ if (!(features & NETIF_F_GRO)) |
2255 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h |
2256 |
+index 075c6206325ce..b1b17f9113006 100644 |
2257 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h |
2258 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h |
2259 |
+@@ -2130,6 +2130,7 @@ struct bnxt { |
2260 |
+ #define BNXT_DUMP_CRASH 1 |
2261 |
+ |
2262 |
+ struct bpf_prog *xdp_prog; |
2263 |
++ u8 xdp_has_frags; |
2264 |
+ |
2265 |
+ struct bnxt_ptp_cfg *ptp_cfg; |
2266 |
+ u8 ptp_all_rx_tstamp; |
2267 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c |
2268 |
+index 6b3d4f4c2a75f..d83be40785b89 100644 |
2269 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c |
2270 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c |
2271 |
+@@ -1246,6 +1246,7 @@ int bnxt_dl_register(struct bnxt *bp) |
2272 |
+ if (rc) |
2273 |
+ goto err_dl_port_unreg; |
2274 |
+ |
2275 |
++ devlink_set_features(dl, DEVLINK_F_RELOAD); |
2276 |
+ out: |
2277 |
+ devlink_register(dl); |
2278 |
+ return 0; |
2279 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c |
2280 |
+index a1a2c7a64fd58..c9cf0569451a2 100644 |
2281 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c |
2282 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c |
2283 |
+@@ -623,7 +623,7 @@ static int bnxt_hwrm_func_vf_resc_cfg(struct bnxt *bp, int num_vfs, bool reset) |
2284 |
+ hw_resc->max_stat_ctxs -= le16_to_cpu(req->min_stat_ctx) * n; |
2285 |
+ hw_resc->max_vnics -= le16_to_cpu(req->min_vnics) * n; |
2286 |
+ if (bp->flags & BNXT_FLAG_CHIP_P5) |
2287 |
+- hw_resc->max_irqs -= vf_msix * n; |
2288 |
++ hw_resc->max_nqs -= vf_msix; |
2289 |
+ |
2290 |
+ rc = pf->active_vfs; |
2291 |
+ } |
2292 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |
2293 |
+index f53387ed0167b..c3065ec0a4798 100644 |
2294 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |
2295 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |
2296 |
+@@ -181,6 +181,7 @@ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, |
2297 |
+ struct xdp_buff *xdp) |
2298 |
+ { |
2299 |
+ struct bnxt_sw_rx_bd *rx_buf; |
2300 |
++ u32 buflen = PAGE_SIZE; |
2301 |
+ struct pci_dev *pdev; |
2302 |
+ dma_addr_t mapping; |
2303 |
+ u32 offset; |
2304 |
+@@ -192,7 +193,10 @@ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, |
2305 |
+ mapping = rx_buf->mapping - bp->rx_dma_offset; |
2306 |
+ dma_sync_single_for_cpu(&pdev->dev, mapping + offset, *len, bp->rx_dir); |
2307 |
+ |
2308 |
+- xdp_init_buff(xdp, BNXT_PAGE_MODE_BUF_SIZE + offset, &rxr->xdp_rxq); |
2309 |
++ if (bp->xdp_has_frags) |
2310 |
++ buflen = BNXT_PAGE_MODE_BUF_SIZE + offset; |
2311 |
++ |
2312 |
++ xdp_init_buff(xdp, buflen, &rxr->xdp_rxq); |
2313 |
+ xdp_prepare_buff(xdp, *data_ptr - offset, offset, *len, false); |
2314 |
+ } |
2315 |
+ |
2316 |
+@@ -397,8 +401,10 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog) |
2317 |
+ netdev_warn(dev, "ethtool rx/tx channels must be combined to support XDP.\n"); |
2318 |
+ return -EOPNOTSUPP; |
2319 |
+ } |
2320 |
+- if (prog) |
2321 |
++ if (prog) { |
2322 |
+ tx_xdp = bp->rx_nr_rings; |
2323 |
++ bp->xdp_has_frags = prog->aux->xdp_has_frags; |
2324 |
++ } |
2325 |
+ |
2326 |
+ tc = netdev_get_num_tc(dev); |
2327 |
+ if (!tc) |
2328 |
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c |
2329 |
+index 19704f5c8291c..22a61802a4027 100644 |
2330 |
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c |
2331 |
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c |
2332 |
+@@ -4395,7 +4395,7 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi, |
2333 |
+ (struct in6_addr *)&ipv6_full_mask)) |
2334 |
+ new_mask |= I40E_L3_V6_DST_MASK; |
2335 |
+ else if (ipv6_addr_any((struct in6_addr *) |
2336 |
+- &usr_ip6_spec->ip6src)) |
2337 |
++ &usr_ip6_spec->ip6dst)) |
2338 |
+ new_mask &= ~I40E_L3_V6_DST_MASK; |
2339 |
+ else |
2340 |
+ return -EOPNOTSUPP; |
2341 |
+diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h |
2342 |
+index 60453b3b8d233..6911cbb7afa50 100644 |
2343 |
+--- a/drivers/net/ethernet/intel/ice/ice.h |
2344 |
++++ b/drivers/net/ethernet/intel/ice/ice.h |
2345 |
+@@ -684,8 +684,8 @@ static inline void ice_set_ring_xdp(struct ice_tx_ring *ring) |
2346 |
+ * ice_xsk_pool - get XSK buffer pool bound to a ring |
2347 |
+ * @ring: Rx ring to use |
2348 |
+ * |
2349 |
+- * Returns a pointer to xdp_umem structure if there is a buffer pool present, |
2350 |
+- * NULL otherwise. |
2351 |
++ * Returns a pointer to xsk_buff_pool structure if there is a buffer pool |
2352 |
++ * present, NULL otherwise. |
2353 |
+ */ |
2354 |
+ static inline struct xsk_buff_pool *ice_xsk_pool(struct ice_rx_ring *ring) |
2355 |
+ { |
2356 |
+@@ -699,23 +699,33 @@ static inline struct xsk_buff_pool *ice_xsk_pool(struct ice_rx_ring *ring) |
2357 |
+ } |
2358 |
+ |
2359 |
+ /** |
2360 |
+- * ice_tx_xsk_pool - get XSK buffer pool bound to a ring |
2361 |
+- * @ring: Tx ring to use |
2362 |
++ * ice_tx_xsk_pool - assign XSK buff pool to XDP ring |
2363 |
++ * @vsi: pointer to VSI |
2364 |
++ * @qid: index of a queue to look at XSK buff pool presence |
2365 |
+ * |
2366 |
+- * Returns a pointer to xdp_umem structure if there is a buffer pool present, |
2367 |
+- * NULL otherwise. Tx equivalent of ice_xsk_pool. |
2368 |
++ * Sets XSK buff pool pointer on XDP ring. |
2369 |
++ * |
2370 |
++ * XDP ring is picked from Rx ring, whereas Rx ring is picked based on provided |
2371 |
++ * queue id. Reason for doing so is that queue vectors might have assigned more |
2372 |
++ * than one XDP ring, e.g. when user reduced the queue count on netdev; Rx ring |
2373 |
++ * carries a pointer to one of these XDP rings for its own purposes, such as |
2374 |
++ * handling XDP_TX action, therefore we can piggyback here on the |
2375 |
++ * rx_ring->xdp_ring assignment that was done during XDP rings initialization. |
2376 |
+ */ |
2377 |
+-static inline struct xsk_buff_pool *ice_tx_xsk_pool(struct ice_tx_ring *ring) |
2378 |
++static inline void ice_tx_xsk_pool(struct ice_vsi *vsi, u16 qid) |
2379 |
+ { |
2380 |
+- struct ice_vsi *vsi = ring->vsi; |
2381 |
+- u16 qid; |
2382 |
++ struct ice_tx_ring *ring; |
2383 |
+ |
2384 |
+- qid = ring->q_index - vsi->alloc_txq; |
2385 |
++ ring = vsi->rx_rings[qid]->xdp_ring; |
2386 |
++ if (!ring) |
2387 |
++ return; |
2388 |
+ |
2389 |
+- if (!ice_is_xdp_ena_vsi(vsi) || !test_bit(qid, vsi->af_xdp_zc_qps)) |
2390 |
+- return NULL; |
2391 |
++ if (!ice_is_xdp_ena_vsi(vsi) || !test_bit(qid, vsi->af_xdp_zc_qps)) { |
2392 |
++ ring->xsk_pool = NULL; |
2393 |
++ return; |
2394 |
++ } |
2395 |
+ |
2396 |
+- return xsk_get_pool_from_qid(vsi->netdev, qid); |
2397 |
++ ring->xsk_pool = xsk_get_pool_from_qid(vsi->netdev, qid); |
2398 |
+ } |
2399 |
+ |
2400 |
+ /** |
2401 |
+diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c |
2402 |
+index d6aafa272fb0b..6c4e1d45235ef 100644 |
2403 |
+--- a/drivers/net/ethernet/intel/ice/ice_lib.c |
2404 |
++++ b/drivers/net/ethernet/intel/ice/ice_lib.c |
2405 |
+@@ -1983,8 +1983,8 @@ int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi) |
2406 |
+ if (ret) |
2407 |
+ return ret; |
2408 |
+ |
2409 |
+- ice_for_each_xdp_txq(vsi, i) |
2410 |
+- vsi->xdp_rings[i]->xsk_pool = ice_tx_xsk_pool(vsi->xdp_rings[i]); |
2411 |
++ ice_for_each_rxq(vsi, i) |
2412 |
++ ice_tx_xsk_pool(vsi, i); |
2413 |
+ |
2414 |
+ return ret; |
2415 |
+ } |
2416 |
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c |
2417 |
+index bfd97a9a8f2e0..3d45e075204e3 100644 |
2418 |
+--- a/drivers/net/ethernet/intel/ice/ice_main.c |
2419 |
++++ b/drivers/net/ethernet/intel/ice/ice_main.c |
2420 |
+@@ -2581,7 +2581,6 @@ static int ice_xdp_alloc_setup_rings(struct ice_vsi *vsi) |
2421 |
+ if (ice_setup_tx_ring(xdp_ring)) |
2422 |
+ goto free_xdp_rings; |
2423 |
+ ice_set_ring_xdp(xdp_ring); |
2424 |
+- xdp_ring->xsk_pool = ice_tx_xsk_pool(xdp_ring); |
2425 |
+ spin_lock_init(&xdp_ring->tx_lock); |
2426 |
+ for (j = 0; j < xdp_ring->count; j++) { |
2427 |
+ tx_desc = ICE_TX_DESC(xdp_ring, j); |
2428 |
+@@ -2589,13 +2588,6 @@ static int ice_xdp_alloc_setup_rings(struct ice_vsi *vsi) |
2429 |
+ } |
2430 |
+ } |
2431 |
+ |
2432 |
+- ice_for_each_rxq(vsi, i) { |
2433 |
+- if (static_key_enabled(&ice_xdp_locking_key)) |
2434 |
+- vsi->rx_rings[i]->xdp_ring = vsi->xdp_rings[i % vsi->num_xdp_txq]; |
2435 |
+- else |
2436 |
+- vsi->rx_rings[i]->xdp_ring = vsi->xdp_rings[i]; |
2437 |
+- } |
2438 |
+- |
2439 |
+ return 0; |
2440 |
+ |
2441 |
+ free_xdp_rings: |
2442 |
+@@ -2685,6 +2677,23 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog) |
2443 |
+ xdp_rings_rem -= xdp_rings_per_v; |
2444 |
+ } |
2445 |
+ |
2446 |
++ ice_for_each_rxq(vsi, i) { |
2447 |
++ if (static_key_enabled(&ice_xdp_locking_key)) { |
2448 |
++ vsi->rx_rings[i]->xdp_ring = vsi->xdp_rings[i % vsi->num_xdp_txq]; |
2449 |
++ } else { |
2450 |
++ struct ice_q_vector *q_vector = vsi->rx_rings[i]->q_vector; |
2451 |
++ struct ice_tx_ring *ring; |
2452 |
++ |
2453 |
++ ice_for_each_tx_ring(ring, q_vector->tx) { |
2454 |
++ if (ice_ring_is_xdp(ring)) { |
2455 |
++ vsi->rx_rings[i]->xdp_ring = ring; |
2456 |
++ break; |
2457 |
++ } |
2458 |
++ } |
2459 |
++ } |
2460 |
++ ice_tx_xsk_pool(vsi, i); |
2461 |
++ } |
2462 |
++ |
2463 |
+ /* omit the scheduler update if in reset path; XDP queues will be |
2464 |
+ * taken into account at the end of ice_vsi_rebuild, where |
2465 |
+ * ice_cfg_vsi_lan is being called |
2466 |
+diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c |
2467 |
+index 49ba8bfdbf047..e48e29258450f 100644 |
2468 |
+--- a/drivers/net/ethernet/intel/ice/ice_xsk.c |
2469 |
++++ b/drivers/net/ethernet/intel/ice/ice_xsk.c |
2470 |
+@@ -243,7 +243,7 @@ static int ice_qp_ena(struct ice_vsi *vsi, u16 q_idx) |
2471 |
+ if (err) |
2472 |
+ goto free_buf; |
2473 |
+ ice_set_ring_xdp(xdp_ring); |
2474 |
+- xdp_ring->xsk_pool = ice_tx_xsk_pool(xdp_ring); |
2475 |
++ ice_tx_xsk_pool(vsi, q_idx); |
2476 |
+ } |
2477 |
+ |
2478 |
+ err = ice_vsi_cfg_rxq(rx_ring); |
2479 |
+@@ -329,6 +329,12 @@ int ice_xsk_pool_setup(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid) |
2480 |
+ bool if_running, pool_present = !!pool; |
2481 |
+ int ret = 0, pool_failure = 0; |
2482 |
+ |
2483 |
++ if (qid >= vsi->num_rxq || qid >= vsi->num_txq) { |
2484 |
++ netdev_err(vsi->netdev, "Please use queue id in scope of combined queues count\n"); |
2485 |
++ pool_failure = -EINVAL; |
2486 |
++ goto failure; |
2487 |
++ } |
2488 |
++ |
2489 |
+ if (!is_power_of_2(vsi->rx_rings[qid]->count) || |
2490 |
+ !is_power_of_2(vsi->tx_rings[qid]->count)) { |
2491 |
+ netdev_err(vsi->netdev, "Please align ring sizes to power of 2\n"); |
2492 |
+@@ -353,7 +359,7 @@ xsk_pool_if_up: |
2493 |
+ if (if_running) { |
2494 |
+ ret = ice_qp_ena(vsi, qid); |
2495 |
+ if (!ret && pool_present) |
2496 |
+- napi_schedule(&vsi->xdp_rings[qid]->q_vector->napi); |
2497 |
++ napi_schedule(&vsi->rx_rings[qid]->xdp_ring->q_vector->napi); |
2498 |
+ else if (ret) |
2499 |
+ netdev_err(vsi->netdev, "ice_qp_ena error = %d\n", ret); |
2500 |
+ } |
2501 |
+@@ -944,13 +950,13 @@ ice_xsk_wakeup(struct net_device *netdev, u32 queue_id, |
2502 |
+ if (!ice_is_xdp_ena_vsi(vsi)) |
2503 |
+ return -EINVAL; |
2504 |
+ |
2505 |
+- if (queue_id >= vsi->num_txq) |
2506 |
++ if (queue_id >= vsi->num_txq || queue_id >= vsi->num_rxq) |
2507 |
+ return -EINVAL; |
2508 |
+ |
2509 |
+- if (!vsi->xdp_rings[queue_id]->xsk_pool) |
2510 |
+- return -EINVAL; |
2511 |
++ ring = vsi->rx_rings[queue_id]->xdp_ring; |
2512 |
+ |
2513 |
+- ring = vsi->xdp_rings[queue_id]; |
2514 |
++ if (!ring->xsk_pool) |
2515 |
++ return -EINVAL; |
2516 |
+ |
2517 |
+ /* The idea here is that if NAPI is running, mark a miss, so |
2518 |
+ * it will run again. If not, trigger an interrupt and |
2519 |
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c |
2520 |
+index 336426a67ac1b..38cda659f65f4 100644 |
2521 |
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c |
2522 |
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c |
2523 |
+@@ -1208,7 +1208,6 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) |
2524 |
+ struct cyclecounter cc; |
2525 |
+ unsigned long flags; |
2526 |
+ u32 incval = 0; |
2527 |
+- u32 tsauxc = 0; |
2528 |
+ u32 fuse0 = 0; |
2529 |
+ |
2530 |
+ /* For some of the boards below this mask is technically incorrect. |
2531 |
+@@ -1243,18 +1242,6 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) |
2532 |
+ case ixgbe_mac_x550em_a: |
2533 |
+ case ixgbe_mac_X550: |
2534 |
+ cc.read = ixgbe_ptp_read_X550; |
2535 |
+- |
2536 |
+- /* enable SYSTIME counter */ |
2537 |
+- IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0); |
2538 |
+- IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0); |
2539 |
+- IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0); |
2540 |
+- tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC); |
2541 |
+- IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, |
2542 |
+- tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME); |
2543 |
+- IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS); |
2544 |
+- IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC); |
2545 |
+- |
2546 |
+- IXGBE_WRITE_FLUSH(hw); |
2547 |
+ break; |
2548 |
+ case ixgbe_mac_X540: |
2549 |
+ cc.read = ixgbe_ptp_read_82599; |
2550 |
+@@ -1286,6 +1273,50 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) |
2551 |
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags); |
2552 |
+ } |
2553 |
+ |
2554 |
++/** |
2555 |
++ * ixgbe_ptp_init_systime - Initialize SYSTIME registers |
2556 |
++ * @adapter: the ixgbe private board structure |
2557 |
++ * |
2558 |
++ * Initialize and start the SYSTIME registers. |
2559 |
++ */ |
2560 |
++static void ixgbe_ptp_init_systime(struct ixgbe_adapter *adapter) |
2561 |
++{ |
2562 |
++ struct ixgbe_hw *hw = &adapter->hw; |
2563 |
++ u32 tsauxc; |
2564 |
++ |
2565 |
++ switch (hw->mac.type) { |
2566 |
++ case ixgbe_mac_X550EM_x: |
2567 |
++ case ixgbe_mac_x550em_a: |
2568 |
++ case ixgbe_mac_X550: |
2569 |
++ tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC); |
2570 |
++ |
2571 |
++ /* Reset SYSTIME registers to 0 */ |
2572 |
++ IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0); |
2573 |
++ IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0); |
2574 |
++ IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0); |
2575 |
++ |
2576 |
++ /* Reset interrupt settings */ |
2577 |
++ IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS); |
2578 |
++ IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC); |
2579 |
++ |
2580 |
++ /* Activate the SYSTIME counter */ |
2581 |
++ IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, |
2582 |
++ tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME); |
2583 |
++ break; |
2584 |
++ case ixgbe_mac_X540: |
2585 |
++ case ixgbe_mac_82599EB: |
2586 |
++ /* Reset SYSTIME registers to 0 */ |
2587 |
++ IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0); |
2588 |
++ IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0); |
2589 |
++ break; |
2590 |
++ default: |
2591 |
++ /* Other devices aren't supported */ |
2592 |
++ return; |
2593 |
++ }; |
2594 |
++ |
2595 |
++ IXGBE_WRITE_FLUSH(hw); |
2596 |
++} |
2597 |
++ |
2598 |
+ /** |
2599 |
+ * ixgbe_ptp_reset |
2600 |
+ * @adapter: the ixgbe private board structure |
2601 |
+@@ -1312,6 +1343,8 @@ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter) |
2602 |
+ |
2603 |
+ ixgbe_ptp_start_cyclecounter(adapter); |
2604 |
+ |
2605 |
++ ixgbe_ptp_init_systime(adapter); |
2606 |
++ |
2607 |
+ spin_lock_irqsave(&adapter->tmreg_lock, flags); |
2608 |
+ timecounter_init(&adapter->hw_tc, &adapter->hw_cc, |
2609 |
+ ktime_to_ns(ktime_get_real())); |
2610 |
+diff --git a/drivers/net/ethernet/lantiq_xrx200.c b/drivers/net/ethernet/lantiq_xrx200.c |
2611 |
+index 5edb68a8aab1e..57f27cc7724e7 100644 |
2612 |
+--- a/drivers/net/ethernet/lantiq_xrx200.c |
2613 |
++++ b/drivers/net/ethernet/lantiq_xrx200.c |
2614 |
+@@ -193,6 +193,7 @@ static int xrx200_alloc_buf(struct xrx200_chan *ch, void *(*alloc)(unsigned int |
2615 |
+ |
2616 |
+ ch->rx_buff[ch->dma.desc] = alloc(priv->rx_skb_size); |
2617 |
+ if (!ch->rx_buff[ch->dma.desc]) { |
2618 |
++ ch->rx_buff[ch->dma.desc] = buf; |
2619 |
+ ret = -ENOMEM; |
2620 |
+ goto skip; |
2621 |
+ } |
2622 |
+@@ -239,6 +240,12 @@ static int xrx200_hw_receive(struct xrx200_chan *ch) |
2623 |
+ } |
2624 |
+ |
2625 |
+ skb = build_skb(buf, priv->rx_skb_size); |
2626 |
++ if (!skb) { |
2627 |
++ skb_free_frag(buf); |
2628 |
++ net_dev->stats.rx_dropped++; |
2629 |
++ return -ENOMEM; |
2630 |
++ } |
2631 |
++ |
2632 |
+ skb_reserve(skb, NET_SKB_PAD); |
2633 |
+ skb_put(skb, len); |
2634 |
+ |
2635 |
+@@ -288,7 +295,7 @@ static int xrx200_poll_rx(struct napi_struct *napi, int budget) |
2636 |
+ if (ret == XRX200_DMA_PACKET_IN_PROGRESS) |
2637 |
+ continue; |
2638 |
+ if (ret != XRX200_DMA_PACKET_COMPLETE) |
2639 |
+- return ret; |
2640 |
++ break; |
2641 |
+ rx++; |
2642 |
+ } else { |
2643 |
+ break; |
2644 |
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c |
2645 |
+index 59c9a10f83ba5..dcf0aac0aa65d 100644 |
2646 |
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c |
2647 |
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c |
2648 |
+@@ -1444,8 +1444,8 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, |
2649 |
+ int done = 0, bytes = 0; |
2650 |
+ |
2651 |
+ while (done < budget) { |
2652 |
++ unsigned int pktlen, *rxdcsum; |
2653 |
+ struct net_device *netdev; |
2654 |
+- unsigned int pktlen; |
2655 |
+ dma_addr_t dma_addr; |
2656 |
+ u32 hash, reason; |
2657 |
+ int mac = 0; |
2658 |
+@@ -1512,23 +1512,31 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, |
2659 |
+ pktlen = RX_DMA_GET_PLEN0(trxd.rxd2); |
2660 |
+ skb->dev = netdev; |
2661 |
+ skb_put(skb, pktlen); |
2662 |
+- if (trxd.rxd4 & eth->soc->txrx.rx_dma_l4_valid) |
2663 |
++ |
2664 |
++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { |
2665 |
++ hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; |
2666 |
++ if (hash != MTK_RXD5_FOE_ENTRY) |
2667 |
++ skb_set_hash(skb, jhash_1word(hash, 0), |
2668 |
++ PKT_HASH_TYPE_L4); |
2669 |
++ rxdcsum = &trxd.rxd3; |
2670 |
++ } else { |
2671 |
++ hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY; |
2672 |
++ if (hash != MTK_RXD4_FOE_ENTRY) |
2673 |
++ skb_set_hash(skb, jhash_1word(hash, 0), |
2674 |
++ PKT_HASH_TYPE_L4); |
2675 |
++ rxdcsum = &trxd.rxd4; |
2676 |
++ } |
2677 |
++ |
2678 |
++ if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid) |
2679 |
+ skb->ip_summed = CHECKSUM_UNNECESSARY; |
2680 |
+ else |
2681 |
+ skb_checksum_none_assert(skb); |
2682 |
+ skb->protocol = eth_type_trans(skb, netdev); |
2683 |
+ bytes += pktlen; |
2684 |
+ |
2685 |
+- hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY; |
2686 |
+- if (hash != MTK_RXD4_FOE_ENTRY) { |
2687 |
+- hash = jhash_1word(hash, 0); |
2688 |
+- skb_set_hash(skb, hash, PKT_HASH_TYPE_L4); |
2689 |
+- } |
2690 |
+- |
2691 |
+ reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); |
2692 |
+ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) |
2693 |
+- mtk_ppe_check_skb(eth->ppe, skb, |
2694 |
+- trxd.rxd4 & MTK_RXD4_FOE_ENTRY); |
2695 |
++ mtk_ppe_check_skb(eth->ppe, skb, hash); |
2696 |
+ |
2697 |
+ if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) { |
2698 |
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { |
2699 |
+@@ -3761,6 +3769,7 @@ static const struct mtk_soc_data mt7986_data = { |
2700 |
+ .txd_size = sizeof(struct mtk_tx_dma_v2), |
2701 |
+ .rxd_size = sizeof(struct mtk_rx_dma_v2), |
2702 |
+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2, |
2703 |
++ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2, |
2704 |
+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, |
2705 |
+ .dma_len_offset = 8, |
2706 |
+ }, |
2707 |
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h |
2708 |
+index 0a632896451a4..98d6a6d047e32 100644 |
2709 |
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h |
2710 |
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h |
2711 |
+@@ -307,6 +307,11 @@ |
2712 |
+ #define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */ |
2713 |
+ #define RX_DMA_SPECIAL_TAG BIT(22) |
2714 |
+ |
2715 |
++/* PDMA descriptor rxd5 */ |
2716 |
++#define MTK_RXD5_FOE_ENTRY GENMASK(14, 0) |
2717 |
++#define MTK_RXD5_PPE_CPU_REASON GENMASK(22, 18) |
2718 |
++#define MTK_RXD5_SRC_PORT GENMASK(29, 26) |
2719 |
++ |
2720 |
+ #define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0xf) |
2721 |
+ #define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0x7) |
2722 |
+ |
2723 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
2724 |
+index 087952b84ccb0..9e6db779b6efa 100644 |
2725 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
2726 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
2727 |
+@@ -3678,7 +3678,9 @@ static int set_feature_hw_tc(struct net_device *netdev, bool enable) |
2728 |
+ struct mlx5e_priv *priv = netdev_priv(netdev); |
2729 |
+ |
2730 |
+ #if IS_ENABLED(CONFIG_MLX5_CLS_ACT) |
2731 |
+- if (!enable && mlx5e_tc_num_filters(priv, MLX5_TC_FLAG(NIC_OFFLOAD))) { |
2732 |
++ int tc_flag = mlx5e_is_uplink_rep(priv) ? MLX5_TC_FLAG(ESW_OFFLOAD) : |
2733 |
++ MLX5_TC_FLAG(NIC_OFFLOAD); |
2734 |
++ if (!enable && mlx5e_tc_num_filters(priv, tc_flag)) { |
2735 |
+ netdev_err(netdev, |
2736 |
+ "Active offloaded tc filters, can't turn hw_tc_offload off\n"); |
2737 |
+ return -EINVAL; |
2738 |
+@@ -4733,14 +4735,6 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16 |
2739 |
+ /* RQ */ |
2740 |
+ mlx5e_build_rq_params(mdev, params); |
2741 |
+ |
2742 |
+- /* HW LRO */ |
2743 |
+- if (MLX5_CAP_ETH(mdev, lro_cap) && |
2744 |
+- params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { |
2745 |
+- /* No XSK params: checking the availability of striding RQ in general. */ |
2746 |
+- if (!mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL)) |
2747 |
+- params->packet_merge.type = slow_pci_heuristic(mdev) ? |
2748 |
+- MLX5E_PACKET_MERGE_NONE : MLX5E_PACKET_MERGE_LRO; |
2749 |
+- } |
2750 |
+ params->packet_merge.timeout = mlx5e_choose_lro_timeout(mdev, MLX5E_DEFAULT_LRO_TIMEOUT); |
2751 |
+ |
2752 |
+ /* CQ moderation params */ |
2753 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c |
2754 |
+index f797fd97d305b..7da3dc6261929 100644 |
2755 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c |
2756 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c |
2757 |
+@@ -662,6 +662,8 @@ static void mlx5e_build_rep_params(struct net_device *netdev) |
2758 |
+ |
2759 |
+ params->mqprio.num_tc = 1; |
2760 |
+ params->tunneled_offload_en = false; |
2761 |
++ if (rep->vport != MLX5_VPORT_UPLINK) |
2762 |
++ params->vlan_strip_disable = true; |
2763 |
+ |
2764 |
+ mlx5_query_min_inline(mdev, ¶ms->tx_min_inline_mode); |
2765 |
+ } |
2766 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c |
2767 |
+index eb79810199d3e..d04739cb793e5 100644 |
2768 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c |
2769 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c |
2770 |
+@@ -427,7 +427,8 @@ esw_setup_vport_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *f |
2771 |
+ dest[dest_idx].vport.vhca_id = |
2772 |
+ MLX5_CAP_GEN(esw_attr->dests[attr_idx].mdev, vhca_id); |
2773 |
+ dest[dest_idx].vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID; |
2774 |
+- if (mlx5_lag_mpesw_is_activated(esw->dev)) |
2775 |
++ if (dest[dest_idx].vport.num == MLX5_VPORT_UPLINK && |
2776 |
++ mlx5_lag_mpesw_is_activated(esw->dev)) |
2777 |
+ dest[dest_idx].type = MLX5_FLOW_DESTINATION_TYPE_UPLINK; |
2778 |
+ } |
2779 |
+ if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP) { |
2780 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c |
2781 |
+index 5d41e19378e09..d98acd68af2ec 100644 |
2782 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c |
2783 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c |
2784 |
+@@ -1067,30 +1067,32 @@ static void mlx5_ldev_add_netdev(struct mlx5_lag *ldev, |
2785 |
+ struct net_device *netdev) |
2786 |
+ { |
2787 |
+ unsigned int fn = mlx5_get_dev_index(dev); |
2788 |
++ unsigned long flags; |
2789 |
+ |
2790 |
+ if (fn >= ldev->ports) |
2791 |
+ return; |
2792 |
+ |
2793 |
+- spin_lock(&lag_lock); |
2794 |
++ spin_lock_irqsave(&lag_lock, flags); |
2795 |
+ ldev->pf[fn].netdev = netdev; |
2796 |
+ ldev->tracker.netdev_state[fn].link_up = 0; |
2797 |
+ ldev->tracker.netdev_state[fn].tx_enabled = 0; |
2798 |
+- spin_unlock(&lag_lock); |
2799 |
++ spin_unlock_irqrestore(&lag_lock, flags); |
2800 |
+ } |
2801 |
+ |
2802 |
+ static void mlx5_ldev_remove_netdev(struct mlx5_lag *ldev, |
2803 |
+ struct net_device *netdev) |
2804 |
+ { |
2805 |
++ unsigned long flags; |
2806 |
+ int i; |
2807 |
+ |
2808 |
+- spin_lock(&lag_lock); |
2809 |
++ spin_lock_irqsave(&lag_lock, flags); |
2810 |
+ for (i = 0; i < ldev->ports; i++) { |
2811 |
+ if (ldev->pf[i].netdev == netdev) { |
2812 |
+ ldev->pf[i].netdev = NULL; |
2813 |
+ break; |
2814 |
+ } |
2815 |
+ } |
2816 |
+- spin_unlock(&lag_lock); |
2817 |
++ spin_unlock_irqrestore(&lag_lock, flags); |
2818 |
+ } |
2819 |
+ |
2820 |
+ static void mlx5_ldev_add_mdev(struct mlx5_lag *ldev, |
2821 |
+@@ -1234,7 +1236,7 @@ void mlx5_lag_add_netdev(struct mlx5_core_dev *dev, |
2822 |
+ mlx5_ldev_add_netdev(ldev, dev, netdev); |
2823 |
+ |
2824 |
+ for (i = 0; i < ldev->ports; i++) |
2825 |
+- if (!ldev->pf[i].dev) |
2826 |
++ if (!ldev->pf[i].netdev) |
2827 |
+ break; |
2828 |
+ |
2829 |
+ if (i >= ldev->ports) |
2830 |
+@@ -1246,12 +1248,13 @@ void mlx5_lag_add_netdev(struct mlx5_core_dev *dev, |
2831 |
+ bool mlx5_lag_is_roce(struct mlx5_core_dev *dev) |
2832 |
+ { |
2833 |
+ struct mlx5_lag *ldev; |
2834 |
++ unsigned long flags; |
2835 |
+ bool res; |
2836 |
+ |
2837 |
+- spin_lock(&lag_lock); |
2838 |
++ spin_lock_irqsave(&lag_lock, flags); |
2839 |
+ ldev = mlx5_lag_dev(dev); |
2840 |
+ res = ldev && __mlx5_lag_is_roce(ldev); |
2841 |
+- spin_unlock(&lag_lock); |
2842 |
++ spin_unlock_irqrestore(&lag_lock, flags); |
2843 |
+ |
2844 |
+ return res; |
2845 |
+ } |
2846 |
+@@ -1260,12 +1263,13 @@ EXPORT_SYMBOL(mlx5_lag_is_roce); |
2847 |
+ bool mlx5_lag_is_active(struct mlx5_core_dev *dev) |
2848 |
+ { |
2849 |
+ struct mlx5_lag *ldev; |
2850 |
++ unsigned long flags; |
2851 |
+ bool res; |
2852 |
+ |
2853 |
+- spin_lock(&lag_lock); |
2854 |
++ spin_lock_irqsave(&lag_lock, flags); |
2855 |
+ ldev = mlx5_lag_dev(dev); |
2856 |
+ res = ldev && __mlx5_lag_is_active(ldev); |
2857 |
+- spin_unlock(&lag_lock); |
2858 |
++ spin_unlock_irqrestore(&lag_lock, flags); |
2859 |
+ |
2860 |
+ return res; |
2861 |
+ } |
2862 |
+@@ -1274,13 +1278,14 @@ EXPORT_SYMBOL(mlx5_lag_is_active); |
2863 |
+ bool mlx5_lag_is_master(struct mlx5_core_dev *dev) |
2864 |
+ { |
2865 |
+ struct mlx5_lag *ldev; |
2866 |
++ unsigned long flags; |
2867 |
+ bool res; |
2868 |
+ |
2869 |
+- spin_lock(&lag_lock); |
2870 |
++ spin_lock_irqsave(&lag_lock, flags); |
2871 |
+ ldev = mlx5_lag_dev(dev); |
2872 |
+ res = ldev && __mlx5_lag_is_active(ldev) && |
2873 |
+ dev == ldev->pf[MLX5_LAG_P1].dev; |
2874 |
+- spin_unlock(&lag_lock); |
2875 |
++ spin_unlock_irqrestore(&lag_lock, flags); |
2876 |
+ |
2877 |
+ return res; |
2878 |
+ } |
2879 |
+@@ -1289,12 +1294,13 @@ EXPORT_SYMBOL(mlx5_lag_is_master); |
2880 |
+ bool mlx5_lag_is_sriov(struct mlx5_core_dev *dev) |
2881 |
+ { |
2882 |
+ struct mlx5_lag *ldev; |
2883 |
++ unsigned long flags; |
2884 |
+ bool res; |
2885 |
+ |
2886 |
+- spin_lock(&lag_lock); |
2887 |
++ spin_lock_irqsave(&lag_lock, flags); |
2888 |
+ ldev = mlx5_lag_dev(dev); |
2889 |
+ res = ldev && __mlx5_lag_is_sriov(ldev); |
2890 |
+- spin_unlock(&lag_lock); |
2891 |
++ spin_unlock_irqrestore(&lag_lock, flags); |
2892 |
+ |
2893 |
+ return res; |
2894 |
+ } |
2895 |
+@@ -1303,13 +1309,14 @@ EXPORT_SYMBOL(mlx5_lag_is_sriov); |
2896 |
+ bool mlx5_lag_is_shared_fdb(struct mlx5_core_dev *dev) |
2897 |
+ { |
2898 |
+ struct mlx5_lag *ldev; |
2899 |
++ unsigned long flags; |
2900 |
+ bool res; |
2901 |
+ |
2902 |
+- spin_lock(&lag_lock); |
2903 |
++ spin_lock_irqsave(&lag_lock, flags); |
2904 |
+ ldev = mlx5_lag_dev(dev); |
2905 |
+ res = ldev && __mlx5_lag_is_sriov(ldev) && |
2906 |
+ test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags); |
2907 |
+- spin_unlock(&lag_lock); |
2908 |
++ spin_unlock_irqrestore(&lag_lock, flags); |
2909 |
+ |
2910 |
+ return res; |
2911 |
+ } |
2912 |
+@@ -1352,9 +1359,10 @@ struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev) |
2913 |
+ { |
2914 |
+ struct net_device *ndev = NULL; |
2915 |
+ struct mlx5_lag *ldev; |
2916 |
++ unsigned long flags; |
2917 |
+ int i; |
2918 |
+ |
2919 |
+- spin_lock(&lag_lock); |
2920 |
++ spin_lock_irqsave(&lag_lock, flags); |
2921 |
+ ldev = mlx5_lag_dev(dev); |
2922 |
+ |
2923 |
+ if (!(ldev && __mlx5_lag_is_roce(ldev))) |
2924 |
+@@ -1373,7 +1381,7 @@ struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev) |
2925 |
+ dev_hold(ndev); |
2926 |
+ |
2927 |
+ unlock: |
2928 |
+- spin_unlock(&lag_lock); |
2929 |
++ spin_unlock_irqrestore(&lag_lock, flags); |
2930 |
+ |
2931 |
+ return ndev; |
2932 |
+ } |
2933 |
+@@ -1383,10 +1391,11 @@ u8 mlx5_lag_get_slave_port(struct mlx5_core_dev *dev, |
2934 |
+ struct net_device *slave) |
2935 |
+ { |
2936 |
+ struct mlx5_lag *ldev; |
2937 |
++ unsigned long flags; |
2938 |
+ u8 port = 0; |
2939 |
+ int i; |
2940 |
+ |
2941 |
+- spin_lock(&lag_lock); |
2942 |
++ spin_lock_irqsave(&lag_lock, flags); |
2943 |
+ ldev = mlx5_lag_dev(dev); |
2944 |
+ if (!(ldev && __mlx5_lag_is_roce(ldev))) |
2945 |
+ goto unlock; |
2946 |
+@@ -1401,7 +1410,7 @@ u8 mlx5_lag_get_slave_port(struct mlx5_core_dev *dev, |
2947 |
+ port = ldev->v2p_map[port * ldev->buckets]; |
2948 |
+ |
2949 |
+ unlock: |
2950 |
+- spin_unlock(&lag_lock); |
2951 |
++ spin_unlock_irqrestore(&lag_lock, flags); |
2952 |
+ return port; |
2953 |
+ } |
2954 |
+ EXPORT_SYMBOL(mlx5_lag_get_slave_port); |
2955 |
+@@ -1422,8 +1431,9 @@ struct mlx5_core_dev *mlx5_lag_get_peer_mdev(struct mlx5_core_dev *dev) |
2956 |
+ { |
2957 |
+ struct mlx5_core_dev *peer_dev = NULL; |
2958 |
+ struct mlx5_lag *ldev; |
2959 |
++ unsigned long flags; |
2960 |
+ |
2961 |
+- spin_lock(&lag_lock); |
2962 |
++ spin_lock_irqsave(&lag_lock, flags); |
2963 |
+ ldev = mlx5_lag_dev(dev); |
2964 |
+ if (!ldev) |
2965 |
+ goto unlock; |
2966 |
+@@ -1433,7 +1443,7 @@ struct mlx5_core_dev *mlx5_lag_get_peer_mdev(struct mlx5_core_dev *dev) |
2967 |
+ ldev->pf[MLX5_LAG_P1].dev; |
2968 |
+ |
2969 |
+ unlock: |
2970 |
+- spin_unlock(&lag_lock); |
2971 |
++ spin_unlock_irqrestore(&lag_lock, flags); |
2972 |
+ return peer_dev; |
2973 |
+ } |
2974 |
+ EXPORT_SYMBOL(mlx5_lag_get_peer_mdev); |
2975 |
+@@ -1446,6 +1456,7 @@ int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev, |
2976 |
+ int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out); |
2977 |
+ struct mlx5_core_dev **mdev; |
2978 |
+ struct mlx5_lag *ldev; |
2979 |
++ unsigned long flags; |
2980 |
+ int num_ports; |
2981 |
+ int ret, i, j; |
2982 |
+ void *out; |
2983 |
+@@ -1462,7 +1473,7 @@ int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev, |
2984 |
+ |
2985 |
+ memset(values, 0, sizeof(*values) * num_counters); |
2986 |
+ |
2987 |
+- spin_lock(&lag_lock); |
2988 |
++ spin_lock_irqsave(&lag_lock, flags); |
2989 |
+ ldev = mlx5_lag_dev(dev); |
2990 |
+ if (ldev && __mlx5_lag_is_active(ldev)) { |
2991 |
+ num_ports = ldev->ports; |
2992 |
+@@ -1472,7 +1483,7 @@ int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev, |
2993 |
+ num_ports = 1; |
2994 |
+ mdev[MLX5_LAG_P1] = dev; |
2995 |
+ } |
2996 |
+- spin_unlock(&lag_lock); |
2997 |
++ spin_unlock_irqrestore(&lag_lock, flags); |
2998 |
+ |
2999 |
+ for (i = 0; i < num_ports; ++i) { |
3000 |
+ u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = {}; |
3001 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c |
3002 |
+index ba2e5232b90be..616207c3b187a 100644 |
3003 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c |
3004 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c |
3005 |
+@@ -1472,7 +1472,9 @@ int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx) |
3006 |
+ memcpy(&dev->profile, &profile[profile_idx], sizeof(dev->profile)); |
3007 |
+ INIT_LIST_HEAD(&priv->ctx_list); |
3008 |
+ spin_lock_init(&priv->ctx_lock); |
3009 |
++ lockdep_register_key(&dev->lock_key); |
3010 |
+ mutex_init(&dev->intf_state_mutex); |
3011 |
++ lockdep_set_class(&dev->intf_state_mutex, &dev->lock_key); |
3012 |
+ |
3013 |
+ mutex_init(&priv->bfregs.reg_head.lock); |
3014 |
+ mutex_init(&priv->bfregs.wc_head.lock); |
3015 |
+@@ -1527,6 +1529,7 @@ err_timeout_init: |
3016 |
+ mutex_destroy(&priv->bfregs.wc_head.lock); |
3017 |
+ mutex_destroy(&priv->bfregs.reg_head.lock); |
3018 |
+ mutex_destroy(&dev->intf_state_mutex); |
3019 |
++ lockdep_unregister_key(&dev->lock_key); |
3020 |
+ return err; |
3021 |
+ } |
3022 |
+ |
3023 |
+@@ -1545,6 +1548,7 @@ void mlx5_mdev_uninit(struct mlx5_core_dev *dev) |
3024 |
+ mutex_destroy(&priv->bfregs.wc_head.lock); |
3025 |
+ mutex_destroy(&priv->bfregs.reg_head.lock); |
3026 |
+ mutex_destroy(&dev->intf_state_mutex); |
3027 |
++ lockdep_unregister_key(&dev->lock_key); |
3028 |
+ } |
3029 |
+ |
3030 |
+ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id) |
3031 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c |
3032 |
+index ec76a8b1acc1c..60596357bfc7a 100644 |
3033 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c |
3034 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c |
3035 |
+@@ -376,8 +376,8 @@ retry: |
3036 |
+ goto out_dropped; |
3037 |
+ } |
3038 |
+ } |
3039 |
++ err = mlx5_cmd_check(dev, err, in, out); |
3040 |
+ if (err) { |
3041 |
+- err = mlx5_cmd_check(dev, err, in, out); |
3042 |
+ mlx5_core_warn(dev, "func_id 0x%x, npages %d, err %d\n", |
3043 |
+ func_id, npages, err); |
3044 |
+ goto out_dropped; |
3045 |
+@@ -524,10 +524,13 @@ static int reclaim_pages(struct mlx5_core_dev *dev, u16 func_id, int npages, |
3046 |
+ dev->priv.reclaim_pages_discard += npages; |
3047 |
+ } |
3048 |
+ /* if triggered by FW event and failed by FW then ignore */ |
3049 |
+- if (event && err == -EREMOTEIO) |
3050 |
++ if (event && err == -EREMOTEIO) { |
3051 |
+ err = 0; |
3052 |
++ goto out_free; |
3053 |
++ } |
3054 |
++ |
3055 |
++ err = mlx5_cmd_check(dev, err, in, out); |
3056 |
+ if (err) { |
3057 |
+- err = mlx5_cmd_check(dev, err, in, out); |
3058 |
+ mlx5_core_err(dev, "failed reclaiming pages: err %d\n", err); |
3059 |
+ goto out_free; |
3060 |
+ } |
3061 |
+diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c |
3062 |
+index f11f1cb92025f..3b6beb96ca856 100644 |
3063 |
+--- a/drivers/net/ethernet/moxa/moxart_ether.c |
3064 |
++++ b/drivers/net/ethernet/moxa/moxart_ether.c |
3065 |
+@@ -74,11 +74,6 @@ static int moxart_set_mac_address(struct net_device *ndev, void *addr) |
3066 |
+ static void moxart_mac_free_memory(struct net_device *ndev) |
3067 |
+ { |
3068 |
+ struct moxart_mac_priv_t *priv = netdev_priv(ndev); |
3069 |
+- int i; |
3070 |
+- |
3071 |
+- for (i = 0; i < RX_DESC_NUM; i++) |
3072 |
+- dma_unmap_single(&priv->pdev->dev, priv->rx_mapping[i], |
3073 |
+- priv->rx_buf_size, DMA_FROM_DEVICE); |
3074 |
+ |
3075 |
+ if (priv->tx_desc_base) |
3076 |
+ dma_free_coherent(&priv->pdev->dev, |
3077 |
+@@ -193,6 +188,7 @@ static int moxart_mac_open(struct net_device *ndev) |
3078 |
+ static int moxart_mac_stop(struct net_device *ndev) |
3079 |
+ { |
3080 |
+ struct moxart_mac_priv_t *priv = netdev_priv(ndev); |
3081 |
++ int i; |
3082 |
+ |
3083 |
+ napi_disable(&priv->napi); |
3084 |
+ |
3085 |
+@@ -204,6 +200,11 @@ static int moxart_mac_stop(struct net_device *ndev) |
3086 |
+ /* disable all functions */ |
3087 |
+ writel(0, priv->base + REG_MAC_CTRL); |
3088 |
+ |
3089 |
++ /* unmap areas mapped in moxart_mac_setup_desc_ring() */ |
3090 |
++ for (i = 0; i < RX_DESC_NUM; i++) |
3091 |
++ dma_unmap_single(&priv->pdev->dev, priv->rx_mapping[i], |
3092 |
++ priv->rx_buf_size, DMA_FROM_DEVICE); |
3093 |
++ |
3094 |
+ return 0; |
3095 |
+ } |
3096 |
+ |
3097 |
+diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c |
3098 |
+index 1443f788ee37c..0be79c5167813 100644 |
3099 |
+--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c |
3100 |
++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c |
3101 |
+@@ -1564,8 +1564,67 @@ static int ionic_set_features(struct net_device *netdev, |
3102 |
+ return err; |
3103 |
+ } |
3104 |
+ |
3105 |
++static int ionic_set_attr_mac(struct ionic_lif *lif, u8 *mac) |
3106 |
++{ |
3107 |
++ struct ionic_admin_ctx ctx = { |
3108 |
++ .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work), |
3109 |
++ .cmd.lif_setattr = { |
3110 |
++ .opcode = IONIC_CMD_LIF_SETATTR, |
3111 |
++ .index = cpu_to_le16(lif->index), |
3112 |
++ .attr = IONIC_LIF_ATTR_MAC, |
3113 |
++ }, |
3114 |
++ }; |
3115 |
++ |
3116 |
++ ether_addr_copy(ctx.cmd.lif_setattr.mac, mac); |
3117 |
++ return ionic_adminq_post_wait(lif, &ctx); |
3118 |
++} |
3119 |
++ |
3120 |
++static int ionic_get_attr_mac(struct ionic_lif *lif, u8 *mac_addr) |
3121 |
++{ |
3122 |
++ struct ionic_admin_ctx ctx = { |
3123 |
++ .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work), |
3124 |
++ .cmd.lif_getattr = { |
3125 |
++ .opcode = IONIC_CMD_LIF_GETATTR, |
3126 |
++ .index = cpu_to_le16(lif->index), |
3127 |
++ .attr = IONIC_LIF_ATTR_MAC, |
3128 |
++ }, |
3129 |
++ }; |
3130 |
++ int err; |
3131 |
++ |
3132 |
++ err = ionic_adminq_post_wait(lif, &ctx); |
3133 |
++ if (err) |
3134 |
++ return err; |
3135 |
++ |
3136 |
++ ether_addr_copy(mac_addr, ctx.comp.lif_getattr.mac); |
3137 |
++ return 0; |
3138 |
++} |
3139 |
++ |
3140 |
++static int ionic_program_mac(struct ionic_lif *lif, u8 *mac) |
3141 |
++{ |
3142 |
++ u8 get_mac[ETH_ALEN]; |
3143 |
++ int err; |
3144 |
++ |
3145 |
++ err = ionic_set_attr_mac(lif, mac); |
3146 |
++ if (err) |
3147 |
++ return err; |
3148 |
++ |
3149 |
++ err = ionic_get_attr_mac(lif, get_mac); |
3150 |
++ if (err) |
3151 |
++ return err; |
3152 |
++ |
3153 |
++ /* To deal with older firmware that silently ignores the set attr mac: |
3154 |
++ * doesn't actually change the mac and doesn't return an error, so we |
3155 |
++ * do the get attr to verify whether or not the set actually happened |
3156 |
++ */ |
3157 |
++ if (!ether_addr_equal(get_mac, mac)) |
3158 |
++ return 1; |
3159 |
++ |
3160 |
++ return 0; |
3161 |
++} |
3162 |
++ |
3163 |
+ static int ionic_set_mac_address(struct net_device *netdev, void *sa) |
3164 |
+ { |
3165 |
++ struct ionic_lif *lif = netdev_priv(netdev); |
3166 |
+ struct sockaddr *addr = sa; |
3167 |
+ u8 *mac; |
3168 |
+ int err; |
3169 |
+@@ -1574,6 +1633,14 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa) |
3170 |
+ if (ether_addr_equal(netdev->dev_addr, mac)) |
3171 |
+ return 0; |
3172 |
+ |
3173 |
++ err = ionic_program_mac(lif, mac); |
3174 |
++ if (err < 0) |
3175 |
++ return err; |
3176 |
++ |
3177 |
++ if (err > 0) |
3178 |
++ netdev_dbg(netdev, "%s: SET and GET ATTR Mac are not equal-due to old FW running\n", |
3179 |
++ __func__); |
3180 |
++ |
3181 |
+ err = eth_prepare_mac_addr_change(netdev, addr); |
3182 |
+ if (err) |
3183 |
+ return err; |
3184 |
+@@ -2963,6 +3030,9 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif) |
3185 |
+ |
3186 |
+ mutex_lock(&lif->queue_lock); |
3187 |
+ |
3188 |
++ if (test_and_clear_bit(IONIC_LIF_F_BROKEN, lif->state)) |
3189 |
++ dev_info(ionic->dev, "FW Up: clearing broken state\n"); |
3190 |
++ |
3191 |
+ err = ionic_qcqs_alloc(lif); |
3192 |
+ if (err) |
3193 |
+ goto err_unlock; |
3194 |
+@@ -3169,6 +3239,7 @@ static int ionic_station_set(struct ionic_lif *lif) |
3195 |
+ .attr = IONIC_LIF_ATTR_MAC, |
3196 |
+ }, |
3197 |
+ }; |
3198 |
++ u8 mac_address[ETH_ALEN]; |
3199 |
+ struct sockaddr addr; |
3200 |
+ int err; |
3201 |
+ |
3202 |
+@@ -3177,8 +3248,23 @@ static int ionic_station_set(struct ionic_lif *lif) |
3203 |
+ return err; |
3204 |
+ netdev_dbg(lif->netdev, "found initial MAC addr %pM\n", |
3205 |
+ ctx.comp.lif_getattr.mac); |
3206 |
+- if (is_zero_ether_addr(ctx.comp.lif_getattr.mac)) |
3207 |
+- return 0; |
3208 |
++ ether_addr_copy(mac_address, ctx.comp.lif_getattr.mac); |
3209 |
++ |
3210 |
++ if (is_zero_ether_addr(mac_address)) { |
3211 |
++ eth_hw_addr_random(netdev); |
3212 |
++ netdev_dbg(netdev, "Random Mac generated: %pM\n", netdev->dev_addr); |
3213 |
++ ether_addr_copy(mac_address, netdev->dev_addr); |
3214 |
++ |
3215 |
++ err = ionic_program_mac(lif, mac_address); |
3216 |
++ if (err < 0) |
3217 |
++ return err; |
3218 |
++ |
3219 |
++ if (err > 0) { |
3220 |
++ netdev_dbg(netdev, "%s:SET/GET ATTR Mac are not same-due to old FW running\n", |
3221 |
++ __func__); |
3222 |
++ return 0; |
3223 |
++ } |
3224 |
++ } |
3225 |
+ |
3226 |
+ if (!is_zero_ether_addr(netdev->dev_addr)) { |
3227 |
+ /* If the netdev mac is non-zero and doesn't match the default |
3228 |
+@@ -3186,12 +3272,11 @@ static int ionic_station_set(struct ionic_lif *lif) |
3229 |
+ * likely here again after a fw-upgrade reset. We need to be |
3230 |
+ * sure the netdev mac is in our filter list. |
3231 |
+ */ |
3232 |
+- if (!ether_addr_equal(ctx.comp.lif_getattr.mac, |
3233 |
+- netdev->dev_addr)) |
3234 |
++ if (!ether_addr_equal(mac_address, netdev->dev_addr)) |
3235 |
+ ionic_lif_addr_add(lif, netdev->dev_addr); |
3236 |
+ } else { |
3237 |
+ /* Update the netdev mac with the device's mac */ |
3238 |
+- memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len); |
3239 |
++ ether_addr_copy(addr.sa_data, mac_address); |
3240 |
+ addr.sa_family = AF_INET; |
3241 |
+ err = eth_prepare_mac_addr_change(netdev, &addr); |
3242 |
+ if (err) { |
3243 |
+diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c |
3244 |
+index 4029b4e021f86..56f93b0305519 100644 |
3245 |
+--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c |
3246 |
++++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c |
3247 |
+@@ -474,8 +474,8 @@ try_again: |
3248 |
+ ionic_opcode_to_str(opcode), opcode, |
3249 |
+ ionic_error_to_str(err), err); |
3250 |
+ |
3251 |
+- msleep(1000); |
3252 |
+ iowrite32(0, &idev->dev_cmd_regs->done); |
3253 |
++ msleep(1000); |
3254 |
+ iowrite32(1, &idev->dev_cmd_regs->doorbell); |
3255 |
+ goto try_again; |
3256 |
+ } |
3257 |
+@@ -488,6 +488,8 @@ try_again: |
3258 |
+ return ionic_error_to_errno(err); |
3259 |
+ } |
3260 |
+ |
3261 |
++ ionic_dev_cmd_clean(ionic); |
3262 |
++ |
3263 |
+ return 0; |
3264 |
+ } |
3265 |
+ |
3266 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c |
3267 |
+index caa4bfc4c1d62..9b6138b117766 100644 |
3268 |
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c |
3269 |
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c |
3270 |
+@@ -258,14 +258,18 @@ EXPORT_SYMBOL_GPL(stmmac_set_mac_addr); |
3271 |
+ /* Enable disable MAC RX/TX */ |
3272 |
+ void stmmac_set_mac(void __iomem *ioaddr, bool enable) |
3273 |
+ { |
3274 |
+- u32 value = readl(ioaddr + MAC_CTRL_REG); |
3275 |
++ u32 old_val, value; |
3276 |
++ |
3277 |
++ old_val = readl(ioaddr + MAC_CTRL_REG); |
3278 |
++ value = old_val; |
3279 |
+ |
3280 |
+ if (enable) |
3281 |
+ value |= MAC_ENABLE_RX | MAC_ENABLE_TX; |
3282 |
+ else |
3283 |
+ value &= ~(MAC_ENABLE_TX | MAC_ENABLE_RX); |
3284 |
+ |
3285 |
+- writel(value, ioaddr + MAC_CTRL_REG); |
3286 |
++ if (value != old_val) |
3287 |
++ writel(value, ioaddr + MAC_CTRL_REG); |
3288 |
+ } |
3289 |
+ |
3290 |
+ void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, |
3291 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
3292 |
+index c5f33630e7718..78f11dabca056 100644 |
3293 |
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
3294 |
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
3295 |
+@@ -983,10 +983,10 @@ static void stmmac_mac_link_up(struct phylink_config *config, |
3296 |
+ bool tx_pause, bool rx_pause) |
3297 |
+ { |
3298 |
+ struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev)); |
3299 |
+- u32 ctrl; |
3300 |
++ u32 old_ctrl, ctrl; |
3301 |
+ |
3302 |
+- ctrl = readl(priv->ioaddr + MAC_CTRL_REG); |
3303 |
+- ctrl &= ~priv->hw->link.speed_mask; |
3304 |
++ old_ctrl = readl(priv->ioaddr + MAC_CTRL_REG); |
3305 |
++ ctrl = old_ctrl & ~priv->hw->link.speed_mask; |
3306 |
+ |
3307 |
+ if (interface == PHY_INTERFACE_MODE_USXGMII) { |
3308 |
+ switch (speed) { |
3309 |
+@@ -1061,7 +1061,8 @@ static void stmmac_mac_link_up(struct phylink_config *config, |
3310 |
+ if (tx_pause && rx_pause) |
3311 |
+ stmmac_mac_flow_ctrl(priv, duplex); |
3312 |
+ |
3313 |
+- writel(ctrl, priv->ioaddr + MAC_CTRL_REG); |
3314 |
++ if (ctrl != old_ctrl) |
3315 |
++ writel(ctrl, priv->ioaddr + MAC_CTRL_REG); |
3316 |
+ |
3317 |
+ stmmac_mac_set(priv, priv->ioaddr, true); |
3318 |
+ if (phy && priv->dma_cap.eee) { |
3319 |
+diff --git a/drivers/net/ipa/ipa_mem.c b/drivers/net/ipa/ipa_mem.c |
3320 |
+index 1e9eae208e44f..53a1dbeaffa6d 100644 |
3321 |
+--- a/drivers/net/ipa/ipa_mem.c |
3322 |
++++ b/drivers/net/ipa/ipa_mem.c |
3323 |
+@@ -568,7 +568,7 @@ static int ipa_smem_init(struct ipa *ipa, u32 item, size_t size) |
3324 |
+ } |
3325 |
+ |
3326 |
+ /* Align the address down and the size up to a page boundary */ |
3327 |
+- addr = qcom_smem_virt_to_phys(virt) & PAGE_MASK; |
3328 |
++ addr = qcom_smem_virt_to_phys(virt); |
3329 |
+ phys = addr & PAGE_MASK; |
3330 |
+ size = PAGE_ALIGN(size + addr - phys); |
3331 |
+ iova = phys; /* We just want a direct mapping */ |
3332 |
+diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c |
3333 |
+index ef02f2cf5ce13..cbabca167a078 100644 |
3334 |
+--- a/drivers/net/ipvlan/ipvtap.c |
3335 |
++++ b/drivers/net/ipvlan/ipvtap.c |
3336 |
+@@ -194,7 +194,7 @@ static struct notifier_block ipvtap_notifier_block __read_mostly = { |
3337 |
+ .notifier_call = ipvtap_device_event, |
3338 |
+ }; |
3339 |
+ |
3340 |
+-static int ipvtap_init(void) |
3341 |
++static int __init ipvtap_init(void) |
3342 |
+ { |
3343 |
+ int err; |
3344 |
+ |
3345 |
+@@ -228,7 +228,7 @@ out1: |
3346 |
+ } |
3347 |
+ module_init(ipvtap_init); |
3348 |
+ |
3349 |
+-static void ipvtap_exit(void) |
3350 |
++static void __exit ipvtap_exit(void) |
3351 |
+ { |
3352 |
+ rtnl_link_unregister(&ipvtap_link_ops); |
3353 |
+ unregister_netdevice_notifier(&ipvtap_notifier_block); |
3354 |
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c |
3355 |
+index f354fad05714a..5b0b23e55fa76 100644 |
3356 |
+--- a/drivers/net/macsec.c |
3357 |
++++ b/drivers/net/macsec.c |
3358 |
+@@ -449,11 +449,6 @@ static struct macsec_eth_header *macsec_ethhdr(struct sk_buff *skb) |
3359 |
+ return (struct macsec_eth_header *)skb_mac_header(skb); |
3360 |
+ } |
3361 |
+ |
3362 |
+-static sci_t dev_to_sci(struct net_device *dev, __be16 port) |
3363 |
+-{ |
3364 |
+- return make_sci(dev->dev_addr, port); |
3365 |
+-} |
3366 |
+- |
3367 |
+ static void __macsec_pn_wrapped(struct macsec_secy *secy, |
3368 |
+ struct macsec_tx_sa *tx_sa) |
3369 |
+ { |
3370 |
+@@ -3622,7 +3617,6 @@ static int macsec_set_mac_address(struct net_device *dev, void *p) |
3371 |
+ |
3372 |
+ out: |
3373 |
+ eth_hw_addr_set(dev, addr->sa_data); |
3374 |
+- macsec->secy.sci = dev_to_sci(dev, MACSEC_PORT_ES); |
3375 |
+ |
3376 |
+ /* If h/w offloading is available, propagate to the device */ |
3377 |
+ if (macsec_is_offloaded(macsec)) { |
3378 |
+@@ -3960,6 +3954,11 @@ static bool sci_exists(struct net_device *dev, sci_t sci) |
3379 |
+ return false; |
3380 |
+ } |
3381 |
+ |
3382 |
++static sci_t dev_to_sci(struct net_device *dev, __be16 port) |
3383 |
++{ |
3384 |
++ return make_sci(dev->dev_addr, port); |
3385 |
++} |
3386 |
++ |
3387 |
+ static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len) |
3388 |
+ { |
3389 |
+ struct macsec_dev *macsec = macsec_priv(dev); |
3390 |
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c |
3391 |
+index 608de5a94165f..f90a21781d8d6 100644 |
3392 |
+--- a/drivers/net/phy/phy_device.c |
3393 |
++++ b/drivers/net/phy/phy_device.c |
3394 |
+@@ -316,11 +316,11 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev) |
3395 |
+ |
3396 |
+ phydev->suspended_by_mdio_bus = 0; |
3397 |
+ |
3398 |
+- /* If we managed to get here with the PHY state machine in a state other |
3399 |
+- * than PHY_HALTED this is an indication that something went wrong and |
3400 |
+- * we should most likely be using MAC managed PM and we are not. |
3401 |
++ /* If we manged to get here with the PHY state machine in a state neither |
3402 |
++ * PHY_HALTED nor PHY_READY this is an indication that something went wrong |
3403 |
++ * and we should most likely be using MAC managed PM and we are not. |
3404 |
+ */ |
3405 |
+- WARN_ON(phydev->state != PHY_HALTED && !phydev->mac_managed_pm); |
3406 |
++ WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY); |
3407 |
+ |
3408 |
+ ret = phy_init_hw(phydev); |
3409 |
+ if (ret < 0) |
3410 |
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c |
3411 |
+index 0f6efaabaa32b..d142ac8fcf6e2 100644 |
3412 |
+--- a/drivers/net/usb/r8152.c |
3413 |
++++ b/drivers/net/usb/r8152.c |
3414 |
+@@ -5906,6 +5906,11 @@ static void r8153_enter_oob(struct r8152 *tp) |
3415 |
+ ocp_data &= ~NOW_IS_OOB; |
3416 |
+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); |
3417 |
+ |
3418 |
++ /* RX FIFO settings for OOB */ |
3419 |
++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_OOB); |
3420 |
++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_OOB); |
3421 |
++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_OOB); |
3422 |
++ |
3423 |
+ rtl_disable(tp); |
3424 |
+ rtl_reset_bmu(tp); |
3425 |
+ |
3426 |
+@@ -6431,21 +6436,8 @@ static void r8156_fc_parameter(struct r8152 *tp) |
3427 |
+ u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp); |
3428 |
+ u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp); |
3429 |
+ |
3430 |
+- switch (tp->version) { |
3431 |
+- case RTL_VER_10: |
3432 |
+- case RTL_VER_11: |
3433 |
+- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 8); |
3434 |
+- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 8); |
3435 |
+- break; |
3436 |
+- case RTL_VER_12: |
3437 |
+- case RTL_VER_13: |
3438 |
+- case RTL_VER_15: |
3439 |
+- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16); |
3440 |
+- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16); |
3441 |
+- break; |
3442 |
+- default: |
3443 |
+- break; |
3444 |
+- } |
3445 |
++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16); |
3446 |
++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16); |
3447 |
+ } |
3448 |
+ |
3449 |
+ static void rtl8156_change_mtu(struct r8152 *tp) |
3450 |
+@@ -6557,6 +6549,11 @@ static void rtl8156_down(struct r8152 *tp) |
3451 |
+ ocp_data &= ~NOW_IS_OOB; |
3452 |
+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); |
3453 |
+ |
3454 |
++ /* RX FIFO settings for OOB */ |
3455 |
++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, 64 / 16); |
3456 |
++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, 1024 / 16); |
3457 |
++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, 4096 / 16); |
3458 |
++ |
3459 |
+ rtl_disable(tp); |
3460 |
+ rtl_reset_bmu(tp); |
3461 |
+ |
3462 |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c |
3463 |
+index faa279bbbcb2c..7eb23805aa942 100644 |
3464 |
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c |
3465 |
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c |
3466 |
+@@ -1403,6 +1403,8 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy, |
3467 |
+ else |
3468 |
+ conn_type = CONNECTION_INFRA_AP; |
3469 |
+ basic_req.basic.conn_type = cpu_to_le32(conn_type); |
3470 |
++ /* Fully active/deactivate BSS network in AP mode only */ |
3471 |
++ basic_req.basic.active = enable; |
3472 |
+ break; |
3473 |
+ case NL80211_IFTYPE_STATION: |
3474 |
+ if (vif->p2p) |
3475 |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c |
3476 |
+index e86fe9ee4623e..d3f310877248b 100644 |
3477 |
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c |
3478 |
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c |
3479 |
+@@ -653,15 +653,6 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw, |
3480 |
+ } |
3481 |
+ } |
3482 |
+ |
3483 |
+- if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) { |
3484 |
+- struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; |
3485 |
+- |
3486 |
+- mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, |
3487 |
+- true); |
3488 |
+- mt7921_mcu_sta_update(dev, NULL, vif, true, |
3489 |
+- MT76_STA_INFO_STATE_NONE); |
3490 |
+- } |
3491 |
+- |
3492 |
+ if (changed & (BSS_CHANGED_BEACON | |
3493 |
+ BSS_CHANGED_BEACON_ENABLED)) |
3494 |
+ mt7921_mcu_uni_add_beacon_offload(dev, hw, vif, |
3495 |
+@@ -1500,6 +1491,42 @@ mt7921_channel_switch_beacon(struct ieee80211_hw *hw, |
3496 |
+ mt7921_mutex_release(dev); |
3497 |
+ } |
3498 |
+ |
3499 |
++static int |
3500 |
++mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
3501 |
++{ |
3502 |
++ struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; |
3503 |
++ struct mt7921_phy *phy = mt7921_hw_phy(hw); |
3504 |
++ struct mt7921_dev *dev = mt7921_hw_dev(hw); |
3505 |
++ int err; |
3506 |
++ |
3507 |
++ err = mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, |
3508 |
++ true); |
3509 |
++ if (err) |
3510 |
++ return err; |
3511 |
++ |
3512 |
++ err = mt7921_mcu_set_bss_pm(dev, vif, true); |
3513 |
++ if (err) |
3514 |
++ return err; |
3515 |
++ |
3516 |
++ return mt7921_mcu_sta_update(dev, NULL, vif, true, |
3517 |
++ MT76_STA_INFO_STATE_NONE); |
3518 |
++} |
3519 |
++ |
3520 |
++static void |
3521 |
++mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
3522 |
++{ |
3523 |
++ struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; |
3524 |
++ struct mt7921_phy *phy = mt7921_hw_phy(hw); |
3525 |
++ struct mt7921_dev *dev = mt7921_hw_dev(hw); |
3526 |
++ int err; |
3527 |
++ |
3528 |
++ err = mt7921_mcu_set_bss_pm(dev, vif, false); |
3529 |
++ if (err) |
3530 |
++ return; |
3531 |
++ |
3532 |
++ mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, false); |
3533 |
++} |
3534 |
++ |
3535 |
+ const struct ieee80211_ops mt7921_ops = { |
3536 |
+ .tx = mt7921_tx, |
3537 |
+ .start = mt7921_start, |
3538 |
+@@ -1510,6 +1537,8 @@ const struct ieee80211_ops mt7921_ops = { |
3539 |
+ .conf_tx = mt7921_conf_tx, |
3540 |
+ .configure_filter = mt7921_configure_filter, |
3541 |
+ .bss_info_changed = mt7921_bss_info_changed, |
3542 |
++ .start_ap = mt7921_start_ap, |
3543 |
++ .stop_ap = mt7921_stop_ap, |
3544 |
+ .sta_state = mt7921_sta_state, |
3545 |
+ .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove, |
3546 |
+ .set_key = mt7921_set_key, |
3547 |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c |
3548 |
+index 613a94be8ea44..6d0aceb5226ab 100644 |
3549 |
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c |
3550 |
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c |
3551 |
+@@ -1020,7 +1020,7 @@ mt7921_mcu_uni_bss_bcnft(struct mt7921_dev *dev, struct ieee80211_vif *vif, |
3552 |
+ &bcnft_req, sizeof(bcnft_req), true); |
3553 |
+ } |
3554 |
+ |
3555 |
+-static int |
3556 |
++int |
3557 |
+ mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif, |
3558 |
+ bool enable) |
3559 |
+ { |
3560 |
+@@ -1049,9 +1049,6 @@ mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif, |
3561 |
+ }; |
3562 |
+ int err; |
3563 |
+ |
3564 |
+- if (vif->type != NL80211_IFTYPE_STATION) |
3565 |
+- return 0; |
3566 |
+- |
3567 |
+ err = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_ABORT), |
3568 |
+ &req_hdr, sizeof(req_hdr), false); |
3569 |
+ if (err < 0 || !enable) |
3570 |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h |
3571 |
+index 66054123bcc47..cebc3cfa01b8a 100644 |
3572 |
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h |
3573 |
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h |
3574 |
+@@ -280,6 +280,8 @@ int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force); |
3575 |
+ int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev); |
3576 |
+ void mt7921_dma_cleanup(struct mt7921_dev *dev); |
3577 |
+ int mt7921_run_firmware(struct mt7921_dev *dev); |
3578 |
++int mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif, |
3579 |
++ bool enable); |
3580 |
+ int mt7921_mcu_sta_update(struct mt7921_dev *dev, struct ieee80211_sta *sta, |
3581 |
+ struct ieee80211_vif *vif, bool enable, |
3582 |
+ enum mt76_sta_info_state state); |
3583 |
+diff --git a/drivers/nfc/pn533/uart.c b/drivers/nfc/pn533/uart.c |
3584 |
+index 2caf997f9bc94..07596bf5f7d6d 100644 |
3585 |
+--- a/drivers/nfc/pn533/uart.c |
3586 |
++++ b/drivers/nfc/pn533/uart.c |
3587 |
+@@ -310,6 +310,7 @@ static void pn532_uart_remove(struct serdev_device *serdev) |
3588 |
+ pn53x_unregister_nfc(pn532->priv); |
3589 |
+ serdev_device_close(serdev); |
3590 |
+ pn53x_common_clean(pn532->priv); |
3591 |
++ del_timer_sync(&pn532->cmd_timeout); |
3592 |
+ kfree_skb(pn532->recv_skb); |
3593 |
+ kfree(pn532); |
3594 |
+ } |
3595 |
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c |
3596 |
+index 6ffc9e4258a80..78edb1ea4748d 100644 |
3597 |
+--- a/drivers/scsi/scsi_lib.c |
3598 |
++++ b/drivers/scsi/scsi_lib.c |
3599 |
+@@ -1549,7 +1549,6 @@ static blk_status_t scsi_prepare_cmd(struct request *req) |
3600 |
+ scsi_init_command(sdev, cmd); |
3601 |
+ |
3602 |
+ cmd->eh_eflags = 0; |
3603 |
+- cmd->allowed = 0; |
3604 |
+ cmd->prot_type = 0; |
3605 |
+ cmd->prot_flags = 0; |
3606 |
+ cmd->submitter = 0; |
3607 |
+@@ -1600,6 +1599,8 @@ static blk_status_t scsi_prepare_cmd(struct request *req) |
3608 |
+ return ret; |
3609 |
+ } |
3610 |
+ |
3611 |
++ /* Usually overridden by the ULP */ |
3612 |
++ cmd->allowed = 0; |
3613 |
+ memset(cmd->cmnd, 0, sizeof(cmd->cmnd)); |
3614 |
+ return scsi_cmd_to_driver(cmd)->init_command(cmd); |
3615 |
+ } |
3616 |
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c |
3617 |
+index fe000da113327..8ced292c4b962 100644 |
3618 |
+--- a/drivers/scsi/storvsc_drv.c |
3619 |
++++ b/drivers/scsi/storvsc_drv.c |
3620 |
+@@ -2012,7 +2012,7 @@ static int storvsc_probe(struct hv_device *device, |
3621 |
+ */ |
3622 |
+ host_dev->handle_error_wq = |
3623 |
+ alloc_ordered_workqueue("storvsc_error_wq_%d", |
3624 |
+- WQ_MEM_RECLAIM, |
3625 |
++ 0, |
3626 |
+ host->host_no); |
3627 |
+ if (!host_dev->handle_error_wq) { |
3628 |
+ ret = -ENOMEM; |
3629 |
+diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c |
3630 |
+index b89075f3b6ab7..2efaed36a3adc 100644 |
3631 |
+--- a/drivers/video/fbdev/core/fbcon.c |
3632 |
++++ b/drivers/video/fbdev/core/fbcon.c |
3633 |
+@@ -2402,15 +2402,21 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount, |
3634 |
+ struct fb_info *info = fbcon_info_from_console(vc->vc_num); |
3635 |
+ struct fbcon_ops *ops = info->fbcon_par; |
3636 |
+ struct fbcon_display *p = &fb_display[vc->vc_num]; |
3637 |
+- int resize; |
3638 |
++ int resize, ret, old_userfont, old_width, old_height, old_charcount; |
3639 |
+ char *old_data = NULL; |
3640 |
+ |
3641 |
+ resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); |
3642 |
+ if (p->userfont) |
3643 |
+ old_data = vc->vc_font.data; |
3644 |
+ vc->vc_font.data = (void *)(p->fontdata = data); |
3645 |
++ old_userfont = p->userfont; |
3646 |
+ if ((p->userfont = userfont)) |
3647 |
+ REFCOUNT(data)++; |
3648 |
++ |
3649 |
++ old_width = vc->vc_font.width; |
3650 |
++ old_height = vc->vc_font.height; |
3651 |
++ old_charcount = vc->vc_font.charcount; |
3652 |
++ |
3653 |
+ vc->vc_font.width = w; |
3654 |
+ vc->vc_font.height = h; |
3655 |
+ vc->vc_font.charcount = charcount; |
3656 |
+@@ -2426,7 +2432,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount, |
3657 |
+ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); |
3658 |
+ cols /= w; |
3659 |
+ rows /= h; |
3660 |
+- vc_resize(vc, cols, rows); |
3661 |
++ ret = vc_resize(vc, cols, rows); |
3662 |
++ if (ret) |
3663 |
++ goto err_out; |
3664 |
+ } else if (con_is_visible(vc) |
3665 |
+ && vc->vc_mode == KD_TEXT) { |
3666 |
+ fbcon_clear_margins(vc, 0); |
3667 |
+@@ -2436,6 +2444,21 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount, |
3668 |
+ if (old_data && (--REFCOUNT(old_data) == 0)) |
3669 |
+ kfree(old_data - FONT_EXTRA_WORDS * sizeof(int)); |
3670 |
+ return 0; |
3671 |
++ |
3672 |
++err_out: |
3673 |
++ p->fontdata = old_data; |
3674 |
++ vc->vc_font.data = (void *)old_data; |
3675 |
++ |
3676 |
++ if (userfont) { |
3677 |
++ p->userfont = old_userfont; |
3678 |
++ REFCOUNT(data)--; |
3679 |
++ } |
3680 |
++ |
3681 |
++ vc->vc_font.width = old_width; |
3682 |
++ vc->vc_font.height = old_height; |
3683 |
++ vc->vc_font.charcount = old_charcount; |
3684 |
++ |
3685 |
++ return ret; |
3686 |
+ } |
3687 |
+ |
3688 |
+ /* |
3689 |
+diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c |
3690 |
+index 3369734108af2..e88e8f6f0a334 100644 |
3691 |
+--- a/drivers/xen/privcmd.c |
3692 |
++++ b/drivers/xen/privcmd.c |
3693 |
+@@ -581,27 +581,30 @@ static int lock_pages( |
3694 |
+ struct privcmd_dm_op_buf kbufs[], unsigned int num, |
3695 |
+ struct page *pages[], unsigned int nr_pages, unsigned int *pinned) |
3696 |
+ { |
3697 |
+- unsigned int i; |
3698 |
++ unsigned int i, off = 0; |
3699 |
+ |
3700 |
+- for (i = 0; i < num; i++) { |
3701 |
++ for (i = 0; i < num; ) { |
3702 |
+ unsigned int requested; |
3703 |
+ int page_count; |
3704 |
+ |
3705 |
+ requested = DIV_ROUND_UP( |
3706 |
+ offset_in_page(kbufs[i].uptr) + kbufs[i].size, |
3707 |
+- PAGE_SIZE); |
3708 |
++ PAGE_SIZE) - off; |
3709 |
+ if (requested > nr_pages) |
3710 |
+ return -ENOSPC; |
3711 |
+ |
3712 |
+ page_count = pin_user_pages_fast( |
3713 |
+- (unsigned long) kbufs[i].uptr, |
3714 |
++ (unsigned long)kbufs[i].uptr + off * PAGE_SIZE, |
3715 |
+ requested, FOLL_WRITE, pages); |
3716 |
+- if (page_count < 0) |
3717 |
+- return page_count; |
3718 |
++ if (page_count <= 0) |
3719 |
++ return page_count ? : -EFAULT; |
3720 |
+ |
3721 |
+ *pinned += page_count; |
3722 |
+ nr_pages -= page_count; |
3723 |
+ pages += page_count; |
3724 |
++ |
3725 |
++ off = (requested == page_count) ? 0 : off + page_count; |
3726 |
++ i += !off; |
3727 |
+ } |
3728 |
+ |
3729 |
+ return 0; |
3730 |
+@@ -677,10 +680,8 @@ static long privcmd_ioctl_dm_op(struct file *file, void __user *udata) |
3731 |
+ } |
3732 |
+ |
3733 |
+ rc = lock_pages(kbufs, kdata.num, pages, nr_pages, &pinned); |
3734 |
+- if (rc < 0) { |
3735 |
+- nr_pages = pinned; |
3736 |
++ if (rc < 0) |
3737 |
+ goto out; |
3738 |
+- } |
3739 |
+ |
3740 |
+ for (i = 0; i < kdata.num; i++) { |
3741 |
+ set_xen_guest_handle(xbufs[i].h, kbufs[i].uptr); |
3742 |
+@@ -692,7 +693,7 @@ static long privcmd_ioctl_dm_op(struct file *file, void __user *udata) |
3743 |
+ xen_preemptible_hcall_end(); |
3744 |
+ |
3745 |
+ out: |
3746 |
+- unlock_pages(pages, nr_pages); |
3747 |
++ unlock_pages(pages, pinned); |
3748 |
+ kfree(xbufs); |
3749 |
+ kfree(pages); |
3750 |
+ kfree(kbufs); |
3751 |
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c |
3752 |
+index deaed255f301e..a8ecd83abb11e 100644 |
3753 |
+--- a/fs/btrfs/block-group.c |
3754 |
++++ b/fs/btrfs/block-group.c |
3755 |
+@@ -440,39 +440,26 @@ void btrfs_wait_block_group_cache_progress(struct btrfs_block_group *cache, |
3756 |
+ btrfs_put_caching_control(caching_ctl); |
3757 |
+ } |
3758 |
+ |
3759 |
+-int btrfs_wait_block_group_cache_done(struct btrfs_block_group *cache) |
3760 |
++static int btrfs_caching_ctl_wait_done(struct btrfs_block_group *cache, |
3761 |
++ struct btrfs_caching_control *caching_ctl) |
3762 |
++{ |
3763 |
++ wait_event(caching_ctl->wait, btrfs_block_group_done(cache)); |
3764 |
++ return cache->cached == BTRFS_CACHE_ERROR ? -EIO : 0; |
3765 |
++} |
3766 |
++ |
3767 |
++static int btrfs_wait_block_group_cache_done(struct btrfs_block_group *cache) |
3768 |
+ { |
3769 |
+ struct btrfs_caching_control *caching_ctl; |
3770 |
+- int ret = 0; |
3771 |
++ int ret; |
3772 |
+ |
3773 |
+ caching_ctl = btrfs_get_caching_control(cache); |
3774 |
+ if (!caching_ctl) |
3775 |
+ return (cache->cached == BTRFS_CACHE_ERROR) ? -EIO : 0; |
3776 |
+- |
3777 |
+- wait_event(caching_ctl->wait, btrfs_block_group_done(cache)); |
3778 |
+- if (cache->cached == BTRFS_CACHE_ERROR) |
3779 |
+- ret = -EIO; |
3780 |
++ ret = btrfs_caching_ctl_wait_done(cache, caching_ctl); |
3781 |
+ btrfs_put_caching_control(caching_ctl); |
3782 |
+ return ret; |
3783 |
+ } |
3784 |
+ |
3785 |
+-static bool space_cache_v1_done(struct btrfs_block_group *cache) |
3786 |
+-{ |
3787 |
+- bool ret; |
3788 |
+- |
3789 |
+- spin_lock(&cache->lock); |
3790 |
+- ret = cache->cached != BTRFS_CACHE_FAST; |
3791 |
+- spin_unlock(&cache->lock); |
3792 |
+- |
3793 |
+- return ret; |
3794 |
+-} |
3795 |
+- |
3796 |
+-void btrfs_wait_space_cache_v1_finished(struct btrfs_block_group *cache, |
3797 |
+- struct btrfs_caching_control *caching_ctl) |
3798 |
+-{ |
3799 |
+- wait_event(caching_ctl->wait, space_cache_v1_done(cache)); |
3800 |
+-} |
3801 |
+- |
3802 |
+ #ifdef CONFIG_BTRFS_DEBUG |
3803 |
+ static void fragment_free_space(struct btrfs_block_group *block_group) |
3804 |
+ { |
3805 |
+@@ -750,9 +737,8 @@ done: |
3806 |
+ btrfs_put_block_group(block_group); |
3807 |
+ } |
3808 |
+ |
3809 |
+-int btrfs_cache_block_group(struct btrfs_block_group *cache, int load_cache_only) |
3810 |
++int btrfs_cache_block_group(struct btrfs_block_group *cache, bool wait) |
3811 |
+ { |
3812 |
+- DEFINE_WAIT(wait); |
3813 |
+ struct btrfs_fs_info *fs_info = cache->fs_info; |
3814 |
+ struct btrfs_caching_control *caching_ctl = NULL; |
3815 |
+ int ret = 0; |
3816 |
+@@ -785,10 +771,7 @@ int btrfs_cache_block_group(struct btrfs_block_group *cache, int load_cache_only |
3817 |
+ } |
3818 |
+ WARN_ON(cache->caching_ctl); |
3819 |
+ cache->caching_ctl = caching_ctl; |
3820 |
+- if (btrfs_test_opt(fs_info, SPACE_CACHE)) |
3821 |
+- cache->cached = BTRFS_CACHE_FAST; |
3822 |
+- else |
3823 |
+- cache->cached = BTRFS_CACHE_STARTED; |
3824 |
++ cache->cached = BTRFS_CACHE_STARTED; |
3825 |
+ cache->has_caching_ctl = 1; |
3826 |
+ spin_unlock(&cache->lock); |
3827 |
+ |
3828 |
+@@ -801,8 +784,8 @@ int btrfs_cache_block_group(struct btrfs_block_group *cache, int load_cache_only |
3829 |
+ |
3830 |
+ btrfs_queue_work(fs_info->caching_workers, &caching_ctl->work); |
3831 |
+ out: |
3832 |
+- if (load_cache_only && caching_ctl) |
3833 |
+- btrfs_wait_space_cache_v1_finished(cache, caching_ctl); |
3834 |
++ if (wait && caching_ctl) |
3835 |
++ ret = btrfs_caching_ctl_wait_done(cache, caching_ctl); |
3836 |
+ if (caching_ctl) |
3837 |
+ btrfs_put_caching_control(caching_ctl); |
3838 |
+ |
3839 |
+@@ -3313,7 +3296,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans, |
3840 |
+ * space back to the block group, otherwise we will leak space. |
3841 |
+ */ |
3842 |
+ if (!alloc && !btrfs_block_group_done(cache)) |
3843 |
+- btrfs_cache_block_group(cache, 1); |
3844 |
++ btrfs_cache_block_group(cache, true); |
3845 |
+ |
3846 |
+ byte_in_group = bytenr - cache->start; |
3847 |
+ WARN_ON(byte_in_group > cache->length); |
3848 |
+diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h |
3849 |
+index 35e0e860cc0bf..6b3cdc4cbc41e 100644 |
3850 |
+--- a/fs/btrfs/block-group.h |
3851 |
++++ b/fs/btrfs/block-group.h |
3852 |
+@@ -263,9 +263,7 @@ void btrfs_dec_nocow_writers(struct btrfs_block_group *bg); |
3853 |
+ void btrfs_wait_nocow_writers(struct btrfs_block_group *bg); |
3854 |
+ void btrfs_wait_block_group_cache_progress(struct btrfs_block_group *cache, |
3855 |
+ u64 num_bytes); |
3856 |
+-int btrfs_wait_block_group_cache_done(struct btrfs_block_group *cache); |
3857 |
+-int btrfs_cache_block_group(struct btrfs_block_group *cache, |
3858 |
+- int load_cache_only); |
3859 |
++int btrfs_cache_block_group(struct btrfs_block_group *cache, bool wait); |
3860 |
+ void btrfs_put_caching_control(struct btrfs_caching_control *ctl); |
3861 |
+ struct btrfs_caching_control *btrfs_get_caching_control( |
3862 |
+ struct btrfs_block_group *cache); |
3863 |
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h |
3864 |
+index 3a51d0c13a957..7d3ca3ea0bcec 100644 |
3865 |
+--- a/fs/btrfs/ctree.h |
3866 |
++++ b/fs/btrfs/ctree.h |
3867 |
+@@ -494,7 +494,6 @@ struct btrfs_free_cluster { |
3868 |
+ enum btrfs_caching_type { |
3869 |
+ BTRFS_CACHE_NO, |
3870 |
+ BTRFS_CACHE_STARTED, |
3871 |
+- BTRFS_CACHE_FAST, |
3872 |
+ BTRFS_CACHE_FINISHED, |
3873 |
+ BTRFS_CACHE_ERROR, |
3874 |
+ }; |
3875 |
+diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c |
3876 |
+index a7dd6ba25e990..c0f358b958abd 100644 |
3877 |
+--- a/fs/btrfs/dev-replace.c |
3878 |
++++ b/fs/btrfs/dev-replace.c |
3879 |
+@@ -165,7 +165,7 @@ no_valid_dev_replace_entry_found: |
3880 |
+ */ |
3881 |
+ if (btrfs_find_device(fs_info->fs_devices, &args)) { |
3882 |
+ btrfs_err(fs_info, |
3883 |
+- "replace devid present without an active replace item"); |
3884 |
++"replace without active item, run 'device scan --forget' on the target device"); |
3885 |
+ ret = -EUCLEAN; |
3886 |
+ } else { |
3887 |
+ dev_replace->srcdev = NULL; |
3888 |
+@@ -1128,8 +1128,7 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info) |
3889 |
+ up_write(&dev_replace->rwsem); |
3890 |
+ |
3891 |
+ /* Scrub for replace must not be running in suspended state */ |
3892 |
+- ret = btrfs_scrub_cancel(fs_info); |
3893 |
+- ASSERT(ret != -ENOTCONN); |
3894 |
++ btrfs_scrub_cancel(fs_info); |
3895 |
+ |
3896 |
+ trans = btrfs_start_transaction(root, 0); |
3897 |
+ if (IS_ERR(trans)) { |
3898 |
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c |
3899 |
+index f2c79838ebe52..ced3fc76063f1 100644 |
3900 |
+--- a/fs/btrfs/extent-tree.c |
3901 |
++++ b/fs/btrfs/extent-tree.c |
3902 |
+@@ -2567,17 +2567,10 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans, |
3903 |
+ return -EINVAL; |
3904 |
+ |
3905 |
+ /* |
3906 |
+- * pull in the free space cache (if any) so that our pin |
3907 |
+- * removes the free space from the cache. We have load_only set |
3908 |
+- * to one because the slow code to read in the free extents does check |
3909 |
+- * the pinned extents. |
3910 |
++ * Fully cache the free space first so that our pin removes the free space |
3911 |
++ * from the cache. |
3912 |
+ */ |
3913 |
+- btrfs_cache_block_group(cache, 1); |
3914 |
+- /* |
3915 |
+- * Make sure we wait until the cache is completely built in case it is |
3916 |
+- * missing or is invalid and therefore needs to be rebuilt. |
3917 |
+- */ |
3918 |
+- ret = btrfs_wait_block_group_cache_done(cache); |
3919 |
++ ret = btrfs_cache_block_group(cache, true); |
3920 |
+ if (ret) |
3921 |
+ goto out; |
3922 |
+ |
3923 |
+@@ -2600,12 +2593,7 @@ static int __exclude_logged_extent(struct btrfs_fs_info *fs_info, |
3924 |
+ if (!block_group) |
3925 |
+ return -EINVAL; |
3926 |
+ |
3927 |
+- btrfs_cache_block_group(block_group, 1); |
3928 |
+- /* |
3929 |
+- * Make sure we wait until the cache is completely built in case it is |
3930 |
+- * missing or is invalid and therefore needs to be rebuilt. |
3931 |
+- */ |
3932 |
+- ret = btrfs_wait_block_group_cache_done(block_group); |
3933 |
++ ret = btrfs_cache_block_group(block_group, true); |
3934 |
+ if (ret) |
3935 |
+ goto out; |
3936 |
+ |
3937 |
+@@ -4415,7 +4403,7 @@ have_block_group: |
3938 |
+ ffe_ctl->cached = btrfs_block_group_done(block_group); |
3939 |
+ if (unlikely(!ffe_ctl->cached)) { |
3940 |
+ ffe_ctl->have_caching_bg = true; |
3941 |
+- ret = btrfs_cache_block_group(block_group, 0); |
3942 |
++ ret = btrfs_cache_block_group(block_group, false); |
3943 |
+ |
3944 |
+ /* |
3945 |
+ * If we get ENOMEM here or something else we want to |
3946 |
+@@ -6169,13 +6157,7 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) |
3947 |
+ |
3948 |
+ if (end - start >= range->minlen) { |
3949 |
+ if (!btrfs_block_group_done(cache)) { |
3950 |
+- ret = btrfs_cache_block_group(cache, 0); |
3951 |
+- if (ret) { |
3952 |
+- bg_failed++; |
3953 |
+- bg_ret = ret; |
3954 |
+- continue; |
3955 |
+- } |
3956 |
+- ret = btrfs_wait_block_group_cache_done(cache); |
3957 |
++ ret = btrfs_cache_block_group(cache, true); |
3958 |
+ if (ret) { |
3959 |
+ bg_failed++; |
3960 |
+ bg_ret = ret; |
3961 |
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c |
3962 |
+index 89c6d7ff19874..78df9b8557ddd 100644 |
3963 |
+--- a/fs/btrfs/file.c |
3964 |
++++ b/fs/btrfs/file.c |
3965 |
+@@ -2483,6 +2483,7 @@ static int fill_holes(struct btrfs_trans_handle *trans, |
3966 |
+ btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes); |
3967 |
+ btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes); |
3968 |
+ btrfs_set_file_extent_offset(leaf, fi, 0); |
3969 |
++ btrfs_set_file_extent_generation(leaf, fi, trans->transid); |
3970 |
+ btrfs_mark_buffer_dirty(leaf); |
3971 |
+ goto out; |
3972 |
+ } |
3973 |
+@@ -2499,6 +2500,7 @@ static int fill_holes(struct btrfs_trans_handle *trans, |
3974 |
+ btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes); |
3975 |
+ btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes); |
3976 |
+ btrfs_set_file_extent_offset(leaf, fi, 0); |
3977 |
++ btrfs_set_file_extent_generation(leaf, fi, trans->transid); |
3978 |
+ btrfs_mark_buffer_dirty(leaf); |
3979 |
+ goto out; |
3980 |
+ } |
3981 |
+diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c |
3982 |
+index a64b26b169040..d647cb2938c01 100644 |
3983 |
+--- a/fs/btrfs/root-tree.c |
3984 |
++++ b/fs/btrfs/root-tree.c |
3985 |
+@@ -349,9 +349,10 @@ int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id, |
3986 |
+ key.offset = ref_id; |
3987 |
+ again: |
3988 |
+ ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); |
3989 |
+- if (ret < 0) |
3990 |
++ if (ret < 0) { |
3991 |
++ err = ret; |
3992 |
+ goto out; |
3993 |
+- if (ret == 0) { |
3994 |
++ } else if (ret == 0) { |
3995 |
+ leaf = path->nodes[0]; |
3996 |
+ ref = btrfs_item_ptr(leaf, path->slots[0], |
3997 |
+ struct btrfs_root_ref); |
3998 |
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c |
3999 |
+index 9cd9d06f54699..3460fd6743807 100644 |
4000 |
+--- a/fs/btrfs/volumes.c |
4001 |
++++ b/fs/btrfs/volumes.c |
4002 |
+@@ -2344,8 +2344,11 @@ int btrfs_get_dev_args_from_path(struct btrfs_fs_info *fs_info, |
4003 |
+ |
4004 |
+ ret = btrfs_get_bdev_and_sb(path, FMODE_READ, fs_info->bdev_holder, 0, |
4005 |
+ &bdev, &disk_super); |
4006 |
+- if (ret) |
4007 |
++ if (ret) { |
4008 |
++ btrfs_put_dev_args_from_path(args); |
4009 |
+ return ret; |
4010 |
++ } |
4011 |
++ |
4012 |
+ args->devid = btrfs_stack_device_id(&disk_super->dev_item); |
4013 |
+ memcpy(args->uuid, disk_super->dev_item.uuid, BTRFS_UUID_SIZE); |
4014 |
+ if (btrfs_fs_incompat(fs_info, METADATA_UUID)) |
4015 |
+diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c |
4016 |
+index 7421abcf325a5..5bb8d8c863119 100644 |
4017 |
+--- a/fs/btrfs/xattr.c |
4018 |
++++ b/fs/btrfs/xattr.c |
4019 |
+@@ -371,6 +371,9 @@ static int btrfs_xattr_handler_set(const struct xattr_handler *handler, |
4020 |
+ const char *name, const void *buffer, |
4021 |
+ size_t size, int flags) |
4022 |
+ { |
4023 |
++ if (btrfs_root_readonly(BTRFS_I(inode)->root)) |
4024 |
++ return -EROFS; |
4025 |
++ |
4026 |
+ name = xattr_full_name(handler, name); |
4027 |
+ return btrfs_setxattr_trans(inode, name, buffer, size, flags); |
4028 |
+ } |
4029 |
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c |
4030 |
+index aa4c1d403708f..3898ec2632dc4 100644 |
4031 |
+--- a/fs/cifs/smb2ops.c |
4032 |
++++ b/fs/cifs/smb2ops.c |
4033 |
+@@ -3671,7 +3671,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, |
4034 |
+ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, |
4035 |
+ loff_t offset, loff_t len) |
4036 |
+ { |
4037 |
+- struct inode *inode; |
4038 |
++ struct inode *inode = file_inode(file); |
4039 |
+ struct cifsFileInfo *cfile = file->private_data; |
4040 |
+ struct file_zero_data_information fsctl_buf; |
4041 |
+ long rc; |
4042 |
+@@ -3680,14 +3680,12 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, |
4043 |
+ |
4044 |
+ xid = get_xid(); |
4045 |
+ |
4046 |
+- inode = d_inode(cfile->dentry); |
4047 |
+- |
4048 |
++ inode_lock(inode); |
4049 |
+ /* Need to make file sparse, if not already, before freeing range. */ |
4050 |
+ /* Consider adding equivalent for compressed since it could also work */ |
4051 |
+ if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse)) { |
4052 |
+ rc = -EOPNOTSUPP; |
4053 |
+- free_xid(xid); |
4054 |
+- return rc; |
4055 |
++ goto out; |
4056 |
+ } |
4057 |
+ |
4058 |
+ filemap_invalidate_lock(inode->i_mapping); |
4059 |
+@@ -3707,8 +3705,10 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, |
4060 |
+ true /* is_fctl */, (char *)&fsctl_buf, |
4061 |
+ sizeof(struct file_zero_data_information), |
4062 |
+ CIFSMaxBufSize, NULL, NULL); |
4063 |
+- free_xid(xid); |
4064 |
+ filemap_invalidate_unlock(inode->i_mapping); |
4065 |
++out: |
4066 |
++ inode_unlock(inode); |
4067 |
++ free_xid(xid); |
4068 |
+ return rc; |
4069 |
+ } |
4070 |
+ |
4071 |
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c |
4072 |
+index c705de32e2257..c7614ade875b5 100644 |
4073 |
+--- a/fs/cifs/smb2pdu.c |
4074 |
++++ b/fs/cifs/smb2pdu.c |
4075 |
+@@ -2571,19 +2571,15 @@ alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len, |
4076 |
+ |
4077 |
+ path_len = UniStrnlen((wchar_t *)path, PATH_MAX); |
4078 |
+ |
4079 |
+- /* |
4080 |
+- * make room for one path separator between the treename and |
4081 |
+- * path |
4082 |
+- */ |
4083 |
+- *out_len = treename_len + 1 + path_len; |
4084 |
++ /* make room for one path separator only if @path isn't empty */ |
4085 |
++ *out_len = treename_len + (path[0] ? 1 : 0) + path_len; |
4086 |
+ |
4087 |
+ /* |
4088 |
+- * final path needs to be null-terminated UTF16 with a |
4089 |
+- * size aligned to 8 |
4090 |
++ * final path needs to be 8-byte aligned as specified in |
4091 |
++ * MS-SMB2 2.2.13 SMB2 CREATE Request. |
4092 |
+ */ |
4093 |
+- |
4094 |
+- *out_size = roundup((*out_len+1)*2, 8); |
4095 |
+- *out_path = kzalloc(*out_size, GFP_KERNEL); |
4096 |
++ *out_size = roundup(*out_len * sizeof(__le16), 8); |
4097 |
++ *out_path = kzalloc(*out_size + sizeof(__le16) /* null */, GFP_KERNEL); |
4098 |
+ if (!*out_path) |
4099 |
+ return -ENOMEM; |
4100 |
+ |
4101 |
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c |
4102 |
+index 05221366a16dc..08a1993ab7fd3 100644 |
4103 |
+--- a/fs/fs-writeback.c |
4104 |
++++ b/fs/fs-writeback.c |
4105 |
+@@ -134,10 +134,10 @@ static bool inode_io_list_move_locked(struct inode *inode, |
4106 |
+ |
4107 |
+ static void wb_wakeup(struct bdi_writeback *wb) |
4108 |
+ { |
4109 |
+- spin_lock_bh(&wb->work_lock); |
4110 |
++ spin_lock_irq(&wb->work_lock); |
4111 |
+ if (test_bit(WB_registered, &wb->state)) |
4112 |
+ mod_delayed_work(bdi_wq, &wb->dwork, 0); |
4113 |
+- spin_unlock_bh(&wb->work_lock); |
4114 |
++ spin_unlock_irq(&wb->work_lock); |
4115 |
+ } |
4116 |
+ |
4117 |
+ static void finish_writeback_work(struct bdi_writeback *wb, |
4118 |
+@@ -164,7 +164,7 @@ static void wb_queue_work(struct bdi_writeback *wb, |
4119 |
+ if (work->done) |
4120 |
+ atomic_inc(&work->done->cnt); |
4121 |
+ |
4122 |
+- spin_lock_bh(&wb->work_lock); |
4123 |
++ spin_lock_irq(&wb->work_lock); |
4124 |
+ |
4125 |
+ if (test_bit(WB_registered, &wb->state)) { |
4126 |
+ list_add_tail(&work->list, &wb->work_list); |
4127 |
+@@ -172,7 +172,7 @@ static void wb_queue_work(struct bdi_writeback *wb, |
4128 |
+ } else |
4129 |
+ finish_writeback_work(wb, work); |
4130 |
+ |
4131 |
+- spin_unlock_bh(&wb->work_lock); |
4132 |
++ spin_unlock_irq(&wb->work_lock); |
4133 |
+ } |
4134 |
+ |
4135 |
+ /** |
4136 |
+@@ -2082,13 +2082,13 @@ static struct wb_writeback_work *get_next_work_item(struct bdi_writeback *wb) |
4137 |
+ { |
4138 |
+ struct wb_writeback_work *work = NULL; |
4139 |
+ |
4140 |
+- spin_lock_bh(&wb->work_lock); |
4141 |
++ spin_lock_irq(&wb->work_lock); |
4142 |
+ if (!list_empty(&wb->work_list)) { |
4143 |
+ work = list_entry(wb->work_list.next, |
4144 |
+ struct wb_writeback_work, list); |
4145 |
+ list_del_init(&work->list); |
4146 |
+ } |
4147 |
+- spin_unlock_bh(&wb->work_lock); |
4148 |
++ spin_unlock_irq(&wb->work_lock); |
4149 |
+ return work; |
4150 |
+ } |
4151 |
+ |
4152 |
+diff --git a/fs/namespace.c b/fs/namespace.c |
4153 |
+index e6a7e769d25dd..a59f8d645654a 100644 |
4154 |
+--- a/fs/namespace.c |
4155 |
++++ b/fs/namespace.c |
4156 |
+@@ -4238,6 +4238,13 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize, |
4157 |
+ err = -EPERM; |
4158 |
+ goto out_fput; |
4159 |
+ } |
4160 |
++ |
4161 |
++ /* We're not controlling the target namespace. */ |
4162 |
++ if (!ns_capable(mnt_userns, CAP_SYS_ADMIN)) { |
4163 |
++ err = -EPERM; |
4164 |
++ goto out_fput; |
4165 |
++ } |
4166 |
++ |
4167 |
+ kattr->mnt_userns = get_user_ns(mnt_userns); |
4168 |
+ |
4169 |
+ out_fput: |
4170 |
+diff --git a/fs/nfs/file.c b/fs/nfs/file.c |
4171 |
+index 2d72b1b7ed74c..9a0e4a89cdf14 100644 |
4172 |
+--- a/fs/nfs/file.c |
4173 |
++++ b/fs/nfs/file.c |
4174 |
+@@ -221,8 +221,10 @@ nfs_file_fsync_commit(struct file *file, int datasync) |
4175 |
+ int |
4176 |
+ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) |
4177 |
+ { |
4178 |
+- struct nfs_open_context *ctx = nfs_file_open_context(file); |
4179 |
+ struct inode *inode = file_inode(file); |
4180 |
++ struct nfs_inode *nfsi = NFS_I(inode); |
4181 |
++ long save_nredirtied = atomic_long_read(&nfsi->redirtied_pages); |
4182 |
++ long nredirtied; |
4183 |
+ int ret; |
4184 |
+ |
4185 |
+ trace_nfs_fsync_enter(inode); |
4186 |
+@@ -237,15 +239,10 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) |
4187 |
+ ret = pnfs_sync_inode(inode, !!datasync); |
4188 |
+ if (ret != 0) |
4189 |
+ break; |
4190 |
+- if (!test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags)) |
4191 |
++ nredirtied = atomic_long_read(&nfsi->redirtied_pages); |
4192 |
++ if (nredirtied == save_nredirtied) |
4193 |
+ break; |
4194 |
+- /* |
4195 |
+- * If nfs_file_fsync_commit detected a server reboot, then |
4196 |
+- * resend all dirty pages that might have been covered by |
4197 |
+- * the NFS_CONTEXT_RESEND_WRITES flag |
4198 |
+- */ |
4199 |
+- start = 0; |
4200 |
+- end = LLONG_MAX; |
4201 |
++ save_nredirtied = nredirtied; |
4202 |
+ } |
4203 |
+ |
4204 |
+ trace_nfs_fsync_exit(inode, ret); |
4205 |
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c |
4206 |
+index b4e46b0ffa2dc..bea7c005119c3 100644 |
4207 |
+--- a/fs/nfs/inode.c |
4208 |
++++ b/fs/nfs/inode.c |
4209 |
+@@ -426,6 +426,7 @@ nfs_ilookup(struct super_block *sb, struct nfs_fattr *fattr, struct nfs_fh *fh) |
4210 |
+ static void nfs_inode_init_regular(struct nfs_inode *nfsi) |
4211 |
+ { |
4212 |
+ atomic_long_set(&nfsi->nrequests, 0); |
4213 |
++ atomic_long_set(&nfsi->redirtied_pages, 0); |
4214 |
+ INIT_LIST_HEAD(&nfsi->commit_info.list); |
4215 |
+ atomic_long_set(&nfsi->commit_info.ncommit, 0); |
4216 |
+ atomic_set(&nfsi->commit_info.rpcs_out, 0); |
4217 |
+diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c |
4218 |
+index e88f6b18445ec..9eb1812878795 100644 |
4219 |
+--- a/fs/nfs/nfs4file.c |
4220 |
++++ b/fs/nfs/nfs4file.c |
4221 |
+@@ -340,6 +340,11 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt, |
4222 |
+ goto out; |
4223 |
+ } |
4224 |
+ |
4225 |
++ if (!S_ISREG(fattr->mode)) { |
4226 |
++ res = ERR_PTR(-EBADF); |
4227 |
++ goto out; |
4228 |
++ } |
4229 |
++ |
4230 |
+ res = ERR_PTR(-ENOMEM); |
4231 |
+ len = strlen(SSC_READ_NAME_BODY) + 16; |
4232 |
+ read_name = kzalloc(len, GFP_KERNEL); |
4233 |
+@@ -357,6 +362,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt, |
4234 |
+ r_ino->i_fop); |
4235 |
+ if (IS_ERR(filep)) { |
4236 |
+ res = ERR_CAST(filep); |
4237 |
++ iput(r_ino); |
4238 |
+ goto out_free_name; |
4239 |
+ } |
4240 |
+ |
4241 |
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c |
4242 |
+index 1c706465d090b..5d7e1c2061842 100644 |
4243 |
+--- a/fs/nfs/write.c |
4244 |
++++ b/fs/nfs/write.c |
4245 |
+@@ -1419,10 +1419,12 @@ static void nfs_initiate_write(struct nfs_pgio_header *hdr, |
4246 |
+ */ |
4247 |
+ static void nfs_redirty_request(struct nfs_page *req) |
4248 |
+ { |
4249 |
++ struct nfs_inode *nfsi = NFS_I(page_file_mapping(req->wb_page)->host); |
4250 |
++ |
4251 |
+ /* Bump the transmission count */ |
4252 |
+ req->wb_nio++; |
4253 |
+ nfs_mark_request_dirty(req); |
4254 |
+- set_bit(NFS_CONTEXT_RESEND_WRITES, &nfs_req_openctx(req)->flags); |
4255 |
++ atomic_long_inc(&nfsi->redirtied_pages); |
4256 |
+ nfs_end_page_writeback(req); |
4257 |
+ nfs_release_request(req); |
4258 |
+ } |
4259 |
+@@ -1892,7 +1894,7 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data) |
4260 |
+ /* We have a mismatch. Write the page again */ |
4261 |
+ dprintk_cont(" mismatch\n"); |
4262 |
+ nfs_mark_request_dirty(req); |
4263 |
+- set_bit(NFS_CONTEXT_RESEND_WRITES, &nfs_req_openctx(req)->flags); |
4264 |
++ atomic_long_inc(&NFS_I(data->inode)->redirtied_pages); |
4265 |
+ next: |
4266 |
+ nfs_unlock_and_release_request(req); |
4267 |
+ /* Latency breaker */ |
4268 |
+diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c |
4269 |
+index 1b8c89dbf6684..3629049decac1 100644 |
4270 |
+--- a/fs/ntfs3/xattr.c |
4271 |
++++ b/fs/ntfs3/xattr.c |
4272 |
+@@ -478,8 +478,7 @@ out: |
4273 |
+ } |
4274 |
+ |
4275 |
+ #ifdef CONFIG_NTFS3_FS_POSIX_ACL |
4276 |
+-static struct posix_acl *ntfs_get_acl_ex(struct user_namespace *mnt_userns, |
4277 |
+- struct inode *inode, int type, |
4278 |
++static struct posix_acl *ntfs_get_acl_ex(struct inode *inode, int type, |
4279 |
+ int locked) |
4280 |
+ { |
4281 |
+ struct ntfs_inode *ni = ntfs_i(inode); |
4282 |
+@@ -514,7 +513,7 @@ static struct posix_acl *ntfs_get_acl_ex(struct user_namespace *mnt_userns, |
4283 |
+ |
4284 |
+ /* Translate extended attribute to acl. */ |
4285 |
+ if (err >= 0) { |
4286 |
+- acl = posix_acl_from_xattr(mnt_userns, buf, err); |
4287 |
++ acl = posix_acl_from_xattr(&init_user_ns, buf, err); |
4288 |
+ } else if (err == -ENODATA) { |
4289 |
+ acl = NULL; |
4290 |
+ } else { |
4291 |
+@@ -537,8 +536,7 @@ struct posix_acl *ntfs_get_acl(struct inode *inode, int type, bool rcu) |
4292 |
+ if (rcu) |
4293 |
+ return ERR_PTR(-ECHILD); |
4294 |
+ |
4295 |
+- /* TODO: init_user_ns? */ |
4296 |
+- return ntfs_get_acl_ex(&init_user_ns, inode, type, 0); |
4297 |
++ return ntfs_get_acl_ex(inode, type, 0); |
4298 |
+ } |
4299 |
+ |
4300 |
+ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns, |
4301 |
+@@ -590,7 +588,7 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns, |
4302 |
+ value = kmalloc(size, GFP_NOFS); |
4303 |
+ if (!value) |
4304 |
+ return -ENOMEM; |
4305 |
+- err = posix_acl_to_xattr(mnt_userns, acl, value, size); |
4306 |
++ err = posix_acl_to_xattr(&init_user_ns, acl, value, size); |
4307 |
+ if (err < 0) |
4308 |
+ goto out; |
4309 |
+ flags = 0; |
4310 |
+@@ -641,7 +639,7 @@ static int ntfs_xattr_get_acl(struct user_namespace *mnt_userns, |
4311 |
+ if (!acl) |
4312 |
+ return -ENODATA; |
4313 |
+ |
4314 |
+- err = posix_acl_to_xattr(mnt_userns, acl, buffer, size); |
4315 |
++ err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
4316 |
+ posix_acl_release(acl); |
4317 |
+ |
4318 |
+ return err; |
4319 |
+@@ -665,12 +663,12 @@ static int ntfs_xattr_set_acl(struct user_namespace *mnt_userns, |
4320 |
+ if (!value) { |
4321 |
+ acl = NULL; |
4322 |
+ } else { |
4323 |
+- acl = posix_acl_from_xattr(mnt_userns, value, size); |
4324 |
++ acl = posix_acl_from_xattr(&init_user_ns, value, size); |
4325 |
+ if (IS_ERR(acl)) |
4326 |
+ return PTR_ERR(acl); |
4327 |
+ |
4328 |
+ if (acl) { |
4329 |
+- err = posix_acl_valid(mnt_userns, acl); |
4330 |
++ err = posix_acl_valid(&init_user_ns, acl); |
4331 |
+ if (err) |
4332 |
+ goto release_and_out; |
4333 |
+ } |
4334 |
+diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c |
4335 |
+index 801e60bab9555..c28bc983a7b1c 100644 |
4336 |
+--- a/fs/ocfs2/dlmglue.c |
4337 |
++++ b/fs/ocfs2/dlmglue.c |
4338 |
+@@ -3403,10 +3403,12 @@ void ocfs2_dlm_shutdown(struct ocfs2_super *osb, |
4339 |
+ ocfs2_lock_res_free(&osb->osb_nfs_sync_lockres); |
4340 |
+ ocfs2_lock_res_free(&osb->osb_orphan_scan.os_lockres); |
4341 |
+ |
4342 |
+- ocfs2_cluster_disconnect(osb->cconn, hangup_pending); |
4343 |
+- osb->cconn = NULL; |
4344 |
++ if (osb->cconn) { |
4345 |
++ ocfs2_cluster_disconnect(osb->cconn, hangup_pending); |
4346 |
++ osb->cconn = NULL; |
4347 |
+ |
4348 |
+- ocfs2_dlm_shutdown_debug(osb); |
4349 |
++ ocfs2_dlm_shutdown_debug(osb); |
4350 |
++ } |
4351 |
+ } |
4352 |
+ |
4353 |
+ static int ocfs2_drop_lock(struct ocfs2_super *osb, |
4354 |
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c |
4355 |
+index 438be028935d2..bc18c27e96830 100644 |
4356 |
+--- a/fs/ocfs2/super.c |
4357 |
++++ b/fs/ocfs2/super.c |
4358 |
+@@ -1914,8 +1914,7 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) |
4359 |
+ !ocfs2_is_hard_readonly(osb)) |
4360 |
+ hangup_needed = 1; |
4361 |
+ |
4362 |
+- if (osb->cconn) |
4363 |
+- ocfs2_dlm_shutdown(osb, hangup_needed); |
4364 |
++ ocfs2_dlm_shutdown(osb, hangup_needed); |
4365 |
+ |
4366 |
+ ocfs2_blockcheck_stats_debugfs_remove(&osb->osb_ecc_stats); |
4367 |
+ debugfs_remove_recursive(osb->osb_debug_root); |
4368 |
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c |
4369 |
+index 2d04e3470d4cd..313788bc0c307 100644 |
4370 |
+--- a/fs/proc/task_mmu.c |
4371 |
++++ b/fs/proc/task_mmu.c |
4372 |
+@@ -525,10 +525,12 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr, |
4373 |
+ struct vm_area_struct *vma = walk->vma; |
4374 |
+ bool locked = !!(vma->vm_flags & VM_LOCKED); |
4375 |
+ struct page *page = NULL; |
4376 |
+- bool migration = false; |
4377 |
++ bool migration = false, young = false, dirty = false; |
4378 |
+ |
4379 |
+ if (pte_present(*pte)) { |
4380 |
+ page = vm_normal_page(vma, addr, *pte); |
4381 |
++ young = pte_young(*pte); |
4382 |
++ dirty = pte_dirty(*pte); |
4383 |
+ } else if (is_swap_pte(*pte)) { |
4384 |
+ swp_entry_t swpent = pte_to_swp_entry(*pte); |
4385 |
+ |
4386 |
+@@ -558,8 +560,7 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr, |
4387 |
+ if (!page) |
4388 |
+ return; |
4389 |
+ |
4390 |
+- smaps_account(mss, page, false, pte_young(*pte), pte_dirty(*pte), |
4391 |
+- locked, migration); |
4392 |
++ smaps_account(mss, page, false, young, dirty, locked, migration); |
4393 |
+ } |
4394 |
+ |
4395 |
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
4396 |
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c |
4397 |
+index de86f5b2859f9..ab0576d372d6e 100644 |
4398 |
+--- a/fs/userfaultfd.c |
4399 |
++++ b/fs/userfaultfd.c |
4400 |
+@@ -1601,6 +1601,10 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, |
4401 |
+ wake_userfault(vma->vm_userfaultfd_ctx.ctx, &range); |
4402 |
+ } |
4403 |
+ |
4404 |
++ /* Reset ptes for the whole vma range if wr-protected */ |
4405 |
++ if (userfaultfd_wp(vma)) |
4406 |
++ uffd_wp_range(mm, vma, start, vma_end - start, false); |
4407 |
++ |
4408 |
+ new_flags = vma->vm_flags & ~__VM_UFFD_FLAGS; |
4409 |
+ prev = vma_merge(mm, prev, start, vma_end, new_flags, |
4410 |
+ vma->anon_vma, vma->vm_file, vma->vm_pgoff, |
4411 |
+diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h |
4412 |
+index d0f7bdd2fdf23..db13bb620f527 100644 |
4413 |
+--- a/include/asm-generic/sections.h |
4414 |
++++ b/include/asm-generic/sections.h |
4415 |
+@@ -97,7 +97,7 @@ static inline bool memory_contains(void *begin, void *end, void *virt, |
4416 |
+ /** |
4417 |
+ * memory_intersects - checks if the region occupied by an object intersects |
4418 |
+ * with another memory region |
4419 |
+- * @begin: virtual address of the beginning of the memory regien |
4420 |
++ * @begin: virtual address of the beginning of the memory region |
4421 |
+ * @end: virtual address of the end of the memory region |
4422 |
+ * @virt: virtual address of the memory object |
4423 |
+ * @size: size of the memory object |
4424 |
+@@ -110,7 +110,10 @@ static inline bool memory_intersects(void *begin, void *end, void *virt, |
4425 |
+ { |
4426 |
+ void *vend = virt + size; |
4427 |
+ |
4428 |
+- return (virt >= begin && virt < end) || (vend >= begin && vend < end); |
4429 |
++ if (virt < end && vend > begin) |
4430 |
++ return true; |
4431 |
++ |
4432 |
++ return false; |
4433 |
+ } |
4434 |
+ |
4435 |
+ /** |
4436 |
+diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h |
4437 |
+index 9ecead1042b9c..c322b98260f52 100644 |
4438 |
+--- a/include/linux/memcontrol.h |
4439 |
++++ b/include/linux/memcontrol.h |
4440 |
+@@ -978,19 +978,30 @@ static inline void mod_memcg_page_state(struct page *page, |
4441 |
+ |
4442 |
+ static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, int idx) |
4443 |
+ { |
4444 |
+- return READ_ONCE(memcg->vmstats.state[idx]); |
4445 |
++ long x = READ_ONCE(memcg->vmstats.state[idx]); |
4446 |
++#ifdef CONFIG_SMP |
4447 |
++ if (x < 0) |
4448 |
++ x = 0; |
4449 |
++#endif |
4450 |
++ return x; |
4451 |
+ } |
4452 |
+ |
4453 |
+ static inline unsigned long lruvec_page_state(struct lruvec *lruvec, |
4454 |
+ enum node_stat_item idx) |
4455 |
+ { |
4456 |
+ struct mem_cgroup_per_node *pn; |
4457 |
++ long x; |
4458 |
+ |
4459 |
+ if (mem_cgroup_disabled()) |
4460 |
+ return node_page_state(lruvec_pgdat(lruvec), idx); |
4461 |
+ |
4462 |
+ pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec); |
4463 |
+- return READ_ONCE(pn->lruvec_stats.state[idx]); |
4464 |
++ x = READ_ONCE(pn->lruvec_stats.state[idx]); |
4465 |
++#ifdef CONFIG_SMP |
4466 |
++ if (x < 0) |
4467 |
++ x = 0; |
4468 |
++#endif |
4469 |
++ return x; |
4470 |
+ } |
4471 |
+ |
4472 |
+ static inline unsigned long lruvec_page_state_local(struct lruvec *lruvec, |
4473 |
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h |
4474 |
+index 5040cd774c5a3..b0b4ac92354a2 100644 |
4475 |
+--- a/include/linux/mlx5/driver.h |
4476 |
++++ b/include/linux/mlx5/driver.h |
4477 |
+@@ -773,6 +773,7 @@ struct mlx5_core_dev { |
4478 |
+ enum mlx5_device_state state; |
4479 |
+ /* sync interface state */ |
4480 |
+ struct mutex intf_state_mutex; |
4481 |
++ struct lock_class_key lock_key; |
4482 |
+ unsigned long intf_state; |
4483 |
+ struct mlx5_priv priv; |
4484 |
+ struct mlx5_profile profile; |
4485 |
+diff --git a/include/linux/mm.h b/include/linux/mm.h |
4486 |
+index 7898e29bcfb54..25b8860f47cc6 100644 |
4487 |
+--- a/include/linux/mm.h |
4488 |
++++ b/include/linux/mm.h |
4489 |
+@@ -2939,7 +2939,6 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, |
4490 |
+ #define FOLL_MIGRATION 0x400 /* wait for page to replace migration entry */ |
4491 |
+ #define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */ |
4492 |
+ #define FOLL_REMOTE 0x2000 /* we are working on non-current tsk/mm */ |
4493 |
+-#define FOLL_COW 0x4000 /* internal GUP flag */ |
4494 |
+ #define FOLL_ANON 0x8000 /* don't do file mappings */ |
4495 |
+ #define FOLL_LONGTERM 0x10000 /* mapping lifetime is indefinite: see below */ |
4496 |
+ #define FOLL_SPLIT_PMD 0x20000 /* split huge pmd before returning */ |
4497 |
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h |
4498 |
+index 2563d30736e9a..db40bc62213bd 100644 |
4499 |
+--- a/include/linux/netdevice.h |
4500 |
++++ b/include/linux/netdevice.h |
4501 |
+@@ -640,9 +640,23 @@ extern int sysctl_devconf_inherit_init_net; |
4502 |
+ */ |
4503 |
+ static inline bool net_has_fallback_tunnels(const struct net *net) |
4504 |
+ { |
4505 |
+- return !IS_ENABLED(CONFIG_SYSCTL) || |
4506 |
+- !sysctl_fb_tunnels_only_for_init_net || |
4507 |
+- (net == &init_net && sysctl_fb_tunnels_only_for_init_net == 1); |
4508 |
++#if IS_ENABLED(CONFIG_SYSCTL) |
4509 |
++ int fb_tunnels_only_for_init_net = READ_ONCE(sysctl_fb_tunnels_only_for_init_net); |
4510 |
++ |
4511 |
++ return !fb_tunnels_only_for_init_net || |
4512 |
++ (net_eq(net, &init_net) && fb_tunnels_only_for_init_net == 1); |
4513 |
++#else |
4514 |
++ return true; |
4515 |
++#endif |
4516 |
++} |
4517 |
++ |
4518 |
++static inline int net_inherit_devconf(void) |
4519 |
++{ |
4520 |
++#if IS_ENABLED(CONFIG_SYSCTL) |
4521 |
++ return READ_ONCE(sysctl_devconf_inherit_init_net); |
4522 |
++#else |
4523 |
++ return 0; |
4524 |
++#endif |
4525 |
+ } |
4526 |
+ |
4527 |
+ static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) |
4528 |
+diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h |
4529 |
+index a13296d6c7ceb..fd533552a062c 100644 |
4530 |
+--- a/include/linux/netfilter_bridge/ebtables.h |
4531 |
++++ b/include/linux/netfilter_bridge/ebtables.h |
4532 |
+@@ -94,10 +94,6 @@ struct ebt_table { |
4533 |
+ struct ebt_replace_kernel *table; |
4534 |
+ unsigned int valid_hooks; |
4535 |
+ rwlock_t lock; |
4536 |
+- /* e.g. could be the table explicitly only allows certain |
4537 |
+- * matches, targets, ... 0 == let it in */ |
4538 |
+- int (*check)(const struct ebt_table_info *info, |
4539 |
+- unsigned int valid_hooks); |
4540 |
+ /* the data used by the kernel */ |
4541 |
+ struct ebt_table_info *private; |
4542 |
+ struct nf_hook_ops *ops; |
4543 |
+diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h |
4544 |
+index a17c337dbdf1d..b1f83697699ee 100644 |
4545 |
+--- a/include/linux/nfs_fs.h |
4546 |
++++ b/include/linux/nfs_fs.h |
4547 |
+@@ -182,6 +182,7 @@ struct nfs_inode { |
4548 |
+ /* Regular file */ |
4549 |
+ struct { |
4550 |
+ atomic_long_t nrequests; |
4551 |
++ atomic_long_t redirtied_pages; |
4552 |
+ struct nfs_mds_commit_info commit_info; |
4553 |
+ struct mutex commit_mutex; |
4554 |
+ }; |
4555 |
+diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h |
4556 |
+index 732b522bacb7e..e1b8a915e9e9f 100644 |
4557 |
+--- a/include/linux/userfaultfd_k.h |
4558 |
++++ b/include/linux/userfaultfd_k.h |
4559 |
+@@ -73,6 +73,8 @@ extern ssize_t mcopy_continue(struct mm_struct *dst_mm, unsigned long dst_start, |
4560 |
+ extern int mwriteprotect_range(struct mm_struct *dst_mm, |
4561 |
+ unsigned long start, unsigned long len, |
4562 |
+ bool enable_wp, atomic_t *mmap_changing); |
4563 |
++extern void uffd_wp_range(struct mm_struct *dst_mm, struct vm_area_struct *vma, |
4564 |
++ unsigned long start, unsigned long len, bool enable_wp); |
4565 |
+ |
4566 |
+ /* mm helpers */ |
4567 |
+ static inline bool is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma, |
4568 |
+diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h |
4569 |
+index c4898fcbf923b..f90f0021f5f2d 100644 |
4570 |
+--- a/include/net/busy_poll.h |
4571 |
++++ b/include/net/busy_poll.h |
4572 |
+@@ -33,7 +33,7 @@ extern unsigned int sysctl_net_busy_poll __read_mostly; |
4573 |
+ |
4574 |
+ static inline bool net_busy_loop_on(void) |
4575 |
+ { |
4576 |
+- return sysctl_net_busy_poll; |
4577 |
++ return READ_ONCE(sysctl_net_busy_poll); |
4578 |
+ } |
4579 |
+ |
4580 |
+ static inline bool sk_can_busy_loop(const struct sock *sk) |
4581 |
+diff --git a/include/net/gro.h b/include/net/gro.h |
4582 |
+index 867656b0739c0..24003dea8fa4d 100644 |
4583 |
+--- a/include/net/gro.h |
4584 |
++++ b/include/net/gro.h |
4585 |
+@@ -439,7 +439,7 @@ static inline void gro_normal_one(struct napi_struct *napi, struct sk_buff *skb, |
4586 |
+ { |
4587 |
+ list_add_tail(&skb->list, &napi->rx_list); |
4588 |
+ napi->rx_count += segs; |
4589 |
+- if (napi->rx_count >= gro_normal_batch) |
4590 |
++ if (napi->rx_count >= READ_ONCE(gro_normal_batch)) |
4591 |
+ gro_normal_list(napi); |
4592 |
+ } |
4593 |
+ |
4594 |
+diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h |
4595 |
+index 64daafd1fc41c..9c93e4981b680 100644 |
4596 |
+--- a/include/net/netfilter/nf_flow_table.h |
4597 |
++++ b/include/net/netfilter/nf_flow_table.h |
4598 |
+@@ -270,6 +270,7 @@ void flow_offload_refresh(struct nf_flowtable *flow_table, |
4599 |
+ |
4600 |
+ struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table, |
4601 |
+ struct flow_offload_tuple *tuple); |
4602 |
++void nf_flow_table_gc_run(struct nf_flowtable *flow_table); |
4603 |
+ void nf_flow_table_gc_cleanup(struct nf_flowtable *flowtable, |
4604 |
+ struct net_device *dev); |
4605 |
+ void nf_flow_table_cleanup(struct net_device *dev); |
4606 |
+@@ -306,6 +307,8 @@ void nf_flow_offload_stats(struct nf_flowtable *flowtable, |
4607 |
+ struct flow_offload *flow); |
4608 |
+ |
4609 |
+ void nf_flow_table_offload_flush(struct nf_flowtable *flowtable); |
4610 |
++void nf_flow_table_offload_flush_cleanup(struct nf_flowtable *flowtable); |
4611 |
++ |
4612 |
+ int nf_flow_table_offload_setup(struct nf_flowtable *flowtable, |
4613 |
+ struct net_device *dev, |
4614 |
+ enum flow_block_command cmd); |
4615 |
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h |
4616 |
+index b8890ace0f879..0daad6e63ccb2 100644 |
4617 |
+--- a/include/net/netfilter/nf_tables.h |
4618 |
++++ b/include/net/netfilter/nf_tables.h |
4619 |
+@@ -1635,6 +1635,7 @@ struct nftables_pernet { |
4620 |
+ struct list_head module_list; |
4621 |
+ struct list_head notify_list; |
4622 |
+ struct mutex commit_mutex; |
4623 |
++ u64 table_handle; |
4624 |
+ unsigned int base_seq; |
4625 |
+ u8 validate_state; |
4626 |
+ }; |
4627 |
+diff --git a/include/ufs/ufshci.h b/include/ufs/ufshci.h |
4628 |
+index f81aa95ffbc40..f525566a0864d 100644 |
4629 |
+--- a/include/ufs/ufshci.h |
4630 |
++++ b/include/ufs/ufshci.h |
4631 |
+@@ -135,11 +135,7 @@ static inline u32 ufshci_version(u32 major, u32 minor) |
4632 |
+ |
4633 |
+ #define UFSHCD_UIC_MASK (UIC_COMMAND_COMPL | UFSHCD_UIC_PWR_MASK) |
4634 |
+ |
4635 |
+-#define UFSHCD_ERROR_MASK (UIC_ERROR |\ |
4636 |
+- DEVICE_FATAL_ERROR |\ |
4637 |
+- CONTROLLER_FATAL_ERROR |\ |
4638 |
+- SYSTEM_BUS_FATAL_ERROR |\ |
4639 |
+- CRYPTO_ENGINE_FATAL_ERROR) |
4640 |
++#define UFSHCD_ERROR_MASK (UIC_ERROR | INT_FATAL_ERRORS) |
4641 |
+ |
4642 |
+ #define INT_FATAL_ERRORS (DEVICE_FATAL_ERROR |\ |
4643 |
+ CONTROLLER_FATAL_ERROR |\ |
4644 |
+diff --git a/init/main.c b/init/main.c |
4645 |
+index 91642a4e69be6..1fe7942f5d4a8 100644 |
4646 |
+--- a/init/main.c |
4647 |
++++ b/init/main.c |
4648 |
+@@ -1446,13 +1446,25 @@ static noinline void __init kernel_init_freeable(void); |
4649 |
+ |
4650 |
+ #if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX) |
4651 |
+ bool rodata_enabled __ro_after_init = true; |
4652 |
++ |
4653 |
++#ifndef arch_parse_debug_rodata |
4654 |
++static inline bool arch_parse_debug_rodata(char *str) { return false; } |
4655 |
++#endif |
4656 |
++ |
4657 |
+ static int __init set_debug_rodata(char *str) |
4658 |
+ { |
4659 |
+- if (strtobool(str, &rodata_enabled)) |
4660 |
++ if (arch_parse_debug_rodata(str)) |
4661 |
++ return 0; |
4662 |
++ |
4663 |
++ if (str && !strcmp(str, "on")) |
4664 |
++ rodata_enabled = true; |
4665 |
++ else if (str && !strcmp(str, "off")) |
4666 |
++ rodata_enabled = false; |
4667 |
++ else |
4668 |
+ pr_warn("Invalid option string for rodata: '%s'\n", str); |
4669 |
+- return 1; |
4670 |
++ return 0; |
4671 |
+ } |
4672 |
+-__setup("rodata=", set_debug_rodata); |
4673 |
++early_param("rodata", set_debug_rodata); |
4674 |
+ #endif |
4675 |
+ |
4676 |
+ #ifdef CONFIG_STRICT_KERNEL_RWX |
4677 |
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c |
4678 |
+index 6a67dbf5195f0..cd155b7e1346d 100644 |
4679 |
+--- a/io_uring/io_uring.c |
4680 |
++++ b/io_uring/io_uring.c |
4681 |
+@@ -4331,7 +4331,12 @@ done: |
4682 |
+ copy_iov: |
4683 |
+ iov_iter_restore(&s->iter, &s->iter_state); |
4684 |
+ ret = io_setup_async_rw(req, iovec, s, false); |
4685 |
+- return ret ?: -EAGAIN; |
4686 |
++ if (!ret) { |
4687 |
++ if (kiocb->ki_flags & IOCB_WRITE) |
4688 |
++ kiocb_end_write(req); |
4689 |
++ return -EAGAIN; |
4690 |
++ } |
4691 |
++ return ret; |
4692 |
+ } |
4693 |
+ out_free: |
4694 |
+ /* it's reportedly faster than delegating the null check to kfree() */ |
4695 |
+diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c |
4696 |
+index 6432a37ac1c94..c565fbf66ac87 100644 |
4697 |
+--- a/kernel/audit_fsnotify.c |
4698 |
++++ b/kernel/audit_fsnotify.c |
4699 |
+@@ -102,6 +102,7 @@ struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pa |
4700 |
+ |
4701 |
+ ret = fsnotify_add_inode_mark(&audit_mark->mark, inode, 0); |
4702 |
+ if (ret < 0) { |
4703 |
++ audit_mark->path = NULL; |
4704 |
+ fsnotify_put_mark(&audit_mark->mark); |
4705 |
+ audit_mark = ERR_PTR(ret); |
4706 |
+ } |
4707 |
+diff --git a/kernel/auditsc.c b/kernel/auditsc.c |
4708 |
+index 3a8c9d744800a..0c33e04c293ad 100644 |
4709 |
+--- a/kernel/auditsc.c |
4710 |
++++ b/kernel/auditsc.c |
4711 |
+@@ -1965,6 +1965,7 @@ void __audit_uring_exit(int success, long code) |
4712 |
+ goto out; |
4713 |
+ } |
4714 |
+ |
4715 |
++ audit_return_fixup(ctx, success, code); |
4716 |
+ if (ctx->context == AUDIT_CTX_SYSCALL) { |
4717 |
+ /* |
4718 |
+ * NOTE: See the note in __audit_uring_entry() about the case |
4719 |
+@@ -2006,7 +2007,6 @@ void __audit_uring_exit(int success, long code) |
4720 |
+ audit_filter_inodes(current, ctx); |
4721 |
+ if (ctx->current_state != AUDIT_STATE_RECORD) |
4722 |
+ goto out; |
4723 |
+- audit_return_fixup(ctx, success, code); |
4724 |
+ audit_log_exit(); |
4725 |
+ |
4726 |
+ out: |
4727 |
+@@ -2090,13 +2090,13 @@ void __audit_syscall_exit(int success, long return_code) |
4728 |
+ if (!list_empty(&context->killed_trees)) |
4729 |
+ audit_kill_trees(context); |
4730 |
+ |
4731 |
++ audit_return_fixup(context, success, return_code); |
4732 |
+ /* run through both filters to ensure we set the filterkey properly */ |
4733 |
+ audit_filter_syscall(current, context); |
4734 |
+ audit_filter_inodes(current, context); |
4735 |
+ if (context->current_state < AUDIT_STATE_RECORD) |
4736 |
+ goto out; |
4737 |
+ |
4738 |
+- audit_return_fixup(context, success, return_code); |
4739 |
+ audit_log_exit(); |
4740 |
+ |
4741 |
+ out: |
4742 |
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c |
4743 |
+index e91d2faef1605..0e45d405f151c 100644 |
4744 |
+--- a/kernel/bpf/verifier.c |
4745 |
++++ b/kernel/bpf/verifier.c |
4746 |
+@@ -6999,8 +6999,7 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta, |
4747 |
+ struct bpf_insn_aux_data *aux = &env->insn_aux_data[insn_idx]; |
4748 |
+ struct bpf_reg_state *regs = cur_regs(env), *reg; |
4749 |
+ struct bpf_map *map = meta->map_ptr; |
4750 |
+- struct tnum range; |
4751 |
+- u64 val; |
4752 |
++ u64 val, max; |
4753 |
+ int err; |
4754 |
+ |
4755 |
+ if (func_id != BPF_FUNC_tail_call) |
4756 |
+@@ -7010,10 +7009,11 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta, |
4757 |
+ return -EINVAL; |
4758 |
+ } |
4759 |
+ |
4760 |
+- range = tnum_range(0, map->max_entries - 1); |
4761 |
+ reg = ®s[BPF_REG_3]; |
4762 |
++ val = reg->var_off.value; |
4763 |
++ max = map->max_entries; |
4764 |
+ |
4765 |
+- if (!register_is_const(reg) || !tnum_in(range, reg->var_off)) { |
4766 |
++ if (!(register_is_const(reg) && val < max)) { |
4767 |
+ bpf_map_key_store(aux, BPF_MAP_KEY_POISON); |
4768 |
+ return 0; |
4769 |
+ } |
4770 |
+@@ -7021,8 +7021,6 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta, |
4771 |
+ err = mark_chain_precision(env, BPF_REG_3); |
4772 |
+ if (err) |
4773 |
+ return err; |
4774 |
+- |
4775 |
+- val = reg->var_off.value; |
4776 |
+ if (bpf_map_key_unseen(aux)) |
4777 |
+ bpf_map_key_store(aux, val); |
4778 |
+ else if (!bpf_map_key_poisoned(aux) && |
4779 |
+diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c |
4780 |
+index 13c8e91d78620..ce95aee05e8ae 100644 |
4781 |
+--- a/kernel/cgroup/cgroup.c |
4782 |
++++ b/kernel/cgroup/cgroup.c |
4783 |
+@@ -1811,6 +1811,7 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask) |
4784 |
+ |
4785 |
+ if (ss->css_rstat_flush) { |
4786 |
+ list_del_rcu(&css->rstat_css_node); |
4787 |
++ synchronize_rcu(); |
4788 |
+ list_add_rcu(&css->rstat_css_node, |
4789 |
+ &dcgrp->rstat_css_list); |
4790 |
+ } |
4791 |
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c |
4792 |
+index 80697e5e03e49..08350e35aba24 100644 |
4793 |
+--- a/kernel/kprobes.c |
4794 |
++++ b/kernel/kprobes.c |
4795 |
+@@ -1707,11 +1707,12 @@ static struct kprobe *__disable_kprobe(struct kprobe *p) |
4796 |
+ /* Try to disarm and disable this/parent probe */ |
4797 |
+ if (p == orig_p || aggr_kprobe_disabled(orig_p)) { |
4798 |
+ /* |
4799 |
+- * If 'kprobes_all_disarmed' is set, 'orig_p' |
4800 |
+- * should have already been disarmed, so |
4801 |
+- * skip unneed disarming process. |
4802 |
++ * Don't be lazy here. Even if 'kprobes_all_disarmed' |
4803 |
++ * is false, 'orig_p' might not have been armed yet. |
4804 |
++ * Note arm_all_kprobes() __tries__ to arm all kprobes |
4805 |
++ * on the best effort basis. |
4806 |
+ */ |
4807 |
+- if (!kprobes_all_disarmed) { |
4808 |
++ if (!kprobes_all_disarmed && !kprobe_disabled(orig_p)) { |
4809 |
+ ret = disarm_kprobe(orig_p, true); |
4810 |
+ if (ret) { |
4811 |
+ p->flags &= ~KPROBE_FLAG_DISABLED; |
4812 |
+diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c |
4813 |
+index a492f159624fa..860b2dcf3ac46 100644 |
4814 |
+--- a/kernel/sys_ni.c |
4815 |
++++ b/kernel/sys_ni.c |
4816 |
+@@ -277,6 +277,7 @@ COND_SYSCALL(landlock_restrict_self); |
4817 |
+ |
4818 |
+ /* mm/fadvise.c */ |
4819 |
+ COND_SYSCALL(fadvise64_64); |
4820 |
++COND_SYSCALL_COMPAT(fadvise64_64); |
4821 |
+ |
4822 |
+ /* mm/, CONFIG_MMU only */ |
4823 |
+ COND_SYSCALL(swapon); |
4824 |
+diff --git a/lib/ratelimit.c b/lib/ratelimit.c |
4825 |
+index e01a93f46f833..ce945c17980b9 100644 |
4826 |
+--- a/lib/ratelimit.c |
4827 |
++++ b/lib/ratelimit.c |
4828 |
+@@ -26,10 +26,16 @@ |
4829 |
+ */ |
4830 |
+ int ___ratelimit(struct ratelimit_state *rs, const char *func) |
4831 |
+ { |
4832 |
++ /* Paired with WRITE_ONCE() in .proc_handler(). |
4833 |
++ * Changing two values seperately could be inconsistent |
4834 |
++ * and some message could be lost. (See: net_ratelimit_state). |
4835 |
++ */ |
4836 |
++ int interval = READ_ONCE(rs->interval); |
4837 |
++ int burst = READ_ONCE(rs->burst); |
4838 |
+ unsigned long flags; |
4839 |
+ int ret; |
4840 |
+ |
4841 |
+- if (!rs->interval) |
4842 |
++ if (!interval) |
4843 |
+ return 1; |
4844 |
+ |
4845 |
+ /* |
4846 |
+@@ -44,7 +50,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func) |
4847 |
+ if (!rs->begin) |
4848 |
+ rs->begin = jiffies; |
4849 |
+ |
4850 |
+- if (time_is_before_jiffies(rs->begin + rs->interval)) { |
4851 |
++ if (time_is_before_jiffies(rs->begin + interval)) { |
4852 |
+ if (rs->missed) { |
4853 |
+ if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) { |
4854 |
+ printk_deferred(KERN_WARNING |
4855 |
+@@ -56,7 +62,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func) |
4856 |
+ rs->begin = jiffies; |
4857 |
+ rs->printed = 0; |
4858 |
+ } |
4859 |
+- if (rs->burst && rs->burst > rs->printed) { |
4860 |
++ if (burst && burst > rs->printed) { |
4861 |
+ rs->printed++; |
4862 |
+ ret = 1; |
4863 |
+ } else { |
4864 |
+diff --git a/mm/backing-dev.c b/mm/backing-dev.c |
4865 |
+index 95550b8fa7fe2..de65cb1e5f761 100644 |
4866 |
+--- a/mm/backing-dev.c |
4867 |
++++ b/mm/backing-dev.c |
4868 |
+@@ -260,10 +260,10 @@ void wb_wakeup_delayed(struct bdi_writeback *wb) |
4869 |
+ unsigned long timeout; |
4870 |
+ |
4871 |
+ timeout = msecs_to_jiffies(dirty_writeback_interval * 10); |
4872 |
+- spin_lock_bh(&wb->work_lock); |
4873 |
++ spin_lock_irq(&wb->work_lock); |
4874 |
+ if (test_bit(WB_registered, &wb->state)) |
4875 |
+ queue_delayed_work(bdi_wq, &wb->dwork, timeout); |
4876 |
+- spin_unlock_bh(&wb->work_lock); |
4877 |
++ spin_unlock_irq(&wb->work_lock); |
4878 |
+ } |
4879 |
+ |
4880 |
+ static void wb_update_bandwidth_workfn(struct work_struct *work) |
4881 |
+@@ -334,12 +334,12 @@ static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb); |
4882 |
+ static void wb_shutdown(struct bdi_writeback *wb) |
4883 |
+ { |
4884 |
+ /* Make sure nobody queues further work */ |
4885 |
+- spin_lock_bh(&wb->work_lock); |
4886 |
++ spin_lock_irq(&wb->work_lock); |
4887 |
+ if (!test_and_clear_bit(WB_registered, &wb->state)) { |
4888 |
+- spin_unlock_bh(&wb->work_lock); |
4889 |
++ spin_unlock_irq(&wb->work_lock); |
4890 |
+ return; |
4891 |
+ } |
4892 |
+- spin_unlock_bh(&wb->work_lock); |
4893 |
++ spin_unlock_irq(&wb->work_lock); |
4894 |
+ |
4895 |
+ cgwb_remove_from_bdi_list(wb); |
4896 |
+ /* |
4897 |
+diff --git a/mm/bootmem_info.c b/mm/bootmem_info.c |
4898 |
+index f18a631e74797..b1efebfcf94bb 100644 |
4899 |
+--- a/mm/bootmem_info.c |
4900 |
++++ b/mm/bootmem_info.c |
4901 |
+@@ -12,6 +12,7 @@ |
4902 |
+ #include <linux/memblock.h> |
4903 |
+ #include <linux/bootmem_info.h> |
4904 |
+ #include <linux/memory_hotplug.h> |
4905 |
++#include <linux/kmemleak.h> |
4906 |
+ |
4907 |
+ void get_page_bootmem(unsigned long info, struct page *page, unsigned long type) |
4908 |
+ { |
4909 |
+@@ -33,6 +34,7 @@ void put_page_bootmem(struct page *page) |
4910 |
+ ClearPagePrivate(page); |
4911 |
+ set_page_private(page, 0); |
4912 |
+ INIT_LIST_HEAD(&page->lru); |
4913 |
++ kmemleak_free_part(page_to_virt(page), PAGE_SIZE); |
4914 |
+ free_reserved_page(page); |
4915 |
+ } |
4916 |
+ } |
4917 |
+diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c |
4918 |
+index a0dab8b5e45f2..53ba8b1e619ca 100644 |
4919 |
+--- a/mm/damon/dbgfs.c |
4920 |
++++ b/mm/damon/dbgfs.c |
4921 |
+@@ -787,6 +787,9 @@ static int dbgfs_mk_context(char *name) |
4922 |
+ return -ENOENT; |
4923 |
+ |
4924 |
+ new_dir = debugfs_create_dir(name, root); |
4925 |
++ /* Below check is required for a potential duplicated name case */ |
4926 |
++ if (IS_ERR(new_dir)) |
4927 |
++ return PTR_ERR(new_dir); |
4928 |
+ dbgfs_dirs[dbgfs_nr_ctxs] = new_dir; |
4929 |
+ |
4930 |
+ new_ctx = dbgfs_new_ctx(); |
4931 |
+diff --git a/mm/gup.c b/mm/gup.c |
4932 |
+index fd3262ae92fc2..38effce68b48d 100644 |
4933 |
+--- a/mm/gup.c |
4934 |
++++ b/mm/gup.c |
4935 |
+@@ -478,14 +478,43 @@ static int follow_pfn_pte(struct vm_area_struct *vma, unsigned long address, |
4936 |
+ return -EEXIST; |
4937 |
+ } |
4938 |
+ |
4939 |
+-/* |
4940 |
+- * FOLL_FORCE can write to even unwritable pte's, but only |
4941 |
+- * after we've gone through a COW cycle and they are dirty. |
4942 |
+- */ |
4943 |
+-static inline bool can_follow_write_pte(pte_t pte, unsigned int flags) |
4944 |
++/* FOLL_FORCE can write to even unwritable PTEs in COW mappings. */ |
4945 |
++static inline bool can_follow_write_pte(pte_t pte, struct page *page, |
4946 |
++ struct vm_area_struct *vma, |
4947 |
++ unsigned int flags) |
4948 |
+ { |
4949 |
+- return pte_write(pte) || |
4950 |
+- ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte)); |
4951 |
++ /* If the pte is writable, we can write to the page. */ |
4952 |
++ if (pte_write(pte)) |
4953 |
++ return true; |
4954 |
++ |
4955 |
++ /* Maybe FOLL_FORCE is set to override it? */ |
4956 |
++ if (!(flags & FOLL_FORCE)) |
4957 |
++ return false; |
4958 |
++ |
4959 |
++ /* But FOLL_FORCE has no effect on shared mappings */ |
4960 |
++ if (vma->vm_flags & (VM_MAYSHARE | VM_SHARED)) |
4961 |
++ return false; |
4962 |
++ |
4963 |
++ /* ... or read-only private ones */ |
4964 |
++ if (!(vma->vm_flags & VM_MAYWRITE)) |
4965 |
++ return false; |
4966 |
++ |
4967 |
++ /* ... or already writable ones that just need to take a write fault */ |
4968 |
++ if (vma->vm_flags & VM_WRITE) |
4969 |
++ return false; |
4970 |
++ |
4971 |
++ /* |
4972 |
++ * See can_change_pte_writable(): we broke COW and could map the page |
4973 |
++ * writable if we have an exclusive anonymous page ... |
4974 |
++ */ |
4975 |
++ if (!page || !PageAnon(page) || !PageAnonExclusive(page)) |
4976 |
++ return false; |
4977 |
++ |
4978 |
++ /* ... and a write-fault isn't required for other reasons. */ |
4979 |
++ if (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && |
4980 |
++ !(vma->vm_flags & VM_SOFTDIRTY) && !pte_soft_dirty(pte)) |
4981 |
++ return false; |
4982 |
++ return !userfaultfd_pte_wp(vma, pte); |
4983 |
+ } |
4984 |
+ |
4985 |
+ static struct page *follow_page_pte(struct vm_area_struct *vma, |
4986 |
+@@ -528,12 +557,19 @@ retry: |
4987 |
+ } |
4988 |
+ if ((flags & FOLL_NUMA) && pte_protnone(pte)) |
4989 |
+ goto no_page; |
4990 |
+- if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, flags)) { |
4991 |
+- pte_unmap_unlock(ptep, ptl); |
4992 |
+- return NULL; |
4993 |
+- } |
4994 |
+ |
4995 |
+ page = vm_normal_page(vma, address, pte); |
4996 |
++ |
4997 |
++ /* |
4998 |
++ * We only care about anon pages in can_follow_write_pte() and don't |
4999 |
++ * have to worry about pte_devmap() because they are never anon. |
5000 |
++ */ |
5001 |
++ if ((flags & FOLL_WRITE) && |
5002 |
++ !can_follow_write_pte(pte, page, vma, flags)) { |
5003 |
++ page = NULL; |
5004 |
++ goto out; |
5005 |
++ } |
5006 |
++ |
5007 |
+ if (!page && pte_devmap(pte) && (flags & (FOLL_GET | FOLL_PIN))) { |
5008 |
+ /* |
5009 |
+ * Only return device mapping pages in the FOLL_GET or FOLL_PIN |
5010 |
+@@ -967,17 +1003,6 @@ static int faultin_page(struct vm_area_struct *vma, |
5011 |
+ return -EBUSY; |
5012 |
+ } |
5013 |
+ |
5014 |
+- /* |
5015 |
+- * The VM_FAULT_WRITE bit tells us that do_wp_page has broken COW when |
5016 |
+- * necessary, even if maybe_mkwrite decided not to set pte_write. We |
5017 |
+- * can thus safely do subsequent page lookups as if they were reads. |
5018 |
+- * But only do so when looping for pte_write is futile: in some cases |
5019 |
+- * userspace may also be wanting to write to the gotten user page, |
5020 |
+- * which a read fault here might prevent (a readonly page might get |
5021 |
+- * reCOWed by userspace write). |
5022 |
+- */ |
5023 |
+- if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE)) |
5024 |
+- *flags |= FOLL_COW; |
5025 |
+ return 0; |
5026 |
+ } |
5027 |
+ |
5028 |
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c |
5029 |
+index 15965084816d3..0f465e70349cb 100644 |
5030 |
+--- a/mm/huge_memory.c |
5031 |
++++ b/mm/huge_memory.c |
5032 |
+@@ -978,12 +978,6 @@ struct page *follow_devmap_pmd(struct vm_area_struct *vma, unsigned long addr, |
5033 |
+ |
5034 |
+ assert_spin_locked(pmd_lockptr(mm, pmd)); |
5035 |
+ |
5036 |
+- /* |
5037 |
+- * When we COW a devmap PMD entry, we split it into PTEs, so we should |
5038 |
+- * not be in this function with `flags & FOLL_COW` set. |
5039 |
+- */ |
5040 |
+- WARN_ONCE(flags & FOLL_COW, "mm: In follow_devmap_pmd with FOLL_COW set"); |
5041 |
+- |
5042 |
+ /* FOLL_GET and FOLL_PIN are mutually exclusive. */ |
5043 |
+ if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) == |
5044 |
+ (FOLL_PIN | FOLL_GET))) |
5045 |
+@@ -1349,14 +1343,43 @@ fallback: |
5046 |
+ return VM_FAULT_FALLBACK; |
5047 |
+ } |
5048 |
+ |
5049 |
+-/* |
5050 |
+- * FOLL_FORCE can write to even unwritable pmd's, but only |
5051 |
+- * after we've gone through a COW cycle and they are dirty. |
5052 |
+- */ |
5053 |
+-static inline bool can_follow_write_pmd(pmd_t pmd, unsigned int flags) |
5054 |
++/* FOLL_FORCE can write to even unwritable PMDs in COW mappings. */ |
5055 |
++static inline bool can_follow_write_pmd(pmd_t pmd, struct page *page, |
5056 |
++ struct vm_area_struct *vma, |
5057 |
++ unsigned int flags) |
5058 |
+ { |
5059 |
+- return pmd_write(pmd) || |
5060 |
+- ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pmd_dirty(pmd)); |
5061 |
++ /* If the pmd is writable, we can write to the page. */ |
5062 |
++ if (pmd_write(pmd)) |
5063 |
++ return true; |
5064 |
++ |
5065 |
++ /* Maybe FOLL_FORCE is set to override it? */ |
5066 |
++ if (!(flags & FOLL_FORCE)) |
5067 |
++ return false; |
5068 |
++ |
5069 |
++ /* But FOLL_FORCE has no effect on shared mappings */ |
5070 |
++ if (vma->vm_flags & (VM_MAYSHARE | VM_SHARED)) |
5071 |
++ return false; |
5072 |
++ |
5073 |
++ /* ... or read-only private ones */ |
5074 |
++ if (!(vma->vm_flags & VM_MAYWRITE)) |
5075 |
++ return false; |
5076 |
++ |
5077 |
++ /* ... or already writable ones that just need to take a write fault */ |
5078 |
++ if (vma->vm_flags & VM_WRITE) |
5079 |
++ return false; |
5080 |
++ |
5081 |
++ /* |
5082 |
++ * See can_change_pte_writable(): we broke COW and could map the page |
5083 |
++ * writable if we have an exclusive anonymous page ... |
5084 |
++ */ |
5085 |
++ if (!page || !PageAnon(page) || !PageAnonExclusive(page)) |
5086 |
++ return false; |
5087 |
++ |
5088 |
++ /* ... and a write-fault isn't required for other reasons. */ |
5089 |
++ if (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && |
5090 |
++ !(vma->vm_flags & VM_SOFTDIRTY) && !pmd_soft_dirty(pmd)) |
5091 |
++ return false; |
5092 |
++ return !userfaultfd_huge_pmd_wp(vma, pmd); |
5093 |
+ } |
5094 |
+ |
5095 |
+ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, |
5096 |
+@@ -1365,12 +1388,16 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, |
5097 |
+ unsigned int flags) |
5098 |
+ { |
5099 |
+ struct mm_struct *mm = vma->vm_mm; |
5100 |
+- struct page *page = NULL; |
5101 |
++ struct page *page; |
5102 |
+ |
5103 |
+ assert_spin_locked(pmd_lockptr(mm, pmd)); |
5104 |
+ |
5105 |
+- if (flags & FOLL_WRITE && !can_follow_write_pmd(*pmd, flags)) |
5106 |
+- goto out; |
5107 |
++ page = pmd_page(*pmd); |
5108 |
++ VM_BUG_ON_PAGE(!PageHead(page) && !is_zone_device_page(page), page); |
5109 |
++ |
5110 |
++ if ((flags & FOLL_WRITE) && |
5111 |
++ !can_follow_write_pmd(*pmd, page, vma, flags)) |
5112 |
++ return NULL; |
5113 |
+ |
5114 |
+ /* Avoid dumping huge zero page */ |
5115 |
+ if ((flags & FOLL_DUMP) && is_huge_zero_pmd(*pmd)) |
5116 |
+@@ -1378,10 +1405,7 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, |
5117 |
+ |
5118 |
+ /* Full NUMA hinting faults to serialise migration in fault paths */ |
5119 |
+ if ((flags & FOLL_NUMA) && pmd_protnone(*pmd)) |
5120 |
+- goto out; |
5121 |
+- |
5122 |
+- page = pmd_page(*pmd); |
5123 |
+- VM_BUG_ON_PAGE(!PageHead(page) && !is_zone_device_page(page), page); |
5124 |
++ return NULL; |
5125 |
+ |
5126 |
+ if (!pmd_write(*pmd) && gup_must_unshare(flags, page)) |
5127 |
+ return ERR_PTR(-EMLINK); |
5128 |
+@@ -1398,7 +1422,6 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, |
5129 |
+ page += (addr & ~HPAGE_PMD_MASK) >> PAGE_SHIFT; |
5130 |
+ VM_BUG_ON_PAGE(!PageCompound(page) && !is_zone_device_page(page), page); |
5131 |
+ |
5132 |
+-out: |
5133 |
+ return page; |
5134 |
+ } |
5135 |
+ |
5136 |
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c |
5137 |
+index 474bfbe9929e1..299dcfaa35b25 100644 |
5138 |
+--- a/mm/hugetlb.c |
5139 |
++++ b/mm/hugetlb.c |
5140 |
+@@ -5232,6 +5232,21 @@ static vm_fault_t hugetlb_wp(struct mm_struct *mm, struct vm_area_struct *vma, |
5141 |
+ VM_BUG_ON(unshare && (flags & FOLL_WRITE)); |
5142 |
+ VM_BUG_ON(!unshare && !(flags & FOLL_WRITE)); |
5143 |
+ |
5144 |
++ /* |
5145 |
++ * hugetlb does not support FOLL_FORCE-style write faults that keep the |
5146 |
++ * PTE mapped R/O such as maybe_mkwrite() would do. |
5147 |
++ */ |
5148 |
++ if (WARN_ON_ONCE(!unshare && !(vma->vm_flags & VM_WRITE))) |
5149 |
++ return VM_FAULT_SIGSEGV; |
5150 |
++ |
5151 |
++ /* Let's take out MAP_SHARED mappings first. */ |
5152 |
++ if (vma->vm_flags & VM_MAYSHARE) { |
5153 |
++ if (unlikely(unshare)) |
5154 |
++ return 0; |
5155 |
++ set_huge_ptep_writable(vma, haddr, ptep); |
5156 |
++ return 0; |
5157 |
++ } |
5158 |
++ |
5159 |
+ pte = huge_ptep_get(ptep); |
5160 |
+ old_page = pte_page(pte); |
5161 |
+ |
5162 |
+@@ -5766,12 +5781,11 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, |
5163 |
+ * If we are going to COW/unshare the mapping later, we examine the |
5164 |
+ * pending reservations for this page now. This will ensure that any |
5165 |
+ * allocations necessary to record that reservation occur outside the |
5166 |
+- * spinlock. For private mappings, we also lookup the pagecache |
5167 |
+- * page now as it is used to determine if a reservation has been |
5168 |
+- * consumed. |
5169 |
++ * spinlock. Also lookup the pagecache page now as it is used to |
5170 |
++ * determine if a reservation has been consumed. |
5171 |
+ */ |
5172 |
+ if ((flags & (FAULT_FLAG_WRITE|FAULT_FLAG_UNSHARE)) && |
5173 |
+- !huge_pte_write(entry)) { |
5174 |
++ !(vma->vm_flags & VM_MAYSHARE) && !huge_pte_write(entry)) { |
5175 |
+ if (vma_needs_reservation(h, vma, haddr) < 0) { |
5176 |
+ ret = VM_FAULT_OOM; |
5177 |
+ goto out_mutex; |
5178 |
+@@ -5779,9 +5793,7 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, |
5179 |
+ /* Just decrements count, does not deallocate */ |
5180 |
+ vma_end_reservation(h, vma, haddr); |
5181 |
+ |
5182 |
+- if (!(vma->vm_flags & VM_MAYSHARE)) |
5183 |
+- pagecache_page = hugetlbfs_pagecache_page(h, |
5184 |
+- vma, haddr); |
5185 |
++ pagecache_page = hugetlbfs_pagecache_page(h, vma, haddr); |
5186 |
+ } |
5187 |
+ |
5188 |
+ ptl = huge_pte_lock(h, mm, ptep); |
5189 |
+@@ -6014,7 +6026,7 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm, |
5190 |
+ if (!huge_pte_none_mostly(huge_ptep_get(dst_pte))) |
5191 |
+ goto out_release_unlock; |
5192 |
+ |
5193 |
+- if (vm_shared) { |
5194 |
++ if (page_in_pagecache) { |
5195 |
+ page_dup_file_rmap(page, true); |
5196 |
+ } else { |
5197 |
+ ClearHPageRestoreReserve(page); |
5198 |
+diff --git a/mm/mmap.c b/mm/mmap.c |
5199 |
+index 7c59ec73acc34..3b284b091bb7e 100644 |
5200 |
+--- a/mm/mmap.c |
5201 |
++++ b/mm/mmap.c |
5202 |
+@@ -1693,8 +1693,12 @@ int vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot) |
5203 |
+ pgprot_val(vm_pgprot_modify(vm_page_prot, vm_flags))) |
5204 |
+ return 0; |
5205 |
+ |
5206 |
+- /* Do we need to track softdirty? */ |
5207 |
+- if (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && !(vm_flags & VM_SOFTDIRTY)) |
5208 |
++ /* |
5209 |
++ * Do we need to track softdirty? hugetlb does not support softdirty |
5210 |
++ * tracking yet. |
5211 |
++ */ |
5212 |
++ if (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && !(vm_flags & VM_SOFTDIRTY) && |
5213 |
++ !is_vm_hugetlb_page(vma)) |
5214 |
+ return 1; |
5215 |
+ |
5216 |
+ /* Specialty mapping? */ |
5217 |
+diff --git a/mm/mprotect.c b/mm/mprotect.c |
5218 |
+index ba5592655ee3b..0d38d5b637621 100644 |
5219 |
+--- a/mm/mprotect.c |
5220 |
++++ b/mm/mprotect.c |
5221 |
+@@ -158,10 +158,11 @@ static unsigned long change_pte_range(struct mmu_gather *tlb, |
5222 |
+ pages++; |
5223 |
+ } else if (is_swap_pte(oldpte)) { |
5224 |
+ swp_entry_t entry = pte_to_swp_entry(oldpte); |
5225 |
+- struct page *page = pfn_swap_entry_to_page(entry); |
5226 |
+ pte_t newpte; |
5227 |
+ |
5228 |
+ if (is_writable_migration_entry(entry)) { |
5229 |
++ struct page *page = pfn_swap_entry_to_page(entry); |
5230 |
++ |
5231 |
+ /* |
5232 |
+ * A protection check is difficult so |
5233 |
+ * just be safe and disable write |
5234 |
+diff --git a/mm/page-writeback.c b/mm/page-writeback.c |
5235 |
+index 55c2776ae6999..3c34db15cf706 100644 |
5236 |
+--- a/mm/page-writeback.c |
5237 |
++++ b/mm/page-writeback.c |
5238 |
+@@ -2867,6 +2867,7 @@ static void wb_inode_writeback_start(struct bdi_writeback *wb) |
5239 |
+ |
5240 |
+ static void wb_inode_writeback_end(struct bdi_writeback *wb) |
5241 |
+ { |
5242 |
++ unsigned long flags; |
5243 |
+ atomic_dec(&wb->writeback_inodes); |
5244 |
+ /* |
5245 |
+ * Make sure estimate of writeback throughput gets updated after |
5246 |
+@@ -2875,7 +2876,10 @@ static void wb_inode_writeback_end(struct bdi_writeback *wb) |
5247 |
+ * that if multiple inodes end writeback at a similar time, they get |
5248 |
+ * batched into one bandwidth update. |
5249 |
+ */ |
5250 |
+- queue_delayed_work(bdi_wq, &wb->bw_dwork, BANDWIDTH_INTERVAL); |
5251 |
++ spin_lock_irqsave(&wb->work_lock, flags); |
5252 |
++ if (test_bit(WB_registered, &wb->state)) |
5253 |
++ queue_delayed_work(bdi_wq, &wb->bw_dwork, BANDWIDTH_INTERVAL); |
5254 |
++ spin_unlock_irqrestore(&wb->work_lock, flags); |
5255 |
+ } |
5256 |
+ |
5257 |
+ bool __folio_end_writeback(struct folio *folio) |
5258 |
+diff --git a/mm/shmem.c b/mm/shmem.c |
5259 |
+index b7f2d4a568673..f152375e770bf 100644 |
5260 |
+--- a/mm/shmem.c |
5261 |
++++ b/mm/shmem.c |
5262 |
+@@ -1771,6 +1771,7 @@ static int shmem_swapin_folio(struct inode *inode, pgoff_t index, |
5263 |
+ |
5264 |
+ if (shmem_should_replace_folio(folio, gfp)) { |
5265 |
+ error = shmem_replace_page(&page, gfp, info, index); |
5266 |
++ folio = page_folio(page); |
5267 |
+ if (error) |
5268 |
+ goto failed; |
5269 |
+ } |
5270 |
+diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c |
5271 |
+index 07d3befc80e41..7327b2573f7c2 100644 |
5272 |
+--- a/mm/userfaultfd.c |
5273 |
++++ b/mm/userfaultfd.c |
5274 |
+@@ -703,14 +703,29 @@ ssize_t mcopy_continue(struct mm_struct *dst_mm, unsigned long start, |
5275 |
+ mmap_changing, 0); |
5276 |
+ } |
5277 |
+ |
5278 |
++void uffd_wp_range(struct mm_struct *dst_mm, struct vm_area_struct *dst_vma, |
5279 |
++ unsigned long start, unsigned long len, bool enable_wp) |
5280 |
++{ |
5281 |
++ struct mmu_gather tlb; |
5282 |
++ pgprot_t newprot; |
5283 |
++ |
5284 |
++ if (enable_wp) |
5285 |
++ newprot = vm_get_page_prot(dst_vma->vm_flags & ~(VM_WRITE)); |
5286 |
++ else |
5287 |
++ newprot = vm_get_page_prot(dst_vma->vm_flags); |
5288 |
++ |
5289 |
++ tlb_gather_mmu(&tlb, dst_mm); |
5290 |
++ change_protection(&tlb, dst_vma, start, start + len, newprot, |
5291 |
++ enable_wp ? MM_CP_UFFD_WP : MM_CP_UFFD_WP_RESOLVE); |
5292 |
++ tlb_finish_mmu(&tlb); |
5293 |
++} |
5294 |
++ |
5295 |
+ int mwriteprotect_range(struct mm_struct *dst_mm, unsigned long start, |
5296 |
+ unsigned long len, bool enable_wp, |
5297 |
+ atomic_t *mmap_changing) |
5298 |
+ { |
5299 |
+ struct vm_area_struct *dst_vma; |
5300 |
+ unsigned long page_mask; |
5301 |
+- struct mmu_gather tlb; |
5302 |
+- pgprot_t newprot; |
5303 |
+ int err; |
5304 |
+ |
5305 |
+ /* |
5306 |
+@@ -750,15 +765,7 @@ int mwriteprotect_range(struct mm_struct *dst_mm, unsigned long start, |
5307 |
+ goto out_unlock; |
5308 |
+ } |
5309 |
+ |
5310 |
+- if (enable_wp) |
5311 |
+- newprot = vm_get_page_prot(dst_vma->vm_flags & ~(VM_WRITE)); |
5312 |
+- else |
5313 |
+- newprot = vm_get_page_prot(dst_vma->vm_flags); |
5314 |
+- |
5315 |
+- tlb_gather_mmu(&tlb, dst_mm); |
5316 |
+- change_protection(&tlb, dst_vma, start, start + len, newprot, |
5317 |
+- enable_wp ? MM_CP_UFFD_WP : MM_CP_UFFD_WP_RESOLVE); |
5318 |
+- tlb_finish_mmu(&tlb); |
5319 |
++ uffd_wp_range(dst_mm, dst_vma, start, len, enable_wp); |
5320 |
+ |
5321 |
+ err = 0; |
5322 |
+ out_unlock: |
5323 |
+diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c |
5324 |
+index 1a11064f99907..8f19253024b0a 100644 |
5325 |
+--- a/net/bridge/netfilter/ebtable_broute.c |
5326 |
++++ b/net/bridge/netfilter/ebtable_broute.c |
5327 |
+@@ -36,18 +36,10 @@ static struct ebt_replace_kernel initial_table = { |
5328 |
+ .entries = (char *)&initial_chain, |
5329 |
+ }; |
5330 |
+ |
5331 |
+-static int check(const struct ebt_table_info *info, unsigned int valid_hooks) |
5332 |
+-{ |
5333 |
+- if (valid_hooks & ~(1 << NF_BR_BROUTING)) |
5334 |
+- return -EINVAL; |
5335 |
+- return 0; |
5336 |
+-} |
5337 |
+- |
5338 |
+ static const struct ebt_table broute_table = { |
5339 |
+ .name = "broute", |
5340 |
+ .table = &initial_table, |
5341 |
+ .valid_hooks = 1 << NF_BR_BROUTING, |
5342 |
+- .check = check, |
5343 |
+ .me = THIS_MODULE, |
5344 |
+ }; |
5345 |
+ |
5346 |
+diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c |
5347 |
+index cb949436bc0e3..278f324e67524 100644 |
5348 |
+--- a/net/bridge/netfilter/ebtable_filter.c |
5349 |
++++ b/net/bridge/netfilter/ebtable_filter.c |
5350 |
+@@ -43,18 +43,10 @@ static struct ebt_replace_kernel initial_table = { |
5351 |
+ .entries = (char *)initial_chains, |
5352 |
+ }; |
5353 |
+ |
5354 |
+-static int check(const struct ebt_table_info *info, unsigned int valid_hooks) |
5355 |
+-{ |
5356 |
+- if (valid_hooks & ~FILTER_VALID_HOOKS) |
5357 |
+- return -EINVAL; |
5358 |
+- return 0; |
5359 |
+-} |
5360 |
+- |
5361 |
+ static const struct ebt_table frame_filter = { |
5362 |
+ .name = "filter", |
5363 |
+ .table = &initial_table, |
5364 |
+ .valid_hooks = FILTER_VALID_HOOKS, |
5365 |
+- .check = check, |
5366 |
+ .me = THIS_MODULE, |
5367 |
+ }; |
5368 |
+ |
5369 |
+diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c |
5370 |
+index 5ee0531ae5061..9066f7f376d57 100644 |
5371 |
+--- a/net/bridge/netfilter/ebtable_nat.c |
5372 |
++++ b/net/bridge/netfilter/ebtable_nat.c |
5373 |
+@@ -43,18 +43,10 @@ static struct ebt_replace_kernel initial_table = { |
5374 |
+ .entries = (char *)initial_chains, |
5375 |
+ }; |
5376 |
+ |
5377 |
+-static int check(const struct ebt_table_info *info, unsigned int valid_hooks) |
5378 |
+-{ |
5379 |
+- if (valid_hooks & ~NAT_VALID_HOOKS) |
5380 |
+- return -EINVAL; |
5381 |
+- return 0; |
5382 |
+-} |
5383 |
+- |
5384 |
+ static const struct ebt_table frame_nat = { |
5385 |
+ .name = "nat", |
5386 |
+ .table = &initial_table, |
5387 |
+ .valid_hooks = NAT_VALID_HOOKS, |
5388 |
+- .check = check, |
5389 |
+ .me = THIS_MODULE, |
5390 |
+ }; |
5391 |
+ |
5392 |
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c |
5393 |
+index f2dbefb61ce83..9a0ae59cdc500 100644 |
5394 |
+--- a/net/bridge/netfilter/ebtables.c |
5395 |
++++ b/net/bridge/netfilter/ebtables.c |
5396 |
+@@ -1040,8 +1040,7 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl, |
5397 |
+ goto free_iterate; |
5398 |
+ } |
5399 |
+ |
5400 |
+- /* the table doesn't like it */ |
5401 |
+- if (t->check && (ret = t->check(newinfo, repl->valid_hooks))) |
5402 |
++ if (repl->valid_hooks != t->valid_hooks) |
5403 |
+ goto free_unlock; |
5404 |
+ |
5405 |
+ if (repl->num_counters && repl->num_counters != t->private->nentries) { |
5406 |
+@@ -1231,11 +1230,6 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table, |
5407 |
+ if (ret != 0) |
5408 |
+ goto free_chainstack; |
5409 |
+ |
5410 |
+- if (table->check && table->check(newinfo, table->valid_hooks)) { |
5411 |
+- ret = -EINVAL; |
5412 |
+- goto free_chainstack; |
5413 |
+- } |
5414 |
+- |
5415 |
+ table->private = newinfo; |
5416 |
+ rwlock_init(&table->lock); |
5417 |
+ mutex_lock(&ebt_mutex); |
5418 |
+diff --git a/net/core/bpf_sk_storage.c b/net/core/bpf_sk_storage.c |
5419 |
+index 1b7f385643b4c..94374d529ea42 100644 |
5420 |
+--- a/net/core/bpf_sk_storage.c |
5421 |
++++ b/net/core/bpf_sk_storage.c |
5422 |
+@@ -310,11 +310,12 @@ BPF_CALL_2(bpf_sk_storage_delete, struct bpf_map *, map, struct sock *, sk) |
5423 |
+ static int bpf_sk_storage_charge(struct bpf_local_storage_map *smap, |
5424 |
+ void *owner, u32 size) |
5425 |
+ { |
5426 |
++ int optmem_max = READ_ONCE(sysctl_optmem_max); |
5427 |
+ struct sock *sk = (struct sock *)owner; |
5428 |
+ |
5429 |
+ /* same check as in sock_kmalloc() */ |
5430 |
+- if (size <= sysctl_optmem_max && |
5431 |
+- atomic_read(&sk->sk_omem_alloc) + size < sysctl_optmem_max) { |
5432 |
++ if (size <= optmem_max && |
5433 |
++ atomic_read(&sk->sk_omem_alloc) + size < optmem_max) { |
5434 |
+ atomic_add(size, &sk->sk_omem_alloc); |
5435 |
+ return 0; |
5436 |
+ } |
5437 |
+diff --git a/net/core/dev.c b/net/core/dev.c |
5438 |
+index 30a1603a7225c..a77a979a4bf75 100644 |
5439 |
+--- a/net/core/dev.c |
5440 |
++++ b/net/core/dev.c |
5441 |
+@@ -4623,7 +4623,7 @@ static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen) |
5442 |
+ struct softnet_data *sd; |
5443 |
+ unsigned int old_flow, new_flow; |
5444 |
+ |
5445 |
+- if (qlen < (netdev_max_backlog >> 1)) |
5446 |
++ if (qlen < (READ_ONCE(netdev_max_backlog) >> 1)) |
5447 |
+ return false; |
5448 |
+ |
5449 |
+ sd = this_cpu_ptr(&softnet_data); |
5450 |
+@@ -4671,7 +4671,7 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu, |
5451 |
+ if (!netif_running(skb->dev)) |
5452 |
+ goto drop; |
5453 |
+ qlen = skb_queue_len(&sd->input_pkt_queue); |
5454 |
+- if (qlen <= netdev_max_backlog && !skb_flow_limit(skb, qlen)) { |
5455 |
++ if (qlen <= READ_ONCE(netdev_max_backlog) && !skb_flow_limit(skb, qlen)) { |
5456 |
+ if (qlen) { |
5457 |
+ enqueue: |
5458 |
+ __skb_queue_tail(&sd->input_pkt_queue, skb); |
5459 |
+@@ -4927,7 +4927,7 @@ static int netif_rx_internal(struct sk_buff *skb) |
5460 |
+ { |
5461 |
+ int ret; |
5462 |
+ |
5463 |
+- net_timestamp_check(netdev_tstamp_prequeue, skb); |
5464 |
++ net_timestamp_check(READ_ONCE(netdev_tstamp_prequeue), skb); |
5465 |
+ |
5466 |
+ trace_netif_rx(skb); |
5467 |
+ |
5468 |
+@@ -5280,7 +5280,7 @@ static int __netif_receive_skb_core(struct sk_buff **pskb, bool pfmemalloc, |
5469 |
+ int ret = NET_RX_DROP; |
5470 |
+ __be16 type; |
5471 |
+ |
5472 |
+- net_timestamp_check(!netdev_tstamp_prequeue, skb); |
5473 |
++ net_timestamp_check(!READ_ONCE(netdev_tstamp_prequeue), skb); |
5474 |
+ |
5475 |
+ trace_netif_receive_skb(skb); |
5476 |
+ |
5477 |
+@@ -5663,7 +5663,7 @@ static int netif_receive_skb_internal(struct sk_buff *skb) |
5478 |
+ { |
5479 |
+ int ret; |
5480 |
+ |
5481 |
+- net_timestamp_check(netdev_tstamp_prequeue, skb); |
5482 |
++ net_timestamp_check(READ_ONCE(netdev_tstamp_prequeue), skb); |
5483 |
+ |
5484 |
+ if (skb_defer_rx_timestamp(skb)) |
5485 |
+ return NET_RX_SUCCESS; |
5486 |
+@@ -5693,7 +5693,7 @@ void netif_receive_skb_list_internal(struct list_head *head) |
5487 |
+ |
5488 |
+ INIT_LIST_HEAD(&sublist); |
5489 |
+ list_for_each_entry_safe(skb, next, head, list) { |
5490 |
+- net_timestamp_check(netdev_tstamp_prequeue, skb); |
5491 |
++ net_timestamp_check(READ_ONCE(netdev_tstamp_prequeue), skb); |
5492 |
+ skb_list_del_init(skb); |
5493 |
+ if (!skb_defer_rx_timestamp(skb)) |
5494 |
+ list_add_tail(&skb->list, &sublist); |
5495 |
+@@ -5917,7 +5917,7 @@ static int process_backlog(struct napi_struct *napi, int quota) |
5496 |
+ net_rps_action_and_irq_enable(sd); |
5497 |
+ } |
5498 |
+ |
5499 |
+- napi->weight = dev_rx_weight; |
5500 |
++ napi->weight = READ_ONCE(dev_rx_weight); |
5501 |
+ while (again) { |
5502 |
+ struct sk_buff *skb; |
5503 |
+ |
5504 |
+@@ -6646,8 +6646,8 @@ static __latent_entropy void net_rx_action(struct softirq_action *h) |
5505 |
+ { |
5506 |
+ struct softnet_data *sd = this_cpu_ptr(&softnet_data); |
5507 |
+ unsigned long time_limit = jiffies + |
5508 |
+- usecs_to_jiffies(netdev_budget_usecs); |
5509 |
+- int budget = netdev_budget; |
5510 |
++ usecs_to_jiffies(READ_ONCE(netdev_budget_usecs)); |
5511 |
++ int budget = READ_ONCE(netdev_budget); |
5512 |
+ LIST_HEAD(list); |
5513 |
+ LIST_HEAD(repoll); |
5514 |
+ |
5515 |
+@@ -10265,7 +10265,7 @@ static struct net_device *netdev_wait_allrefs_any(struct list_head *list) |
5516 |
+ return dev; |
5517 |
+ |
5518 |
+ if (time_after(jiffies, warning_time + |
5519 |
+- netdev_unregister_timeout_secs * HZ)) { |
5520 |
++ READ_ONCE(netdev_unregister_timeout_secs) * HZ)) { |
5521 |
+ list_for_each_entry(dev, list, todo_list) { |
5522 |
+ pr_emerg("unregister_netdevice: waiting for %s to become free. Usage count = %d\n", |
5523 |
+ dev->name, netdev_refcnt_read(dev)); |
5524 |
+diff --git a/net/core/filter.c b/net/core/filter.c |
5525 |
+index 74f05ed6aff29..063176428086b 100644 |
5526 |
+--- a/net/core/filter.c |
5527 |
++++ b/net/core/filter.c |
5528 |
+@@ -1214,10 +1214,11 @@ void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp) |
5529 |
+ static bool __sk_filter_charge(struct sock *sk, struct sk_filter *fp) |
5530 |
+ { |
5531 |
+ u32 filter_size = bpf_prog_size(fp->prog->len); |
5532 |
++ int optmem_max = READ_ONCE(sysctl_optmem_max); |
5533 |
+ |
5534 |
+ /* same check as in sock_kmalloc() */ |
5535 |
+- if (filter_size <= sysctl_optmem_max && |
5536 |
+- atomic_read(&sk->sk_omem_alloc) + filter_size < sysctl_optmem_max) { |
5537 |
++ if (filter_size <= optmem_max && |
5538 |
++ atomic_read(&sk->sk_omem_alloc) + filter_size < optmem_max) { |
5539 |
+ atomic_add(filter_size, &sk->sk_omem_alloc); |
5540 |
+ return true; |
5541 |
+ } |
5542 |
+@@ -1548,7 +1549,7 @@ int sk_reuseport_attach_filter(struct sock_fprog *fprog, struct sock *sk) |
5543 |
+ if (IS_ERR(prog)) |
5544 |
+ return PTR_ERR(prog); |
5545 |
+ |
5546 |
+- if (bpf_prog_size(prog->len) > sysctl_optmem_max) |
5547 |
++ if (bpf_prog_size(prog->len) > READ_ONCE(sysctl_optmem_max)) |
5548 |
+ err = -ENOMEM; |
5549 |
+ else |
5550 |
+ err = reuseport_attach_prog(sk, prog); |
5551 |
+@@ -1615,7 +1616,7 @@ int sk_reuseport_attach_bpf(u32 ufd, struct sock *sk) |
5552 |
+ } |
5553 |
+ } else { |
5554 |
+ /* BPF_PROG_TYPE_SOCKET_FILTER */ |
5555 |
+- if (bpf_prog_size(prog->len) > sysctl_optmem_max) { |
5556 |
++ if (bpf_prog_size(prog->len) > READ_ONCE(sysctl_optmem_max)) { |
5557 |
+ err = -ENOMEM; |
5558 |
+ goto err_prog_put; |
5559 |
+ } |
5560 |
+@@ -5036,14 +5037,14 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname, |
5561 |
+ /* Only some socketops are supported */ |
5562 |
+ switch (optname) { |
5563 |
+ case SO_RCVBUF: |
5564 |
+- val = min_t(u32, val, sysctl_rmem_max); |
5565 |
++ val = min_t(u32, val, READ_ONCE(sysctl_rmem_max)); |
5566 |
+ val = min_t(int, val, INT_MAX / 2); |
5567 |
+ sk->sk_userlocks |= SOCK_RCVBUF_LOCK; |
5568 |
+ WRITE_ONCE(sk->sk_rcvbuf, |
5569 |
+ max_t(int, val * 2, SOCK_MIN_RCVBUF)); |
5570 |
+ break; |
5571 |
+ case SO_SNDBUF: |
5572 |
+- val = min_t(u32, val, sysctl_wmem_max); |
5573 |
++ val = min_t(u32, val, READ_ONCE(sysctl_wmem_max)); |
5574 |
+ val = min_t(int, val, INT_MAX / 2); |
5575 |
+ sk->sk_userlocks |= SOCK_SNDBUF_LOCK; |
5576 |
+ WRITE_ONCE(sk->sk_sndbuf, |
5577 |
+diff --git a/net/core/gro_cells.c b/net/core/gro_cells.c |
5578 |
+index 541c7a72a28a4..21619c70a82b7 100644 |
5579 |
+--- a/net/core/gro_cells.c |
5580 |
++++ b/net/core/gro_cells.c |
5581 |
+@@ -26,7 +26,7 @@ int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb) |
5582 |
+ |
5583 |
+ cell = this_cpu_ptr(gcells->cells); |
5584 |
+ |
5585 |
+- if (skb_queue_len(&cell->napi_skbs) > netdev_max_backlog) { |
5586 |
++ if (skb_queue_len(&cell->napi_skbs) > READ_ONCE(netdev_max_backlog)) { |
5587 |
+ drop: |
5588 |
+ dev_core_stats_rx_dropped_inc(dev); |
5589 |
+ kfree_skb(skb); |
5590 |
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c |
5591 |
+index 5b3559cb1d827..bebf58464d667 100644 |
5592 |
+--- a/net/core/skbuff.c |
5593 |
++++ b/net/core/skbuff.c |
5594 |
+@@ -4772,7 +4772,7 @@ static bool skb_may_tx_timestamp(struct sock *sk, bool tsonly) |
5595 |
+ { |
5596 |
+ bool ret; |
5597 |
+ |
5598 |
+- if (likely(sysctl_tstamp_allow_data || tsonly)) |
5599 |
++ if (likely(READ_ONCE(sysctl_tstamp_allow_data) || tsonly)) |
5600 |
+ return true; |
5601 |
+ |
5602 |
+ read_lock_bh(&sk->sk_callback_lock); |
5603 |
+diff --git a/net/core/sock.c b/net/core/sock.c |
5604 |
+index 2ff40dd0a7a65..16ab5ef749c60 100644 |
5605 |
+--- a/net/core/sock.c |
5606 |
++++ b/net/core/sock.c |
5607 |
+@@ -1100,7 +1100,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, |
5608 |
+ * play 'guess the biggest size' games. RCVBUF/SNDBUF |
5609 |
+ * are treated in BSD as hints |
5610 |
+ */ |
5611 |
+- val = min_t(u32, val, sysctl_wmem_max); |
5612 |
++ val = min_t(u32, val, READ_ONCE(sysctl_wmem_max)); |
5613 |
+ set_sndbuf: |
5614 |
+ /* Ensure val * 2 fits into an int, to prevent max_t() |
5615 |
+ * from treating it as a negative value. |
5616 |
+@@ -1132,7 +1132,7 @@ set_sndbuf: |
5617 |
+ * play 'guess the biggest size' games. RCVBUF/SNDBUF |
5618 |
+ * are treated in BSD as hints |
5619 |
+ */ |
5620 |
+- __sock_set_rcvbuf(sk, min_t(u32, val, sysctl_rmem_max)); |
5621 |
++ __sock_set_rcvbuf(sk, min_t(u32, val, READ_ONCE(sysctl_rmem_max))); |
5622 |
+ break; |
5623 |
+ |
5624 |
+ case SO_RCVBUFFORCE: |
5625 |
+@@ -2535,7 +2535,7 @@ struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size, |
5626 |
+ |
5627 |
+ /* small safe race: SKB_TRUESIZE may differ from final skb->truesize */ |
5628 |
+ if (atomic_read(&sk->sk_omem_alloc) + SKB_TRUESIZE(size) > |
5629 |
+- sysctl_optmem_max) |
5630 |
++ READ_ONCE(sysctl_optmem_max)) |
5631 |
+ return NULL; |
5632 |
+ |
5633 |
+ skb = alloc_skb(size, priority); |
5634 |
+@@ -2553,8 +2553,10 @@ struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size, |
5635 |
+ */ |
5636 |
+ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority) |
5637 |
+ { |
5638 |
+- if ((unsigned int)size <= sysctl_optmem_max && |
5639 |
+- atomic_read(&sk->sk_omem_alloc) + size < sysctl_optmem_max) { |
5640 |
++ int optmem_max = READ_ONCE(sysctl_optmem_max); |
5641 |
++ |
5642 |
++ if ((unsigned int)size <= optmem_max && |
5643 |
++ atomic_read(&sk->sk_omem_alloc) + size < optmem_max) { |
5644 |
+ void *mem; |
5645 |
+ /* First do the add, to avoid the race if kmalloc |
5646 |
+ * might sleep. |
5647 |
+@@ -3307,8 +3309,8 @@ void sock_init_data(struct socket *sock, struct sock *sk) |
5648 |
+ timer_setup(&sk->sk_timer, NULL, 0); |
5649 |
+ |
5650 |
+ sk->sk_allocation = GFP_KERNEL; |
5651 |
+- sk->sk_rcvbuf = sysctl_rmem_default; |
5652 |
+- sk->sk_sndbuf = sysctl_wmem_default; |
5653 |
++ sk->sk_rcvbuf = READ_ONCE(sysctl_rmem_default); |
5654 |
++ sk->sk_sndbuf = READ_ONCE(sysctl_wmem_default); |
5655 |
+ sk->sk_state = TCP_CLOSE; |
5656 |
+ sk_set_socket(sk, sock); |
5657 |
+ |
5658 |
+@@ -3363,7 +3365,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) |
5659 |
+ |
5660 |
+ #ifdef CONFIG_NET_RX_BUSY_POLL |
5661 |
+ sk->sk_napi_id = 0; |
5662 |
+- sk->sk_ll_usec = sysctl_net_busy_read; |
5663 |
++ sk->sk_ll_usec = READ_ONCE(sysctl_net_busy_read); |
5664 |
+ #endif |
5665 |
+ |
5666 |
+ sk->sk_max_pacing_rate = ~0UL; |
5667 |
+diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c |
5668 |
+index 71a13596ea2bf..725891527814c 100644 |
5669 |
+--- a/net/core/sysctl_net_core.c |
5670 |
++++ b/net/core/sysctl_net_core.c |
5671 |
+@@ -234,14 +234,17 @@ static int set_default_qdisc(struct ctl_table *table, int write, |
5672 |
+ static int proc_do_dev_weight(struct ctl_table *table, int write, |
5673 |
+ void *buffer, size_t *lenp, loff_t *ppos) |
5674 |
+ { |
5675 |
+- int ret; |
5676 |
++ static DEFINE_MUTEX(dev_weight_mutex); |
5677 |
++ int ret, weight; |
5678 |
+ |
5679 |
++ mutex_lock(&dev_weight_mutex); |
5680 |
+ ret = proc_dointvec(table, write, buffer, lenp, ppos); |
5681 |
+- if (ret != 0) |
5682 |
+- return ret; |
5683 |
+- |
5684 |
+- dev_rx_weight = weight_p * dev_weight_rx_bias; |
5685 |
+- dev_tx_weight = weight_p * dev_weight_tx_bias; |
5686 |
++ if (!ret && write) { |
5687 |
++ weight = READ_ONCE(weight_p); |
5688 |
++ WRITE_ONCE(dev_rx_weight, weight * dev_weight_rx_bias); |
5689 |
++ WRITE_ONCE(dev_tx_weight, weight * dev_weight_tx_bias); |
5690 |
++ } |
5691 |
++ mutex_unlock(&dev_weight_mutex); |
5692 |
+ |
5693 |
+ return ret; |
5694 |
+ } |
5695 |
+diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c |
5696 |
+index b2366ad540e62..787a44e3222db 100644 |
5697 |
+--- a/net/ipv4/devinet.c |
5698 |
++++ b/net/ipv4/devinet.c |
5699 |
+@@ -2682,23 +2682,27 @@ static __net_init int devinet_init_net(struct net *net) |
5700 |
+ #endif |
5701 |
+ |
5702 |
+ if (!net_eq(net, &init_net)) { |
5703 |
+- if (IS_ENABLED(CONFIG_SYSCTL) && |
5704 |
+- sysctl_devconf_inherit_init_net == 3) { |
5705 |
++ switch (net_inherit_devconf()) { |
5706 |
++ case 3: |
5707 |
+ /* copy from the current netns */ |
5708 |
+ memcpy(all, current->nsproxy->net_ns->ipv4.devconf_all, |
5709 |
+ sizeof(ipv4_devconf)); |
5710 |
+ memcpy(dflt, |
5711 |
+ current->nsproxy->net_ns->ipv4.devconf_dflt, |
5712 |
+ sizeof(ipv4_devconf_dflt)); |
5713 |
+- } else if (!IS_ENABLED(CONFIG_SYSCTL) || |
5714 |
+- sysctl_devconf_inherit_init_net != 2) { |
5715 |
+- /* inherit == 0 or 1: copy from init_net */ |
5716 |
++ break; |
5717 |
++ case 0: |
5718 |
++ case 1: |
5719 |
++ /* copy from init_net */ |
5720 |
+ memcpy(all, init_net.ipv4.devconf_all, |
5721 |
+ sizeof(ipv4_devconf)); |
5722 |
+ memcpy(dflt, init_net.ipv4.devconf_dflt, |
5723 |
+ sizeof(ipv4_devconf_dflt)); |
5724 |
++ break; |
5725 |
++ case 2: |
5726 |
++ /* use compiled values */ |
5727 |
++ break; |
5728 |
+ } |
5729 |
+- /* else inherit == 2: use compiled values */ |
5730 |
+ } |
5731 |
+ |
5732 |
+ #ifdef CONFIG_SYSCTL |
5733 |
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c |
5734 |
+index 00b4bf26fd932..da8b3cc67234d 100644 |
5735 |
+--- a/net/ipv4/ip_output.c |
5736 |
++++ b/net/ipv4/ip_output.c |
5737 |
+@@ -1712,7 +1712,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, |
5738 |
+ |
5739 |
+ sk->sk_protocol = ip_hdr(skb)->protocol; |
5740 |
+ sk->sk_bound_dev_if = arg->bound_dev_if; |
5741 |
+- sk->sk_sndbuf = sysctl_wmem_default; |
5742 |
++ sk->sk_sndbuf = READ_ONCE(sysctl_wmem_default); |
5743 |
+ ipc.sockc.mark = fl4.flowi4_mark; |
5744 |
+ err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base, |
5745 |
+ len, 0, &ipc, &rt, MSG_DONTWAIT); |
5746 |
+diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c |
5747 |
+index a8a323ecbb54b..e49a61a053a68 100644 |
5748 |
+--- a/net/ipv4/ip_sockglue.c |
5749 |
++++ b/net/ipv4/ip_sockglue.c |
5750 |
+@@ -772,7 +772,7 @@ static int ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval, int optlen) |
5751 |
+ |
5752 |
+ if (optlen < GROUP_FILTER_SIZE(0)) |
5753 |
+ return -EINVAL; |
5754 |
+- if (optlen > sysctl_optmem_max) |
5755 |
++ if (optlen > READ_ONCE(sysctl_optmem_max)) |
5756 |
+ return -ENOBUFS; |
5757 |
+ |
5758 |
+ gsf = memdup_sockptr(optval, optlen); |
5759 |
+@@ -808,7 +808,7 @@ static int compat_ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval, |
5760 |
+ |
5761 |
+ if (optlen < size0) |
5762 |
+ return -EINVAL; |
5763 |
+- if (optlen > sysctl_optmem_max - 4) |
5764 |
++ if (optlen > READ_ONCE(sysctl_optmem_max) - 4) |
5765 |
+ return -ENOBUFS; |
5766 |
+ |
5767 |
+ p = kmalloc(optlen + 4, GFP_KERNEL); |
5768 |
+@@ -1233,7 +1233,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, int optname, |
5769 |
+ |
5770 |
+ if (optlen < IP_MSFILTER_SIZE(0)) |
5771 |
+ goto e_inval; |
5772 |
+- if (optlen > sysctl_optmem_max) { |
5773 |
++ if (optlen > READ_ONCE(sysctl_optmem_max)) { |
5774 |
+ err = -ENOBUFS; |
5775 |
+ break; |
5776 |
+ } |
5777 |
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c |
5778 |
+index 3ae2ea0488838..3d446773ff2a5 100644 |
5779 |
+--- a/net/ipv4/tcp.c |
5780 |
++++ b/net/ipv4/tcp.c |
5781 |
+@@ -1000,7 +1000,7 @@ new_segment: |
5782 |
+ |
5783 |
+ i = skb_shinfo(skb)->nr_frags; |
5784 |
+ can_coalesce = skb_can_coalesce(skb, i, page, offset); |
5785 |
+- if (!can_coalesce && i >= sysctl_max_skb_frags) { |
5786 |
++ if (!can_coalesce && i >= READ_ONCE(sysctl_max_skb_frags)) { |
5787 |
+ tcp_mark_push(tp, skb); |
5788 |
+ goto new_segment; |
5789 |
+ } |
5790 |
+@@ -1348,7 +1348,7 @@ new_segment: |
5791 |
+ |
5792 |
+ if (!skb_can_coalesce(skb, i, pfrag->page, |
5793 |
+ pfrag->offset)) { |
5794 |
+- if (i >= sysctl_max_skb_frags) { |
5795 |
++ if (i >= READ_ONCE(sysctl_max_skb_frags)) { |
5796 |
+ tcp_mark_push(tp, skb); |
5797 |
+ goto new_segment; |
5798 |
+ } |
5799 |
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c |
5800 |
+index aed0c5f828bef..84314de754f87 100644 |
5801 |
+--- a/net/ipv4/tcp_output.c |
5802 |
++++ b/net/ipv4/tcp_output.c |
5803 |
+@@ -239,7 +239,7 @@ void tcp_select_initial_window(const struct sock *sk, int __space, __u32 mss, |
5804 |
+ if (wscale_ok) { |
5805 |
+ /* Set window scaling on max possible window */ |
5806 |
+ space = max_t(u32, space, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2])); |
5807 |
+- space = max_t(u32, space, sysctl_rmem_max); |
5808 |
++ space = max_t(u32, space, READ_ONCE(sysctl_rmem_max)); |
5809 |
+ space = min_t(u32, space, *window_clamp); |
5810 |
+ *rcv_wscale = clamp_t(int, ilog2(space) - 15, |
5811 |
+ 0, TCP_MAX_WSCALE); |
5812 |
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c |
5813 |
+index 49cc6587dd771..b738eb7e1cae8 100644 |
5814 |
+--- a/net/ipv6/addrconf.c |
5815 |
++++ b/net/ipv6/addrconf.c |
5816 |
+@@ -7158,9 +7158,8 @@ static int __net_init addrconf_init_net(struct net *net) |
5817 |
+ if (!dflt) |
5818 |
+ goto err_alloc_dflt; |
5819 |
+ |
5820 |
+- if (IS_ENABLED(CONFIG_SYSCTL) && |
5821 |
+- !net_eq(net, &init_net)) { |
5822 |
+- switch (sysctl_devconf_inherit_init_net) { |
5823 |
++ if (!net_eq(net, &init_net)) { |
5824 |
++ switch (net_inherit_devconf()) { |
5825 |
+ case 1: /* copy from init_net */ |
5826 |
+ memcpy(all, init_net.ipv6.devconf_all, |
5827 |
+ sizeof(ipv6_devconf)); |
5828 |
+diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c |
5829 |
+index 222f6bf220ba0..e0dcc7a193df2 100644 |
5830 |
+--- a/net/ipv6/ipv6_sockglue.c |
5831 |
++++ b/net/ipv6/ipv6_sockglue.c |
5832 |
+@@ -210,7 +210,7 @@ static int ipv6_set_mcast_msfilter(struct sock *sk, sockptr_t optval, |
5833 |
+ |
5834 |
+ if (optlen < GROUP_FILTER_SIZE(0)) |
5835 |
+ return -EINVAL; |
5836 |
+- if (optlen > sysctl_optmem_max) |
5837 |
++ if (optlen > READ_ONCE(sysctl_optmem_max)) |
5838 |
+ return -ENOBUFS; |
5839 |
+ |
5840 |
+ gsf = memdup_sockptr(optval, optlen); |
5841 |
+@@ -244,7 +244,7 @@ static int compat_ipv6_set_mcast_msfilter(struct sock *sk, sockptr_t optval, |
5842 |
+ |
5843 |
+ if (optlen < size0) |
5844 |
+ return -EINVAL; |
5845 |
+- if (optlen > sysctl_optmem_max - 4) |
5846 |
++ if (optlen > READ_ONCE(sysctl_optmem_max) - 4) |
5847 |
+ return -ENOBUFS; |
5848 |
+ |
5849 |
+ p = kmalloc(optlen + 4, GFP_KERNEL); |
5850 |
+diff --git a/net/key/af_key.c b/net/key/af_key.c |
5851 |
+index fb16d7c4e1b8d..20e73643b9c89 100644 |
5852 |
+--- a/net/key/af_key.c |
5853 |
++++ b/net/key/af_key.c |
5854 |
+@@ -1697,9 +1697,12 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, const struct sad |
5855 |
+ pfk->registered |= (1<<hdr->sadb_msg_satype); |
5856 |
+ } |
5857 |
+ |
5858 |
++ mutex_lock(&pfkey_mutex); |
5859 |
+ xfrm_probe_algs(); |
5860 |
+ |
5861 |
+ supp_skb = compose_sadb_supported(hdr, GFP_KERNEL | __GFP_ZERO); |
5862 |
++ mutex_unlock(&pfkey_mutex); |
5863 |
++ |
5864 |
+ if (!supp_skb) { |
5865 |
+ if (hdr->sadb_msg_satype != SADB_SATYPE_UNSPEC) |
5866 |
+ pfk->registered &= ~(1<<hdr->sadb_msg_satype); |
5867 |
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c |
5868 |
+index 3d90fa9653ef3..513f571a082ba 100644 |
5869 |
+--- a/net/mptcp/protocol.c |
5870 |
++++ b/net/mptcp/protocol.c |
5871 |
+@@ -1299,7 +1299,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, |
5872 |
+ |
5873 |
+ i = skb_shinfo(skb)->nr_frags; |
5874 |
+ can_coalesce = skb_can_coalesce(skb, i, dfrag->page, offset); |
5875 |
+- if (!can_coalesce && i >= sysctl_max_skb_frags) { |
5876 |
++ if (!can_coalesce && i >= READ_ONCE(sysctl_max_skb_frags)) { |
5877 |
+ tcp_mark_push(tcp_sk(ssk), skb); |
5878 |
+ goto alloc_skb; |
5879 |
+ } |
5880 |
+diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c |
5881 |
+index 9d43277b8b4fe..a56fd0b5a430a 100644 |
5882 |
+--- a/net/netfilter/ipvs/ip_vs_sync.c |
5883 |
++++ b/net/netfilter/ipvs/ip_vs_sync.c |
5884 |
+@@ -1280,12 +1280,12 @@ static void set_sock_size(struct sock *sk, int mode, int val) |
5885 |
+ lock_sock(sk); |
5886 |
+ if (mode) { |
5887 |
+ val = clamp_t(int, val, (SOCK_MIN_SNDBUF + 1) / 2, |
5888 |
+- sysctl_wmem_max); |
5889 |
++ READ_ONCE(sysctl_wmem_max)); |
5890 |
+ sk->sk_sndbuf = val * 2; |
5891 |
+ sk->sk_userlocks |= SOCK_SNDBUF_LOCK; |
5892 |
+ } else { |
5893 |
+ val = clamp_t(int, val, (SOCK_MIN_RCVBUF + 1) / 2, |
5894 |
+- sysctl_rmem_max); |
5895 |
++ READ_ONCE(sysctl_rmem_max)); |
5896 |
+ sk->sk_rcvbuf = val * 2; |
5897 |
+ sk->sk_userlocks |= SOCK_RCVBUF_LOCK; |
5898 |
+ } |
5899 |
+diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c |
5900 |
+index f2def06d10709..483b18d35cade 100644 |
5901 |
+--- a/net/netfilter/nf_flow_table_core.c |
5902 |
++++ b/net/netfilter/nf_flow_table_core.c |
5903 |
+@@ -442,12 +442,17 @@ static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table, |
5904 |
+ } |
5905 |
+ } |
5906 |
+ |
5907 |
++void nf_flow_table_gc_run(struct nf_flowtable *flow_table) |
5908 |
++{ |
5909 |
++ nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL); |
5910 |
++} |
5911 |
++ |
5912 |
+ static void nf_flow_offload_work_gc(struct work_struct *work) |
5913 |
+ { |
5914 |
+ struct nf_flowtable *flow_table; |
5915 |
+ |
5916 |
+ flow_table = container_of(work, struct nf_flowtable, gc_work.work); |
5917 |
+- nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL); |
5918 |
++ nf_flow_table_gc_run(flow_table); |
5919 |
+ queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ); |
5920 |
+ } |
5921 |
+ |
5922 |
+@@ -605,11 +610,11 @@ void nf_flow_table_free(struct nf_flowtable *flow_table) |
5923 |
+ mutex_unlock(&flowtable_lock); |
5924 |
+ |
5925 |
+ cancel_delayed_work_sync(&flow_table->gc_work); |
5926 |
+- nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); |
5927 |
+- nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL); |
5928 |
+ nf_flow_table_offload_flush(flow_table); |
5929 |
+- if (nf_flowtable_hw_offload(flow_table)) |
5930 |
+- nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL); |
5931 |
++ /* ... no more pending work after this stage ... */ |
5932 |
++ nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); |
5933 |
++ nf_flow_table_gc_run(flow_table); |
5934 |
++ nf_flow_table_offload_flush_cleanup(flow_table); |
5935 |
+ rhashtable_destroy(&flow_table->rhashtable); |
5936 |
+ } |
5937 |
+ EXPORT_SYMBOL_GPL(nf_flow_table_free); |
5938 |
+diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c |
5939 |
+index 11b6e19420920..4d1169b634c5f 100644 |
5940 |
+--- a/net/netfilter/nf_flow_table_offload.c |
5941 |
++++ b/net/netfilter/nf_flow_table_offload.c |
5942 |
+@@ -1063,6 +1063,14 @@ void nf_flow_offload_stats(struct nf_flowtable *flowtable, |
5943 |
+ flow_offload_queue_work(offload); |
5944 |
+ } |
5945 |
+ |
5946 |
++void nf_flow_table_offload_flush_cleanup(struct nf_flowtable *flowtable) |
5947 |
++{ |
5948 |
++ if (nf_flowtable_hw_offload(flowtable)) { |
5949 |
++ flush_workqueue(nf_flow_offload_del_wq); |
5950 |
++ nf_flow_table_gc_run(flowtable); |
5951 |
++ } |
5952 |
++} |
5953 |
++ |
5954 |
+ void nf_flow_table_offload_flush(struct nf_flowtable *flowtable) |
5955 |
+ { |
5956 |
+ if (nf_flowtable_hw_offload(flowtable)) { |
5957 |
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c |
5958 |
+index 4bd6e9427c918..bc690238a3c56 100644 |
5959 |
+--- a/net/netfilter/nf_tables_api.c |
5960 |
++++ b/net/netfilter/nf_tables_api.c |
5961 |
+@@ -32,7 +32,6 @@ static LIST_HEAD(nf_tables_objects); |
5962 |
+ static LIST_HEAD(nf_tables_flowtables); |
5963 |
+ static LIST_HEAD(nf_tables_destroy_list); |
5964 |
+ static DEFINE_SPINLOCK(nf_tables_destroy_list_lock); |
5965 |
+-static u64 table_handle; |
5966 |
+ |
5967 |
+ enum { |
5968 |
+ NFT_VALIDATE_SKIP = 0, |
5969 |
+@@ -1235,7 +1234,7 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info, |
5970 |
+ INIT_LIST_HEAD(&table->flowtables); |
5971 |
+ table->family = family; |
5972 |
+ table->flags = flags; |
5973 |
+- table->handle = ++table_handle; |
5974 |
++ table->handle = ++nft_net->table_handle; |
5975 |
+ if (table->flags & NFT_TABLE_F_OWNER) |
5976 |
+ table->nlpid = NETLINK_CB(skb).portid; |
5977 |
+ |
5978 |
+@@ -2196,9 +2195,9 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, |
5979 |
+ struct netlink_ext_ack *extack) |
5980 |
+ { |
5981 |
+ const struct nlattr * const *nla = ctx->nla; |
5982 |
++ struct nft_stats __percpu *stats = NULL; |
5983 |
+ struct nft_table *table = ctx->table; |
5984 |
+ struct nft_base_chain *basechain; |
5985 |
+- struct nft_stats __percpu *stats; |
5986 |
+ struct net *net = ctx->net; |
5987 |
+ char name[NFT_NAME_MAXLEN]; |
5988 |
+ struct nft_rule_blob *blob; |
5989 |
+@@ -2236,7 +2235,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, |
5990 |
+ return PTR_ERR(stats); |
5991 |
+ } |
5992 |
+ rcu_assign_pointer(basechain->stats, stats); |
5993 |
+- static_branch_inc(&nft_counters_enabled); |
5994 |
+ } |
5995 |
+ |
5996 |
+ err = nft_basechain_init(basechain, family, &hook, flags); |
5997 |
+@@ -2319,6 +2317,9 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, |
5998 |
+ goto err_unregister_hook; |
5999 |
+ } |
6000 |
+ |
6001 |
++ if (stats) |
6002 |
++ static_branch_inc(&nft_counters_enabled); |
6003 |
++ |
6004 |
+ table->use++; |
6005 |
+ |
6006 |
+ return 0; |
6007 |
+@@ -2574,6 +2575,9 @@ static int nf_tables_newchain(struct sk_buff *skb, const struct nfnl_info *info, |
6008 |
+ nft_ctx_init(&ctx, net, skb, info->nlh, family, table, chain, nla); |
6009 |
+ |
6010 |
+ if (chain != NULL) { |
6011 |
++ if (chain->flags & NFT_CHAIN_BINDING) |
6012 |
++ return -EINVAL; |
6013 |
++ |
6014 |
+ if (info->nlh->nlmsg_flags & NLM_F_EXCL) { |
6015 |
+ NL_SET_BAD_ATTR(extack, attr); |
6016 |
+ return -EEXIST; |
6017 |
+@@ -9653,6 +9657,8 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, |
6018 |
+ return PTR_ERR(chain); |
6019 |
+ if (nft_is_base_chain(chain)) |
6020 |
+ return -EOPNOTSUPP; |
6021 |
++ if (nft_chain_is_bound(chain)) |
6022 |
++ return -EINVAL; |
6023 |
+ if (desc->flags & NFT_DATA_DESC_SETELEM && |
6024 |
+ chain->flags & NFT_CHAIN_BINDING) |
6025 |
+ return -EINVAL; |
6026 |
+diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c |
6027 |
+index 5eed18f90b020..175d666c8d87e 100644 |
6028 |
+--- a/net/netfilter/nft_osf.c |
6029 |
++++ b/net/netfilter/nft_osf.c |
6030 |
+@@ -115,9 +115,21 @@ static int nft_osf_validate(const struct nft_ctx *ctx, |
6031 |
+ const struct nft_expr *expr, |
6032 |
+ const struct nft_data **data) |
6033 |
+ { |
6034 |
+- return nft_chain_validate_hooks(ctx->chain, (1 << NF_INET_LOCAL_IN) | |
6035 |
+- (1 << NF_INET_PRE_ROUTING) | |
6036 |
+- (1 << NF_INET_FORWARD)); |
6037 |
++ unsigned int hooks; |
6038 |
++ |
6039 |
++ switch (ctx->family) { |
6040 |
++ case NFPROTO_IPV4: |
6041 |
++ case NFPROTO_IPV6: |
6042 |
++ case NFPROTO_INET: |
6043 |
++ hooks = (1 << NF_INET_LOCAL_IN) | |
6044 |
++ (1 << NF_INET_PRE_ROUTING) | |
6045 |
++ (1 << NF_INET_FORWARD); |
6046 |
++ break; |
6047 |
++ default: |
6048 |
++ return -EOPNOTSUPP; |
6049 |
++ } |
6050 |
++ |
6051 |
++ return nft_chain_validate_hooks(ctx->chain, hooks); |
6052 |
+ } |
6053 |
+ |
6054 |
+ static bool nft_osf_reduce(struct nft_regs_track *track, |
6055 |
+diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c |
6056 |
+index 2e7ac007cb30f..eb0e40c297121 100644 |
6057 |
+--- a/net/netfilter/nft_payload.c |
6058 |
++++ b/net/netfilter/nft_payload.c |
6059 |
+@@ -740,17 +740,23 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, |
6060 |
+ const struct nlattr * const tb[]) |
6061 |
+ { |
6062 |
+ struct nft_payload_set *priv = nft_expr_priv(expr); |
6063 |
++ u32 csum_offset, csum_type = NFT_PAYLOAD_CSUM_NONE; |
6064 |
++ int err; |
6065 |
+ |
6066 |
+ priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE])); |
6067 |
+ priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); |
6068 |
+ priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); |
6069 |
+ |
6070 |
+ if (tb[NFTA_PAYLOAD_CSUM_TYPE]) |
6071 |
+- priv->csum_type = |
6072 |
+- ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_TYPE])); |
6073 |
+- if (tb[NFTA_PAYLOAD_CSUM_OFFSET]) |
6074 |
+- priv->csum_offset = |
6075 |
+- ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_OFFSET])); |
6076 |
++ csum_type = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_TYPE])); |
6077 |
++ if (tb[NFTA_PAYLOAD_CSUM_OFFSET]) { |
6078 |
++ err = nft_parse_u32_check(tb[NFTA_PAYLOAD_CSUM_OFFSET], U8_MAX, |
6079 |
++ &csum_offset); |
6080 |
++ if (err < 0) |
6081 |
++ return err; |
6082 |
++ |
6083 |
++ priv->csum_offset = csum_offset; |
6084 |
++ } |
6085 |
+ if (tb[NFTA_PAYLOAD_CSUM_FLAGS]) { |
6086 |
+ u32 flags; |
6087 |
+ |
6088 |
+@@ -761,7 +767,7 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, |
6089 |
+ priv->csum_flags = flags; |
6090 |
+ } |
6091 |
+ |
6092 |
+- switch (priv->csum_type) { |
6093 |
++ switch (csum_type) { |
6094 |
+ case NFT_PAYLOAD_CSUM_NONE: |
6095 |
+ case NFT_PAYLOAD_CSUM_INET: |
6096 |
+ break; |
6097 |
+@@ -775,6 +781,7 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, |
6098 |
+ default: |
6099 |
+ return -EOPNOTSUPP; |
6100 |
+ } |
6101 |
++ priv->csum_type = csum_type; |
6102 |
+ |
6103 |
+ return nft_parse_register_load(tb[NFTA_PAYLOAD_SREG], &priv->sreg, |
6104 |
+ priv->len); |
6105 |
+@@ -833,6 +840,7 @@ nft_payload_select_ops(const struct nft_ctx *ctx, |
6106 |
+ { |
6107 |
+ enum nft_payload_bases base; |
6108 |
+ unsigned int offset, len; |
6109 |
++ int err; |
6110 |
+ |
6111 |
+ if (tb[NFTA_PAYLOAD_BASE] == NULL || |
6112 |
+ tb[NFTA_PAYLOAD_OFFSET] == NULL || |
6113 |
+@@ -859,8 +867,13 @@ nft_payload_select_ops(const struct nft_ctx *ctx, |
6114 |
+ if (tb[NFTA_PAYLOAD_DREG] == NULL) |
6115 |
+ return ERR_PTR(-EINVAL); |
6116 |
+ |
6117 |
+- offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); |
6118 |
+- len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); |
6119 |
++ err = nft_parse_u32_check(tb[NFTA_PAYLOAD_OFFSET], U8_MAX, &offset); |
6120 |
++ if (err < 0) |
6121 |
++ return ERR_PTR(err); |
6122 |
++ |
6123 |
++ err = nft_parse_u32_check(tb[NFTA_PAYLOAD_LEN], U8_MAX, &len); |
6124 |
++ if (err < 0) |
6125 |
++ return ERR_PTR(err); |
6126 |
+ |
6127 |
+ if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) && |
6128 |
+ base != NFT_PAYLOAD_LL_HEADER && base != NFT_PAYLOAD_INNER_HEADER) |
6129 |
+diff --git a/net/netfilter/nft_tproxy.c b/net/netfilter/nft_tproxy.c |
6130 |
+index 801f013971dfa..a701ad64f10af 100644 |
6131 |
+--- a/net/netfilter/nft_tproxy.c |
6132 |
++++ b/net/netfilter/nft_tproxy.c |
6133 |
+@@ -312,6 +312,13 @@ static int nft_tproxy_dump(struct sk_buff *skb, |
6134 |
+ return 0; |
6135 |
+ } |
6136 |
+ |
6137 |
++static int nft_tproxy_validate(const struct nft_ctx *ctx, |
6138 |
++ const struct nft_expr *expr, |
6139 |
++ const struct nft_data **data) |
6140 |
++{ |
6141 |
++ return nft_chain_validate_hooks(ctx->chain, 1 << NF_INET_PRE_ROUTING); |
6142 |
++} |
6143 |
++ |
6144 |
+ static struct nft_expr_type nft_tproxy_type; |
6145 |
+ static const struct nft_expr_ops nft_tproxy_ops = { |
6146 |
+ .type = &nft_tproxy_type, |
6147 |
+@@ -321,6 +328,7 @@ static const struct nft_expr_ops nft_tproxy_ops = { |
6148 |
+ .destroy = nft_tproxy_destroy, |
6149 |
+ .dump = nft_tproxy_dump, |
6150 |
+ .reduce = NFT_REDUCE_READONLY, |
6151 |
++ .validate = nft_tproxy_validate, |
6152 |
+ }; |
6153 |
+ |
6154 |
+ static struct nft_expr_type nft_tproxy_type __read_mostly = { |
6155 |
+diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c |
6156 |
+index d0f9b1d51b0e9..96b03e0bf74ff 100644 |
6157 |
+--- a/net/netfilter/nft_tunnel.c |
6158 |
++++ b/net/netfilter/nft_tunnel.c |
6159 |
+@@ -161,6 +161,7 @@ static const struct nft_expr_ops nft_tunnel_get_ops = { |
6160 |
+ |
6161 |
+ static struct nft_expr_type nft_tunnel_type __read_mostly = { |
6162 |
+ .name = "tunnel", |
6163 |
++ .family = NFPROTO_NETDEV, |
6164 |
+ .ops = &nft_tunnel_get_ops, |
6165 |
+ .policy = nft_tunnel_policy, |
6166 |
+ .maxattr = NFTA_TUNNEL_MAX, |
6167 |
+diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c |
6168 |
+index 11c45c8c6c164..036d92c0ad794 100644 |
6169 |
+--- a/net/rose/rose_loopback.c |
6170 |
++++ b/net/rose/rose_loopback.c |
6171 |
+@@ -96,7 +96,8 @@ static void rose_loopback_timer(struct timer_list *unused) |
6172 |
+ } |
6173 |
+ |
6174 |
+ if (frametype == ROSE_CALL_REQUEST) { |
6175 |
+- if (!rose_loopback_neigh->dev) { |
6176 |
++ if (!rose_loopback_neigh->dev && |
6177 |
++ !rose_loopback_neigh->loopback) { |
6178 |
+ kfree_skb(skb); |
6179 |
+ continue; |
6180 |
+ } |
6181 |
+diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c |
6182 |
+index 84d0a41096450..6401cdf7a6246 100644 |
6183 |
+--- a/net/rxrpc/call_object.c |
6184 |
++++ b/net/rxrpc/call_object.c |
6185 |
+@@ -285,8 +285,10 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, |
6186 |
+ _enter("%p,%lx", rx, p->user_call_ID); |
6187 |
+ |
6188 |
+ limiter = rxrpc_get_call_slot(p, gfp); |
6189 |
+- if (!limiter) |
6190 |
++ if (!limiter) { |
6191 |
++ release_sock(&rx->sk); |
6192 |
+ return ERR_PTR(-ERESTARTSYS); |
6193 |
++ } |
6194 |
+ |
6195 |
+ call = rxrpc_alloc_client_call(rx, srx, gfp, debug_id); |
6196 |
+ if (IS_ERR(call)) { |
6197 |
+diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c |
6198 |
+index 1d38e279e2efa..3c3a626459deb 100644 |
6199 |
+--- a/net/rxrpc/sendmsg.c |
6200 |
++++ b/net/rxrpc/sendmsg.c |
6201 |
+@@ -51,10 +51,7 @@ static int rxrpc_wait_for_tx_window_intr(struct rxrpc_sock *rx, |
6202 |
+ return sock_intr_errno(*timeo); |
6203 |
+ |
6204 |
+ trace_rxrpc_transmit(call, rxrpc_transmit_wait); |
6205 |
+- mutex_unlock(&call->user_mutex); |
6206 |
+ *timeo = schedule_timeout(*timeo); |
6207 |
+- if (mutex_lock_interruptible(&call->user_mutex) < 0) |
6208 |
+- return sock_intr_errno(*timeo); |
6209 |
+ } |
6210 |
+ } |
6211 |
+ |
6212 |
+@@ -290,37 +287,48 @@ out: |
6213 |
+ static int rxrpc_send_data(struct rxrpc_sock *rx, |
6214 |
+ struct rxrpc_call *call, |
6215 |
+ struct msghdr *msg, size_t len, |
6216 |
+- rxrpc_notify_end_tx_t notify_end_tx) |
6217 |
++ rxrpc_notify_end_tx_t notify_end_tx, |
6218 |
++ bool *_dropped_lock) |
6219 |
+ { |
6220 |
+ struct rxrpc_skb_priv *sp; |
6221 |
+ struct sk_buff *skb; |
6222 |
+ struct sock *sk = &rx->sk; |
6223 |
++ enum rxrpc_call_state state; |
6224 |
+ long timeo; |
6225 |
+- bool more; |
6226 |
+- int ret, copied; |
6227 |
++ bool more = msg->msg_flags & MSG_MORE; |
6228 |
++ int ret, copied = 0; |
6229 |
+ |
6230 |
+ timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); |
6231 |
+ |
6232 |
+ /* this should be in poll */ |
6233 |
+ sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
6234 |
+ |
6235 |
++reload: |
6236 |
++ ret = -EPIPE; |
6237 |
+ if (sk->sk_shutdown & SEND_SHUTDOWN) |
6238 |
+- return -EPIPE; |
6239 |
+- |
6240 |
+- more = msg->msg_flags & MSG_MORE; |
6241 |
+- |
6242 |
++ goto maybe_error; |
6243 |
++ state = READ_ONCE(call->state); |
6244 |
++ ret = -ESHUTDOWN; |
6245 |
++ if (state >= RXRPC_CALL_COMPLETE) |
6246 |
++ goto maybe_error; |
6247 |
++ ret = -EPROTO; |
6248 |
++ if (state != RXRPC_CALL_CLIENT_SEND_REQUEST && |
6249 |
++ state != RXRPC_CALL_SERVER_ACK_REQUEST && |
6250 |
++ state != RXRPC_CALL_SERVER_SEND_REPLY) |
6251 |
++ goto maybe_error; |
6252 |
++ |
6253 |
++ ret = -EMSGSIZE; |
6254 |
+ if (call->tx_total_len != -1) { |
6255 |
+- if (len > call->tx_total_len) |
6256 |
+- return -EMSGSIZE; |
6257 |
+- if (!more && len != call->tx_total_len) |
6258 |
+- return -EMSGSIZE; |
6259 |
++ if (len - copied > call->tx_total_len) |
6260 |
++ goto maybe_error; |
6261 |
++ if (!more && len - copied != call->tx_total_len) |
6262 |
++ goto maybe_error; |
6263 |
+ } |
6264 |
+ |
6265 |
+ skb = call->tx_pending; |
6266 |
+ call->tx_pending = NULL; |
6267 |
+ rxrpc_see_skb(skb, rxrpc_skb_seen); |
6268 |
+ |
6269 |
+- copied = 0; |
6270 |
+ do { |
6271 |
+ /* Check to see if there's a ping ACK to reply to. */ |
6272 |
+ if (call->ackr_reason == RXRPC_ACK_PING_RESPONSE) |
6273 |
+@@ -331,16 +339,8 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, |
6274 |
+ |
6275 |
+ _debug("alloc"); |
6276 |
+ |
6277 |
+- if (!rxrpc_check_tx_space(call, NULL)) { |
6278 |
+- ret = -EAGAIN; |
6279 |
+- if (msg->msg_flags & MSG_DONTWAIT) |
6280 |
+- goto maybe_error; |
6281 |
+- ret = rxrpc_wait_for_tx_window(rx, call, |
6282 |
+- &timeo, |
6283 |
+- msg->msg_flags & MSG_WAITALL); |
6284 |
+- if (ret < 0) |
6285 |
+- goto maybe_error; |
6286 |
+- } |
6287 |
++ if (!rxrpc_check_tx_space(call, NULL)) |
6288 |
++ goto wait_for_space; |
6289 |
+ |
6290 |
+ /* Work out the maximum size of a packet. Assume that |
6291 |
+ * the security header is going to be in the padded |
6292 |
+@@ -468,6 +468,27 @@ maybe_error: |
6293 |
+ efault: |
6294 |
+ ret = -EFAULT; |
6295 |
+ goto out; |
6296 |
++ |
6297 |
++wait_for_space: |
6298 |
++ ret = -EAGAIN; |
6299 |
++ if (msg->msg_flags & MSG_DONTWAIT) |
6300 |
++ goto maybe_error; |
6301 |
++ mutex_unlock(&call->user_mutex); |
6302 |
++ *_dropped_lock = true; |
6303 |
++ ret = rxrpc_wait_for_tx_window(rx, call, &timeo, |
6304 |
++ msg->msg_flags & MSG_WAITALL); |
6305 |
++ if (ret < 0) |
6306 |
++ goto maybe_error; |
6307 |
++ if (call->interruptibility == RXRPC_INTERRUPTIBLE) { |
6308 |
++ if (mutex_lock_interruptible(&call->user_mutex) < 0) { |
6309 |
++ ret = sock_intr_errno(timeo); |
6310 |
++ goto maybe_error; |
6311 |
++ } |
6312 |
++ } else { |
6313 |
++ mutex_lock(&call->user_mutex); |
6314 |
++ } |
6315 |
++ *_dropped_lock = false; |
6316 |
++ goto reload; |
6317 |
+ } |
6318 |
+ |
6319 |
+ /* |
6320 |
+@@ -629,6 +650,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) |
6321 |
+ enum rxrpc_call_state state; |
6322 |
+ struct rxrpc_call *call; |
6323 |
+ unsigned long now, j; |
6324 |
++ bool dropped_lock = false; |
6325 |
+ int ret; |
6326 |
+ |
6327 |
+ struct rxrpc_send_params p = { |
6328 |
+@@ -737,21 +759,13 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) |
6329 |
+ ret = rxrpc_send_abort_packet(call); |
6330 |
+ } else if (p.command != RXRPC_CMD_SEND_DATA) { |
6331 |
+ ret = -EINVAL; |
6332 |
+- } else if (rxrpc_is_client_call(call) && |
6333 |
+- state != RXRPC_CALL_CLIENT_SEND_REQUEST) { |
6334 |
+- /* request phase complete for this client call */ |
6335 |
+- ret = -EPROTO; |
6336 |
+- } else if (rxrpc_is_service_call(call) && |
6337 |
+- state != RXRPC_CALL_SERVER_ACK_REQUEST && |
6338 |
+- state != RXRPC_CALL_SERVER_SEND_REPLY) { |
6339 |
+- /* Reply phase not begun or not complete for service call. */ |
6340 |
+- ret = -EPROTO; |
6341 |
+ } else { |
6342 |
+- ret = rxrpc_send_data(rx, call, msg, len, NULL); |
6343 |
++ ret = rxrpc_send_data(rx, call, msg, len, NULL, &dropped_lock); |
6344 |
+ } |
6345 |
+ |
6346 |
+ out_put_unlock: |
6347 |
+- mutex_unlock(&call->user_mutex); |
6348 |
++ if (!dropped_lock) |
6349 |
++ mutex_unlock(&call->user_mutex); |
6350 |
+ error_put: |
6351 |
+ rxrpc_put_call(call, rxrpc_call_put); |
6352 |
+ _leave(" = %d", ret); |
6353 |
+@@ -779,6 +793,7 @@ int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, |
6354 |
+ struct msghdr *msg, size_t len, |
6355 |
+ rxrpc_notify_end_tx_t notify_end_tx) |
6356 |
+ { |
6357 |
++ bool dropped_lock = false; |
6358 |
+ int ret; |
6359 |
+ |
6360 |
+ _enter("{%d,%s},", call->debug_id, rxrpc_call_states[call->state]); |
6361 |
+@@ -796,7 +811,7 @@ int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, |
6362 |
+ case RXRPC_CALL_SERVER_ACK_REQUEST: |
6363 |
+ case RXRPC_CALL_SERVER_SEND_REPLY: |
6364 |
+ ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len, |
6365 |
+- notify_end_tx); |
6366 |
++ notify_end_tx, &dropped_lock); |
6367 |
+ break; |
6368 |
+ case RXRPC_CALL_COMPLETE: |
6369 |
+ read_lock_bh(&call->state_lock); |
6370 |
+@@ -810,7 +825,8 @@ int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, |
6371 |
+ break; |
6372 |
+ } |
6373 |
+ |
6374 |
+- mutex_unlock(&call->user_mutex); |
6375 |
++ if (!dropped_lock) |
6376 |
++ mutex_unlock(&call->user_mutex); |
6377 |
+ _leave(" = %d", ret); |
6378 |
+ return ret; |
6379 |
+ } |
6380 |
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c |
6381 |
+index dba0b3e24af5e..a64c3c1541118 100644 |
6382 |
+--- a/net/sched/sch_generic.c |
6383 |
++++ b/net/sched/sch_generic.c |
6384 |
+@@ -409,7 +409,7 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets) |
6385 |
+ |
6386 |
+ void __qdisc_run(struct Qdisc *q) |
6387 |
+ { |
6388 |
+- int quota = dev_tx_weight; |
6389 |
++ int quota = READ_ONCE(dev_tx_weight); |
6390 |
+ int packets; |
6391 |
+ |
6392 |
+ while (qdisc_restart(q, &packets)) { |
6393 |
+diff --git a/net/socket.c b/net/socket.c |
6394 |
+index 96300cdc06251..34102aa4ab0a6 100644 |
6395 |
+--- a/net/socket.c |
6396 |
++++ b/net/socket.c |
6397 |
+@@ -1801,7 +1801,7 @@ int __sys_listen(int fd, int backlog) |
6398 |
+ |
6399 |
+ sock = sockfd_lookup_light(fd, &err, &fput_needed); |
6400 |
+ if (sock) { |
6401 |
+- somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn; |
6402 |
++ somaxconn = READ_ONCE(sock_net(sock->sk)->core.sysctl_somaxconn); |
6403 |
+ if ((unsigned int)backlog > somaxconn) |
6404 |
+ backlog = somaxconn; |
6405 |
+ |
6406 |
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c |
6407 |
+index 733f9f2260926..c1a01947530f0 100644 |
6408 |
+--- a/net/sunrpc/clnt.c |
6409 |
++++ b/net/sunrpc/clnt.c |
6410 |
+@@ -1888,7 +1888,7 @@ call_encode(struct rpc_task *task) |
6411 |
+ break; |
6412 |
+ case -EKEYEXPIRED: |
6413 |
+ if (!task->tk_cred_retry) { |
6414 |
+- rpc_exit(task, task->tk_status); |
6415 |
++ rpc_call_rpcerror(task, task->tk_status); |
6416 |
+ } else { |
6417 |
+ task->tk_action = call_refresh; |
6418 |
+ task->tk_cred_retry--; |
6419 |
+diff --git a/net/xfrm/espintcp.c b/net/xfrm/espintcp.c |
6420 |
+index 82d14eea1b5ad..974eb97b77d22 100644 |
6421 |
+--- a/net/xfrm/espintcp.c |
6422 |
++++ b/net/xfrm/espintcp.c |
6423 |
+@@ -168,7 +168,7 @@ int espintcp_queue_out(struct sock *sk, struct sk_buff *skb) |
6424 |
+ { |
6425 |
+ struct espintcp_ctx *ctx = espintcp_getctx(sk); |
6426 |
+ |
6427 |
+- if (skb_queue_len(&ctx->out_queue) >= netdev_max_backlog) |
6428 |
++ if (skb_queue_len(&ctx->out_queue) >= READ_ONCE(netdev_max_backlog)) |
6429 |
+ return -ENOBUFS; |
6430 |
+ |
6431 |
+ __skb_queue_tail(&ctx->out_queue, skb); |
6432 |
+diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c |
6433 |
+index 144238a50f3d4..b2f4ec9c537f0 100644 |
6434 |
+--- a/net/xfrm/xfrm_input.c |
6435 |
++++ b/net/xfrm/xfrm_input.c |
6436 |
+@@ -669,7 +669,6 @@ resume: |
6437 |
+ |
6438 |
+ x->curlft.bytes += skb->len; |
6439 |
+ x->curlft.packets++; |
6440 |
+- x->curlft.use_time = ktime_get_real_seconds(); |
6441 |
+ |
6442 |
+ spin_unlock(&x->lock); |
6443 |
+ |
6444 |
+@@ -783,7 +782,7 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb, |
6445 |
+ |
6446 |
+ trans = this_cpu_ptr(&xfrm_trans_tasklet); |
6447 |
+ |
6448 |
+- if (skb_queue_len(&trans->queue) >= netdev_max_backlog) |
6449 |
++ if (skb_queue_len(&trans->queue) >= READ_ONCE(netdev_max_backlog)) |
6450 |
+ return -ENOBUFS; |
6451 |
+ |
6452 |
+ BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb)); |
6453 |
+diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c |
6454 |
+index 555ab35cd119a..9a5e79a38c679 100644 |
6455 |
+--- a/net/xfrm/xfrm_output.c |
6456 |
++++ b/net/xfrm/xfrm_output.c |
6457 |
+@@ -534,7 +534,6 @@ static int xfrm_output_one(struct sk_buff *skb, int err) |
6458 |
+ |
6459 |
+ x->curlft.bytes += skb->len; |
6460 |
+ x->curlft.packets++; |
6461 |
+- x->curlft.use_time = ktime_get_real_seconds(); |
6462 |
+ |
6463 |
+ spin_unlock_bh(&x->lock); |
6464 |
+ |
6465 |
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c |
6466 |
+index f1a0bab920a55..cc6ab79609e29 100644 |
6467 |
+--- a/net/xfrm/xfrm_policy.c |
6468 |
++++ b/net/xfrm/xfrm_policy.c |
6469 |
+@@ -3162,7 +3162,7 @@ ok: |
6470 |
+ return dst; |
6471 |
+ |
6472 |
+ nopol: |
6473 |
+- if (!(dst_orig->dev->flags & IFF_LOOPBACK) && |
6474 |
++ if ((!dst_orig->dev || !(dst_orig->dev->flags & IFF_LOOPBACK)) && |
6475 |
+ net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK) { |
6476 |
+ err = -EPERM; |
6477 |
+ goto error; |
6478 |
+@@ -3599,6 +3599,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, |
6479 |
+ if (pols[1]) { |
6480 |
+ if (IS_ERR(pols[1])) { |
6481 |
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR); |
6482 |
++ xfrm_pol_put(pols[0]); |
6483 |
+ return 0; |
6484 |
+ } |
6485 |
+ pols[1]->curlft.use_time = ktime_get_real_seconds(); |
6486 |
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c |
6487 |
+index ccfb172eb5b8d..11d89af9cb55a 100644 |
6488 |
+--- a/net/xfrm/xfrm_state.c |
6489 |
++++ b/net/xfrm/xfrm_state.c |
6490 |
+@@ -1592,6 +1592,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, |
6491 |
+ x->replay = orig->replay; |
6492 |
+ x->preplay = orig->preplay; |
6493 |
+ x->mapping_maxage = orig->mapping_maxage; |
6494 |
++ x->lastused = orig->lastused; |
6495 |
+ x->new_mapping = 0; |
6496 |
+ x->new_mapping_sport = 0; |
6497 |
+ |
6498 |
+diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config |
6499 |
+index 73e0762092feb..02a6000a82bbf 100644 |
6500 |
+--- a/tools/perf/Makefile.config |
6501 |
++++ b/tools/perf/Makefile.config |
6502 |
+@@ -265,7 +265,7 @@ endif |
6503 |
+ # defined. get-executable-or-default fails with an error if the first argument is supplied but |
6504 |
+ # doesn't exist. |
6505 |
+ override PYTHON_CONFIG := $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON_AUTO)) |
6506 |
+-override PYTHON := $(call get-executable-or-default,PYTHON,$(subst -config,,$(PYTHON_AUTO))) |
6507 |
++override PYTHON := $(call get-executable-or-default,PYTHON,$(subst -config,,$(PYTHON_CONFIG))) |
6508 |
+ |
6509 |
+ grep-libs = $(filter -l%,$(1)) |
6510 |
+ strip-libs = $(filter-out -l%,$(1)) |
6511 |
+diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c |
6512 |
+index 86f838c5661ee..5f0333a8acd8a 100644 |
6513 |
+--- a/tools/perf/builtin-stat.c |
6514 |
++++ b/tools/perf/builtin-stat.c |
6515 |
+@@ -826,6 +826,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) |
6516 |
+ } |
6517 |
+ |
6518 |
+ evlist__for_each_entry(evsel_list, counter) { |
6519 |
++ counter->reset_group = false; |
6520 |
+ if (bpf_counter__load(counter, &target)) |
6521 |
+ return -1; |
6522 |
+ if (!evsel__is_bpf(counter)) |