1 |
commit: 94580b1463bbf03ca324c74c008b18d535048b6f |
2 |
Author: Alice Ferrazzi <alicef <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Oct 13 16:14:14 2021 +0000 |
4 |
Commit: Alice Ferrazzi <alicef <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Oct 13 16:14:54 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=94580b14 |
7 |
|
8 |
Linux patch 5.14.12 |
9 |
|
10 |
Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1011_linux-5.14.12.patch | 5808 ++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 5812 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 6096d94..4456b48 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -91,6 +91,10 @@ Patch: 1010_linux-5.14.11.patch |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 5.14.11 |
23 |
|
24 |
+Patch: 1011_linux-5.14.12.patch |
25 |
+From: http://www.kernel.org |
26 |
+Desc: Linux 5.14.12 |
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/1011_linux-5.14.12.patch b/1011_linux-5.14.12.patch |
33 |
new file mode 100644 |
34 |
index 0000000..5f0db51 |
35 |
--- /dev/null |
36 |
+++ b/1011_linux-5.14.12.patch |
37 |
@@ -0,0 +1,5808 @@ |
38 |
+diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml |
39 |
+index 26932d2e86aba..8608b9dd8e9db 100644 |
40 |
+--- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml |
41 |
++++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml |
42 |
+@@ -18,7 +18,7 @@ properties: |
43 |
+ const: ti,sn65dsi86 |
44 |
+ |
45 |
+ reg: |
46 |
+- const: 0x2d |
47 |
++ enum: [ 0x2c, 0x2d ] |
48 |
+ |
49 |
+ enable-gpios: |
50 |
+ maxItems: 1 |
51 |
+diff --git a/Makefile b/Makefile |
52 |
+index ca6c4472775cb..02cde08f4978e 100644 |
53 |
+--- a/Makefile |
54 |
++++ b/Makefile |
55 |
+@@ -1,7 +1,7 @@ |
56 |
+ # SPDX-License-Identifier: GPL-2.0 |
57 |
+ VERSION = 5 |
58 |
+ PATCHLEVEL = 14 |
59 |
+-SUBLEVEL = 11 |
60 |
++SUBLEVEL = 12 |
61 |
+ EXTRAVERSION = |
62 |
+ NAME = Opossums on Parade |
63 |
+ |
64 |
+diff --git a/arch/arm/boot/dts/imx53-m53menlo.dts b/arch/arm/boot/dts/imx53-m53menlo.dts |
65 |
+index d3082b9774e40..4f88e96d81ddb 100644 |
66 |
+--- a/arch/arm/boot/dts/imx53-m53menlo.dts |
67 |
++++ b/arch/arm/boot/dts/imx53-m53menlo.dts |
68 |
+@@ -56,6 +56,7 @@ |
69 |
+ panel { |
70 |
+ compatible = "edt,etm0700g0dh6"; |
71 |
+ pinctrl-0 = <&pinctrl_display_gpio>; |
72 |
++ pinctrl-names = "default"; |
73 |
+ enable-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; |
74 |
+ |
75 |
+ port { |
76 |
+@@ -76,8 +77,7 @@ |
77 |
+ regulator-name = "vbus"; |
78 |
+ regulator-min-microvolt = <5000000>; |
79 |
+ regulator-max-microvolt = <5000000>; |
80 |
+- gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>; |
81 |
+- enable-active-high; |
82 |
++ gpio = <&gpio1 2 0>; |
83 |
+ }; |
84 |
+ }; |
85 |
+ |
86 |
+diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi |
87 |
+index cb8b539eb29d1..e5c4dc65fbabf 100644 |
88 |
+--- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi |
89 |
++++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi |
90 |
+@@ -5,6 +5,7 @@ |
91 |
+ #include <dt-bindings/gpio/gpio.h> |
92 |
+ #include <dt-bindings/interrupt-controller/irq.h> |
93 |
+ #include <dt-bindings/input/input.h> |
94 |
++#include <dt-bindings/leds/common.h> |
95 |
+ #include <dt-bindings/pwm/pwm.h> |
96 |
+ |
97 |
+ / { |
98 |
+@@ -277,6 +278,7 @@ |
99 |
+ led-cur = /bits/ 8 <0x20>; |
100 |
+ max-cur = /bits/ 8 <0x60>; |
101 |
+ reg = <0>; |
102 |
++ color = <LED_COLOR_ID_RED>; |
103 |
+ }; |
104 |
+ |
105 |
+ chan@1 { |
106 |
+@@ -284,6 +286,7 @@ |
107 |
+ led-cur = /bits/ 8 <0x20>; |
108 |
+ max-cur = /bits/ 8 <0x60>; |
109 |
+ reg = <1>; |
110 |
++ color = <LED_COLOR_ID_GREEN>; |
111 |
+ }; |
112 |
+ |
113 |
+ chan@2 { |
114 |
+@@ -291,6 +294,7 @@ |
115 |
+ led-cur = /bits/ 8 <0x20>; |
116 |
+ max-cur = /bits/ 8 <0x60>; |
117 |
+ reg = <2>; |
118 |
++ color = <LED_COLOR_ID_BLUE>; |
119 |
+ }; |
120 |
+ |
121 |
+ chan@3 { |
122 |
+@@ -298,6 +302,7 @@ |
123 |
+ led-cur = /bits/ 8 <0x0>; |
124 |
+ max-cur = /bits/ 8 <0x0>; |
125 |
+ reg = <3>; |
126 |
++ color = <LED_COLOR_ID_WHITE>; |
127 |
+ }; |
128 |
+ }; |
129 |
+ |
130 |
+diff --git a/arch/arm/boot/dts/imx6qdl-pico.dtsi b/arch/arm/boot/dts/imx6qdl-pico.dtsi |
131 |
+index 5de4ccb979163..f7a56d6b160c8 100644 |
132 |
+--- a/arch/arm/boot/dts/imx6qdl-pico.dtsi |
133 |
++++ b/arch/arm/boot/dts/imx6qdl-pico.dtsi |
134 |
+@@ -176,7 +176,18 @@ |
135 |
+ pinctrl-0 = <&pinctrl_enet>; |
136 |
+ phy-mode = "rgmii-id"; |
137 |
+ phy-reset-gpios = <&gpio1 26 GPIO_ACTIVE_LOW>; |
138 |
++ phy-handle = <&phy>; |
139 |
+ status = "okay"; |
140 |
++ |
141 |
++ mdio { |
142 |
++ #address-cells = <1>; |
143 |
++ #size-cells = <0>; |
144 |
++ |
145 |
++ phy: ethernet-phy@1 { |
146 |
++ reg = <1>; |
147 |
++ qca,clk-out-frequency = <125000000>; |
148 |
++ }; |
149 |
++ }; |
150 |
+ }; |
151 |
+ |
152 |
+ &hdmi { |
153 |
+diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts |
154 |
+index 5a63ca6157229..99f4cf777a384 100644 |
155 |
+--- a/arch/arm/boot/dts/imx6sx-sdb.dts |
156 |
++++ b/arch/arm/boot/dts/imx6sx-sdb.dts |
157 |
+@@ -114,7 +114,7 @@ |
158 |
+ compatible = "micron,n25q256a", "jedec,spi-nor"; |
159 |
+ spi-max-frequency = <29000000>; |
160 |
+ spi-rx-bus-width = <4>; |
161 |
+- spi-tx-bus-width = <4>; |
162 |
++ spi-tx-bus-width = <1>; |
163 |
+ reg = <0>; |
164 |
+ }; |
165 |
+ |
166 |
+@@ -124,7 +124,7 @@ |
167 |
+ compatible = "micron,n25q256a", "jedec,spi-nor"; |
168 |
+ spi-max-frequency = <29000000>; |
169 |
+ spi-rx-bus-width = <4>; |
170 |
+- spi-tx-bus-width = <4>; |
171 |
++ spi-tx-bus-width = <1>; |
172 |
+ reg = <2>; |
173 |
+ }; |
174 |
+ }; |
175 |
+diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi |
176 |
+index 779cc536566d6..a3fde3316c736 100644 |
177 |
+--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi |
178 |
++++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi |
179 |
+@@ -292,7 +292,7 @@ |
180 |
+ compatible = "micron,n25q256a", "jedec,spi-nor"; |
181 |
+ spi-max-frequency = <29000000>; |
182 |
+ spi-rx-bus-width = <4>; |
183 |
+- spi-tx-bus-width = <4>; |
184 |
++ spi-tx-bus-width = <1>; |
185 |
+ reg = <0>; |
186 |
+ }; |
187 |
+ }; |
188 |
+diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts |
189 |
+index c5b9037184149..7d530ae3483b8 100644 |
190 |
+--- a/arch/arm/boot/dts/omap3430-sdp.dts |
191 |
++++ b/arch/arm/boot/dts/omap3430-sdp.dts |
192 |
+@@ -101,7 +101,7 @@ |
193 |
+ |
194 |
+ nand@1,0 { |
195 |
+ compatible = "ti,omap2-nand"; |
196 |
+- reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ |
197 |
++ reg = <1 0 4>; /* CS1, offset 0, IO size 4 */ |
198 |
+ interrupt-parent = <&gpmc>; |
199 |
+ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ |
200 |
+ <1 IRQ_TYPE_NONE>; /* termcount */ |
201 |
+diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi |
202 |
+index e36d590e83732..72c4a9fc41a20 100644 |
203 |
+--- a/arch/arm/boot/dts/qcom-apq8064.dtsi |
204 |
++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi |
205 |
+@@ -198,7 +198,7 @@ |
206 |
+ clock-frequency = <19200000>; |
207 |
+ }; |
208 |
+ |
209 |
+- pxo_board { |
210 |
++ pxo_board: pxo_board { |
211 |
+ compatible = "fixed-clock"; |
212 |
+ #clock-cells = <0>; |
213 |
+ clock-frequency = <27000000>; |
214 |
+@@ -1148,7 +1148,7 @@ |
215 |
+ }; |
216 |
+ |
217 |
+ gpu: adreno-3xx@4300000 { |
218 |
+- compatible = "qcom,adreno-3xx"; |
219 |
++ compatible = "qcom,adreno-320.2", "qcom,adreno"; |
220 |
+ reg = <0x04300000 0x20000>; |
221 |
+ reg-names = "kgsl_3d0_reg_memory"; |
222 |
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; |
223 |
+@@ -1163,7 +1163,6 @@ |
224 |
+ <&mmcc GFX3D_AHB_CLK>, |
225 |
+ <&mmcc GFX3D_AXI_CLK>, |
226 |
+ <&mmcc MMSS_IMEM_AHB_CLK>; |
227 |
+- qcom,chipid = <0x03020002>; |
228 |
+ |
229 |
+ iommus = <&gfx3d 0 |
230 |
+ &gfx3d 1 |
231 |
+@@ -1306,7 +1305,7 @@ |
232 |
+ reg-names = "dsi_pll", "dsi_phy", "dsi_phy_regulator"; |
233 |
+ clock-names = "iface_clk", "ref"; |
234 |
+ clocks = <&mmcc DSI_M_AHB_CLK>, |
235 |
+- <&cxo_board>; |
236 |
++ <&pxo_board>; |
237 |
+ }; |
238 |
+ |
239 |
+ |
240 |
+diff --git a/arch/arm/configs/gemini_defconfig b/arch/arm/configs/gemini_defconfig |
241 |
+index d2d5f1cf815f2..e6ff844821cfb 100644 |
242 |
+--- a/arch/arm/configs/gemini_defconfig |
243 |
++++ b/arch/arm/configs/gemini_defconfig |
244 |
+@@ -76,6 +76,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y |
245 |
+ CONFIG_DRM=y |
246 |
+ CONFIG_DRM_PANEL_ILITEK_IL9322=y |
247 |
+ CONFIG_DRM_TVE200=y |
248 |
++CONFIG_FB=y |
249 |
+ CONFIG_LOGO=y |
250 |
+ CONFIG_USB=y |
251 |
+ CONFIG_USB_MON=y |
252 |
+diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c |
253 |
+index 90dcdfe3b3d0d..2dee383f90509 100644 |
254 |
+--- a/arch/arm/mach-at91/pm.c |
255 |
++++ b/arch/arm/mach-at91/pm.c |
256 |
+@@ -514,18 +514,22 @@ static const struct of_device_id ramc_ids[] __initconst = { |
257 |
+ { /*sentinel*/ } |
258 |
+ }; |
259 |
+ |
260 |
+-static __init void at91_dt_ramc(void) |
261 |
++static __init int at91_dt_ramc(void) |
262 |
+ { |
263 |
+ struct device_node *np; |
264 |
+ const struct of_device_id *of_id; |
265 |
+ int idx = 0; |
266 |
+ void *standby = NULL; |
267 |
+ const struct ramc_info *ramc; |
268 |
++ int ret; |
269 |
+ |
270 |
+ for_each_matching_node_and_match(np, ramc_ids, &of_id) { |
271 |
+ soc_pm.data.ramc[idx] = of_iomap(np, 0); |
272 |
+- if (!soc_pm.data.ramc[idx]) |
273 |
+- panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx); |
274 |
++ if (!soc_pm.data.ramc[idx]) { |
275 |
++ pr_err("unable to map ramc[%d] cpu registers\n", idx); |
276 |
++ ret = -ENOMEM; |
277 |
++ goto unmap_ramc; |
278 |
++ } |
279 |
+ |
280 |
+ ramc = of_id->data; |
281 |
+ if (!standby) |
282 |
+@@ -535,15 +539,26 @@ static __init void at91_dt_ramc(void) |
283 |
+ idx++; |
284 |
+ } |
285 |
+ |
286 |
+- if (!idx) |
287 |
+- panic(pr_fmt("unable to find compatible ram controller node in dtb\n")); |
288 |
++ if (!idx) { |
289 |
++ pr_err("unable to find compatible ram controller node in dtb\n"); |
290 |
++ ret = -ENODEV; |
291 |
++ goto unmap_ramc; |
292 |
++ } |
293 |
+ |
294 |
+ if (!standby) { |
295 |
+ pr_warn("ramc no standby function available\n"); |
296 |
+- return; |
297 |
++ return 0; |
298 |
+ } |
299 |
+ |
300 |
+ at91_cpuidle_device.dev.platform_data = standby; |
301 |
++ |
302 |
++ return 0; |
303 |
++ |
304 |
++unmap_ramc: |
305 |
++ while (idx) |
306 |
++ iounmap(soc_pm.data.ramc[--idx]); |
307 |
++ |
308 |
++ return ret; |
309 |
+ } |
310 |
+ |
311 |
+ static void at91rm9200_idle(void) |
312 |
+@@ -866,6 +881,8 @@ static void __init at91_pm_init(void (*pm_idle)(void)) |
313 |
+ |
314 |
+ void __init at91rm9200_pm_init(void) |
315 |
+ { |
316 |
++ int ret; |
317 |
++ |
318 |
+ if (!IS_ENABLED(CONFIG_SOC_AT91RM9200)) |
319 |
+ return; |
320 |
+ |
321 |
+@@ -877,7 +894,9 @@ void __init at91rm9200_pm_init(void) |
322 |
+ soc_pm.data.standby_mode = AT91_PM_STANDBY; |
323 |
+ soc_pm.data.suspend_mode = AT91_PM_ULP0; |
324 |
+ |
325 |
+- at91_dt_ramc(); |
326 |
++ ret = at91_dt_ramc(); |
327 |
++ if (ret) |
328 |
++ return; |
329 |
+ |
330 |
+ /* |
331 |
+ * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. |
332 |
+@@ -892,13 +911,17 @@ void __init sam9x60_pm_init(void) |
333 |
+ static const int modes[] __initconst = { |
334 |
+ AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1, |
335 |
+ }; |
336 |
++ int ret; |
337 |
+ |
338 |
+ if (!IS_ENABLED(CONFIG_SOC_SAM9X60)) |
339 |
+ return; |
340 |
+ |
341 |
+ at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); |
342 |
+ at91_pm_modes_init(); |
343 |
+- at91_dt_ramc(); |
344 |
++ ret = at91_dt_ramc(); |
345 |
++ if (ret) |
346 |
++ return; |
347 |
++ |
348 |
+ at91_pm_init(NULL); |
349 |
+ |
350 |
+ soc_pm.ws_ids = sam9x60_ws_ids; |
351 |
+@@ -907,6 +930,8 @@ void __init sam9x60_pm_init(void) |
352 |
+ |
353 |
+ void __init at91sam9_pm_init(void) |
354 |
+ { |
355 |
++ int ret; |
356 |
++ |
357 |
+ if (!IS_ENABLED(CONFIG_SOC_AT91SAM9)) |
358 |
+ return; |
359 |
+ |
360 |
+@@ -918,7 +943,10 @@ void __init at91sam9_pm_init(void) |
361 |
+ soc_pm.data.standby_mode = AT91_PM_STANDBY; |
362 |
+ soc_pm.data.suspend_mode = AT91_PM_ULP0; |
363 |
+ |
364 |
+- at91_dt_ramc(); |
365 |
++ ret = at91_dt_ramc(); |
366 |
++ if (ret) |
367 |
++ return; |
368 |
++ |
369 |
+ at91_pm_init(at91sam9_idle); |
370 |
+ } |
371 |
+ |
372 |
+@@ -927,12 +955,16 @@ void __init sama5_pm_init(void) |
373 |
+ static const int modes[] __initconst = { |
374 |
+ AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, |
375 |
+ }; |
376 |
++ int ret; |
377 |
+ |
378 |
+ if (!IS_ENABLED(CONFIG_SOC_SAMA5)) |
379 |
+ return; |
380 |
+ |
381 |
+ at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); |
382 |
+- at91_dt_ramc(); |
383 |
++ ret = at91_dt_ramc(); |
384 |
++ if (ret) |
385 |
++ return; |
386 |
++ |
387 |
+ at91_pm_init(NULL); |
388 |
+ } |
389 |
+ |
390 |
+@@ -942,13 +974,17 @@ void __init sama5d2_pm_init(void) |
391 |
+ AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1, |
392 |
+ AT91_PM_BACKUP, |
393 |
+ }; |
394 |
++ int ret; |
395 |
+ |
396 |
+ if (!IS_ENABLED(CONFIG_SOC_SAMA5D2)) |
397 |
+ return; |
398 |
+ |
399 |
+ at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); |
400 |
+ at91_pm_modes_init(); |
401 |
+- at91_dt_ramc(); |
402 |
++ ret = at91_dt_ramc(); |
403 |
++ if (ret) |
404 |
++ return; |
405 |
++ |
406 |
+ at91_pm_init(NULL); |
407 |
+ |
408 |
+ soc_pm.ws_ids = sama5d2_ws_ids; |
409 |
+diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c |
410 |
+index 9244437cb1b9b..f2ecca339910a 100644 |
411 |
+--- a/arch/arm/mach-imx/pm-imx6.c |
412 |
++++ b/arch/arm/mach-imx/pm-imx6.c |
413 |
+@@ -10,6 +10,7 @@ |
414 |
+ #include <linux/io.h> |
415 |
+ #include <linux/irq.h> |
416 |
+ #include <linux/genalloc.h> |
417 |
++#include <linux/irqchip/arm-gic.h> |
418 |
+ #include <linux/mfd/syscon.h> |
419 |
+ #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> |
420 |
+ #include <linux/of.h> |
421 |
+@@ -619,6 +620,7 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata |
422 |
+ |
423 |
+ static void imx6_pm_stby_poweroff(void) |
424 |
+ { |
425 |
++ gic_cpu_if_down(0); |
426 |
+ imx6_set_lpm(STOP_POWER_OFF); |
427 |
+ imx6q_suspend_finish(0); |
428 |
+ |
429 |
+diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c |
430 |
+index 12b26e04686fa..0c2936c7a3799 100644 |
431 |
+--- a/arch/arm/mach-omap2/omap_hwmod.c |
432 |
++++ b/arch/arm/mach-omap2/omap_hwmod.c |
433 |
+@@ -3614,6 +3614,8 @@ int omap_hwmod_init_module(struct device *dev, |
434 |
+ oh->flags |= HWMOD_SWSUP_SIDLE_ACT; |
435 |
+ if (data->cfg->quirks & SYSC_QUIRK_SWSUP_MSTANDBY) |
436 |
+ oh->flags |= HWMOD_SWSUP_MSTANDBY; |
437 |
++ if (data->cfg->quirks & SYSC_QUIRK_CLKDM_NOAUTO) |
438 |
++ oh->flags |= HWMOD_CLKDM_NOAUTO; |
439 |
+ |
440 |
+ error = omap_hwmod_check_module(dev, oh, data, sysc_fields, |
441 |
+ rev_offs, sysc_offs, syss_offs, |
442 |
+diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c |
443 |
+index a951276f05475..a903b26cde409 100644 |
444 |
+--- a/arch/arm/net/bpf_jit_32.c |
445 |
++++ b/arch/arm/net/bpf_jit_32.c |
446 |
+@@ -36,6 +36,10 @@ |
447 |
+ * +-----+ |
448 |
+ * |RSVD | JIT scratchpad |
449 |
+ * current ARM_SP => +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE) |
450 |
++ * | ... | caller-saved registers |
451 |
++ * +-----+ |
452 |
++ * | ... | arguments passed on stack |
453 |
++ * ARM_SP during call => +-----| |
454 |
+ * | | |
455 |
+ * | ... | Function call stack |
456 |
+ * | | |
457 |
+@@ -63,6 +67,12 @@ |
458 |
+ * |
459 |
+ * When popping registers off the stack at the end of a BPF function, we |
460 |
+ * reference them via the current ARM_FP register. |
461 |
++ * |
462 |
++ * Some eBPF operations are implemented via a call to a helper function. |
463 |
++ * Such calls are "invisible" in the eBPF code, so it is up to the calling |
464 |
++ * program to preserve any caller-saved ARM registers during the call. The |
465 |
++ * JIT emits code to push and pop those registers onto the stack, immediately |
466 |
++ * above the callee stack frame. |
467 |
+ */ |
468 |
+ #define CALLEE_MASK (1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \ |
469 |
+ 1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R9 | \ |
470 |
+@@ -70,6 +80,8 @@ |
471 |
+ #define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR) |
472 |
+ #define CALLEE_POP_MASK (CALLEE_MASK | 1 << ARM_PC) |
473 |
+ |
474 |
++#define CALLER_MASK (1 << ARM_R0 | 1 << ARM_R1 | 1 << ARM_R2 | 1 << ARM_R3) |
475 |
++ |
476 |
+ enum { |
477 |
+ /* Stack layout - these are offsets from (top of stack - 4) */ |
478 |
+ BPF_R2_HI, |
479 |
+@@ -464,6 +476,7 @@ static inline int epilogue_offset(const struct jit_ctx *ctx) |
480 |
+ |
481 |
+ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) |
482 |
+ { |
483 |
++ const int exclude_mask = BIT(ARM_R0) | BIT(ARM_R1); |
484 |
+ const s8 *tmp = bpf2a32[TMP_REG_1]; |
485 |
+ |
486 |
+ #if __LINUX_ARM_ARCH__ == 7 |
487 |
+@@ -495,11 +508,17 @@ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) |
488 |
+ emit(ARM_MOV_R(ARM_R0, rm), ctx); |
489 |
+ } |
490 |
+ |
491 |
++ /* Push caller-saved registers on stack */ |
492 |
++ emit(ARM_PUSH(CALLER_MASK & ~exclude_mask), ctx); |
493 |
++ |
494 |
+ /* Call appropriate function */ |
495 |
+ emit_mov_i(ARM_IP, op == BPF_DIV ? |
496 |
+ (u32)jit_udiv32 : (u32)jit_mod32, ctx); |
497 |
+ emit_blx_r(ARM_IP, ctx); |
498 |
+ |
499 |
++ /* Restore caller-saved registers from stack */ |
500 |
++ emit(ARM_POP(CALLER_MASK & ~exclude_mask), ctx); |
501 |
++ |
502 |
+ /* Save return value */ |
503 |
+ if (rd != ARM_R0) |
504 |
+ emit(ARM_MOV_R(rd, ARM_R0), ctx); |
505 |
+diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi |
506 |
+index 343ecf0e8973a..06b36cc65865c 100644 |
507 |
+--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi |
508 |
++++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi |
509 |
+@@ -405,9 +405,9 @@ |
510 |
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>; |
511 |
+ clock-frequency = <0>; /* fixed up by bootloader */ |
512 |
+ clocks = <&clockgen QORIQ_CLK_HWACCEL 1>; |
513 |
+- voltage-ranges = <1800 1800 3300 3300>; |
514 |
++ voltage-ranges = <1800 1800>; |
515 |
+ sdhci,auto-cmd12; |
516 |
+- broken-cd; |
517 |
++ non-removable; |
518 |
+ little-endian; |
519 |
+ bus-width = <4>; |
520 |
+ status = "disabled"; |
521 |
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi |
522 |
+index 988f8ab679ad6..40f5e7a3b0644 100644 |
523 |
+--- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi |
524 |
++++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi |
525 |
+@@ -91,7 +91,7 @@ |
526 |
+ #size-cells = <1>; |
527 |
+ compatible = "jedec,spi-nor"; |
528 |
+ spi-max-frequency = <80000000>; |
529 |
+- spi-tx-bus-width = <4>; |
530 |
++ spi-tx-bus-width = <1>; |
531 |
+ spi-rx-bus-width = <4>; |
532 |
+ }; |
533 |
+ }; |
534 |
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts |
535 |
+index 4e2820d19244a..a2b24d4d4e3e7 100644 |
536 |
+--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts |
537 |
++++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts |
538 |
+@@ -48,7 +48,7 @@ |
539 |
+ #size-cells = <1>; |
540 |
+ compatible = "jedec,spi-nor"; |
541 |
+ spi-max-frequency = <80000000>; |
542 |
+- spi-tx-bus-width = <4>; |
543 |
++ spi-tx-bus-width = <1>; |
544 |
+ spi-rx-bus-width = <4>; |
545 |
+ }; |
546 |
+ }; |
547 |
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi |
548 |
+index d0456daefda88..9db9b90bf2bc9 100644 |
549 |
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi |
550 |
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi |
551 |
+@@ -102,6 +102,7 @@ |
552 |
+ regulator-min-microvolt = <850000>; |
553 |
+ regulator-max-microvolt = <950000>; |
554 |
+ regulator-boot-on; |
555 |
++ regulator-always-on; |
556 |
+ regulator-ramp-delay = <3125>; |
557 |
+ nxp,dvs-run-voltage = <950000>; |
558 |
+ nxp,dvs-standby-voltage = <850000>; |
559 |
+diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi |
560 |
+index 54eaf3d6055b1..3b2d627a03428 100644 |
561 |
+--- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi |
562 |
++++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi |
563 |
+@@ -101,7 +101,7 @@ |
564 |
+ #size-cells = <1>; |
565 |
+ compatible = "jedec,spi-nor"; |
566 |
+ spi-max-frequency = <80000000>; |
567 |
+- spi-tx-bus-width = <4>; |
568 |
++ spi-tx-bus-width = <1>; |
569 |
+ spi-rx-bus-width = <4>; |
570 |
+ }; |
571 |
+ }; |
572 |
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi |
573 |
+index aa78e0d8c72b2..fc178eebf8aa4 100644 |
574 |
+--- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi |
575 |
++++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi |
576 |
+@@ -74,7 +74,7 @@ |
577 |
+ compatible = "jedec,spi-nor"; |
578 |
+ reg = <0>; |
579 |
+ spi-max-frequency = <80000000>; |
580 |
+- spi-tx-bus-width = <4>; |
581 |
++ spi-tx-bus-width = <1>; |
582 |
+ spi-rx-bus-width = <4>; |
583 |
+ }; |
584 |
+ }; |
585 |
+diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts |
586 |
+index 4d2035e3dd7cc..4886f3e31587a 100644 |
587 |
+--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts |
588 |
++++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts |
589 |
+@@ -337,6 +337,8 @@ |
590 |
+ #size-cells = <1>; |
591 |
+ compatible = "micron,n25q256a", "jedec,spi-nor"; |
592 |
+ spi-max-frequency = <29000000>; |
593 |
++ spi-tx-bus-width = <1>; |
594 |
++ spi-rx-bus-width = <4>; |
595 |
+ }; |
596 |
+ }; |
597 |
+ |
598 |
+diff --git a/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts b/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts |
599 |
+index f593e4ff62e1c..564746d5000d5 100644 |
600 |
+--- a/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts |
601 |
++++ b/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts |
602 |
+@@ -281,7 +281,7 @@ |
603 |
+ #address-cells = <1>; |
604 |
+ #size-cells = <1>; |
605 |
+ reg = <0>; |
606 |
+- spi-tx-bus-width = <4>; |
607 |
++ spi-tx-bus-width = <1>; |
608 |
+ spi-rx-bus-width = <4>; |
609 |
+ m25p,fast-read; |
610 |
+ spi-max-frequency = <50000000>; |
611 |
+diff --git a/arch/arm64/boot/dts/qcom/pm8150.dtsi b/arch/arm64/boot/dts/qcom/pm8150.dtsi |
612 |
+index c566a64b1373f..00385b1fd358f 100644 |
613 |
+--- a/arch/arm64/boot/dts/qcom/pm8150.dtsi |
614 |
++++ b/arch/arm64/boot/dts/qcom/pm8150.dtsi |
615 |
+@@ -48,7 +48,7 @@ |
616 |
+ #size-cells = <0>; |
617 |
+ |
618 |
+ pon: power-on@800 { |
619 |
+- compatible = "qcom,pm8916-pon"; |
620 |
++ compatible = "qcom,pm8998-pon"; |
621 |
+ reg = <0x0800>; |
622 |
+ |
623 |
+ pon_pwrkey: pwrkey { |
624 |
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi |
625 |
+index c08f074106994..188c5768a55ae 100644 |
626 |
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi |
627 |
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi |
628 |
+@@ -1437,9 +1437,9 @@ |
629 |
+ |
630 |
+ cpufreq_hw: cpufreq@18591000 { |
631 |
+ compatible = "qcom,cpufreq-epss"; |
632 |
+- reg = <0 0x18591100 0 0x900>, |
633 |
+- <0 0x18592100 0 0x900>, |
634 |
+- <0 0x18593100 0 0x900>; |
635 |
++ reg = <0 0x18591000 0 0x1000>, |
636 |
++ <0 0x18592000 0 0x1000>, |
637 |
++ <0 0x18593000 0 0x1000>; |
638 |
+ clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>; |
639 |
+ clock-names = "xo", "alternate"; |
640 |
+ #freq-domain-cells = <1>; |
641 |
+diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h |
642 |
+index 35fb8ee6dd33e..fd43d876892ec 100644 |
643 |
+--- a/arch/mips/include/asm/mips-cps.h |
644 |
++++ b/arch/mips/include/asm/mips-cps.h |
645 |
+@@ -10,8 +10,6 @@ |
646 |
+ #include <linux/io.h> |
647 |
+ #include <linux/types.h> |
648 |
+ |
649 |
+-#include <asm/mips-boards/launch.h> |
650 |
+- |
651 |
+ extern unsigned long __cps_access_bad_size(void) |
652 |
+ __compiletime_error("Bad size for CPS accessor"); |
653 |
+ |
654 |
+@@ -167,30 +165,11 @@ static inline uint64_t mips_cps_cluster_config(unsigned int cluster) |
655 |
+ */ |
656 |
+ static inline unsigned int mips_cps_numcores(unsigned int cluster) |
657 |
+ { |
658 |
+- unsigned int ncores; |
659 |
+- |
660 |
+ if (!mips_cm_present()) |
661 |
+ return 0; |
662 |
+ |
663 |
+ /* Add one before masking to handle 0xff indicating no cores */ |
664 |
+- ncores = (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES; |
665 |
+- |
666 |
+- if (IS_ENABLED(CONFIG_SOC_MT7621)) { |
667 |
+- struct cpulaunch *launch; |
668 |
+- |
669 |
+- /* |
670 |
+- * Ralink MT7621S SoC is single core, but the GCR_CONFIG method |
671 |
+- * always reports 2 cores. Check the second core's LAUNCH_FREADY |
672 |
+- * flag to detect if the second core is missing. This method |
673 |
+- * only works before the core has been started. |
674 |
+- */ |
675 |
+- launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); |
676 |
+- launch += 2; /* MT7621 has 2 VPEs per core */ |
677 |
+- if (!(launch->flags & LAUNCH_FREADY)) |
678 |
+- ncores = 1; |
679 |
+- } |
680 |
+- |
681 |
+- return ncores; |
682 |
++ return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES; |
683 |
+ } |
684 |
+ |
685 |
+ /** |
686 |
+diff --git a/arch/powerpc/boot/dts/fsl/t1023rdb.dts b/arch/powerpc/boot/dts/fsl/t1023rdb.dts |
687 |
+index 5ba6fbfca2742..f82f85c65964c 100644 |
688 |
+--- a/arch/powerpc/boot/dts/fsl/t1023rdb.dts |
689 |
++++ b/arch/powerpc/boot/dts/fsl/t1023rdb.dts |
690 |
+@@ -154,7 +154,7 @@ |
691 |
+ |
692 |
+ fm1mac3: ethernet@e4000 { |
693 |
+ phy-handle = <&sgmii_aqr_phy3>; |
694 |
+- phy-connection-type = "sgmii-2500"; |
695 |
++ phy-connection-type = "2500base-x"; |
696 |
+ sleep = <&rcpm 0x20000000>; |
697 |
+ }; |
698 |
+ |
699 |
+diff --git a/arch/powerpc/include/asm/book3s/32/kup.h b/arch/powerpc/include/asm/book3s/32/kup.h |
700 |
+index d4b145b279f6c..9f38040f0641d 100644 |
701 |
+--- a/arch/powerpc/include/asm/book3s/32/kup.h |
702 |
++++ b/arch/powerpc/include/asm/book3s/32/kup.h |
703 |
+@@ -136,6 +136,14 @@ static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap) |
704 |
+ if (kuap_is_disabled()) |
705 |
+ return; |
706 |
+ |
707 |
++ if (unlikely(kuap != KUAP_NONE)) { |
708 |
++ current->thread.kuap = KUAP_NONE; |
709 |
++ kuap_lock(kuap, false); |
710 |
++ } |
711 |
++ |
712 |
++ if (likely(regs->kuap == KUAP_NONE)) |
713 |
++ return; |
714 |
++ |
715 |
+ current->thread.kuap = regs->kuap; |
716 |
+ |
717 |
+ kuap_unlock(regs->kuap, false); |
718 |
+diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h |
719 |
+index 6b800d3e2681f..a925dbc5833c7 100644 |
720 |
+--- a/arch/powerpc/include/asm/interrupt.h |
721 |
++++ b/arch/powerpc/include/asm/interrupt.h |
722 |
+@@ -525,10 +525,9 @@ static __always_inline long ____##func(struct pt_regs *regs) |
723 |
+ /* kernel/traps.c */ |
724 |
+ DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception); |
725 |
+ #ifdef CONFIG_PPC_BOOK3S_64 |
726 |
+-DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception); |
727 |
+-#else |
728 |
+-DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception); |
729 |
++DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async); |
730 |
+ #endif |
731 |
++DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception); |
732 |
+ DECLARE_INTERRUPT_HANDLER(SMIException); |
733 |
+ DECLARE_INTERRUPT_HANDLER(handle_hmi_exception); |
734 |
+ DECLARE_INTERRUPT_HANDLER(unknown_exception); |
735 |
+diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c |
736 |
+index 111249fd619de..038ce8d9061d1 100644 |
737 |
+--- a/arch/powerpc/kernel/dma-iommu.c |
738 |
++++ b/arch/powerpc/kernel/dma-iommu.c |
739 |
+@@ -184,6 +184,15 @@ u64 dma_iommu_get_required_mask(struct device *dev) |
740 |
+ struct iommu_table *tbl = get_iommu_table_base(dev); |
741 |
+ u64 mask; |
742 |
+ |
743 |
++ if (dev_is_pci(dev)) { |
744 |
++ u64 bypass_mask = dma_direct_get_required_mask(dev); |
745 |
++ |
746 |
++ if (dma_iommu_dma_supported(dev, bypass_mask)) { |
747 |
++ dev_info(dev, "%s: returning bypass mask 0x%llx\n", __func__, bypass_mask); |
748 |
++ return bypass_mask; |
749 |
++ } |
750 |
++ } |
751 |
++ |
752 |
+ if (!tbl) |
753 |
+ return 0; |
754 |
+ |
755 |
+diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S |
756 |
+index 37859e62a8dcb..eaf1f72131a18 100644 |
757 |
+--- a/arch/powerpc/kernel/exceptions-64s.S |
758 |
++++ b/arch/powerpc/kernel/exceptions-64s.S |
759 |
+@@ -1243,7 +1243,7 @@ EXC_COMMON_BEGIN(machine_check_common) |
760 |
+ li r10,MSR_RI |
761 |
+ mtmsrd r10,1 |
762 |
+ addi r3,r1,STACK_FRAME_OVERHEAD |
763 |
+- bl machine_check_exception |
764 |
++ bl machine_check_exception_async |
765 |
+ b interrupt_return_srr |
766 |
+ |
767 |
+ |
768 |
+@@ -1303,7 +1303,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) |
769 |
+ subi r12,r12,1 |
770 |
+ sth r12,PACA_IN_MCE(r13) |
771 |
+ |
772 |
+- /* Invoke machine_check_exception to print MCE event and panic. */ |
773 |
++ /* |
774 |
++ * Invoke machine_check_exception to print MCE event and panic. |
775 |
++ * This is the NMI version of the handler because we are called from |
776 |
++ * the early handler which is a true NMI. |
777 |
++ */ |
778 |
+ addi r3,r1,STACK_FRAME_OVERHEAD |
779 |
+ bl machine_check_exception |
780 |
+ |
781 |
+@@ -1665,27 +1669,30 @@ EXC_COMMON_BEGIN(program_check_common) |
782 |
+ */ |
783 |
+ |
784 |
+ andi. r10,r12,MSR_PR |
785 |
+- bne 2f /* If userspace, go normal path */ |
786 |
++ bne .Lnormal_stack /* If userspace, go normal path */ |
787 |
+ |
788 |
+ andis. r10,r12,(SRR1_PROGTM)@h |
789 |
+- bne 1f /* If TM, emergency */ |
790 |
++ bne .Lemergency_stack /* If TM, emergency */ |
791 |
+ |
792 |
+ cmpdi r1,-INT_FRAME_SIZE /* check if r1 is in userspace */ |
793 |
+- blt 2f /* normal path if not */ |
794 |
++ blt .Lnormal_stack /* normal path if not */ |
795 |
+ |
796 |
+ /* Use the emergency stack */ |
797 |
+-1: andi. r10,r12,MSR_PR /* Set CR0 correctly for label */ |
798 |
++.Lemergency_stack: |
799 |
++ andi. r10,r12,MSR_PR /* Set CR0 correctly for label */ |
800 |
+ /* 3 in EXCEPTION_PROLOG_COMMON */ |
801 |
+ mr r10,r1 /* Save r1 */ |
802 |
+ ld r1,PACAEMERGSP(r13) /* Use emergency stack */ |
803 |
+ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ |
804 |
+ __ISTACK(program_check)=0 |
805 |
+ __GEN_COMMON_BODY program_check |
806 |
+- b 3f |
807 |
+-2: |
808 |
++ b .Ldo_program_check |
809 |
++ |
810 |
++.Lnormal_stack: |
811 |
+ __ISTACK(program_check)=1 |
812 |
+ __GEN_COMMON_BODY program_check |
813 |
+-3: |
814 |
++ |
815 |
++.Ldo_program_check: |
816 |
+ addi r3,r1,STACK_FRAME_OVERHEAD |
817 |
+ bl program_check_exception |
818 |
+ REST_NVGPRS(r1) /* instruction emulation may change GPRs */ |
819 |
+diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c |
820 |
+index d56254f05e174..08356ec9bfed4 100644 |
821 |
+--- a/arch/powerpc/kernel/traps.c |
822 |
++++ b/arch/powerpc/kernel/traps.c |
823 |
+@@ -341,10 +341,16 @@ static bool exception_common(int signr, struct pt_regs *regs, int code, |
824 |
+ return false; |
825 |
+ } |
826 |
+ |
827 |
+- show_signal_msg(signr, regs, code, addr); |
828 |
++ /* |
829 |
++ * Must not enable interrupts even for user-mode exception, because |
830 |
++ * this can be called from machine check, which may be a NMI or IRQ |
831 |
++ * which don't like interrupts being enabled. Could check for |
832 |
++ * in_hardirq || in_nmi perhaps, but there doesn't seem to be a good |
833 |
++ * reason why _exception() should enable irqs for an exception handler, |
834 |
++ * the handlers themselves do that directly. |
835 |
++ */ |
836 |
+ |
837 |
+- if (arch_irqs_disabled()) |
838 |
+- interrupt_cond_local_irq_enable(regs); |
839 |
++ show_signal_msg(signr, regs, code, addr); |
840 |
+ |
841 |
+ current->thread.trap_nr = code; |
842 |
+ |
843 |
+@@ -791,24 +797,22 @@ void die_mce(const char *str, struct pt_regs *regs, long err) |
844 |
+ * do_exit() checks for in_interrupt() and panics in that case, so |
845 |
+ * exit the irq/nmi before calling die. |
846 |
+ */ |
847 |
+- if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) |
848 |
+- irq_exit(); |
849 |
+- else |
850 |
++ if (in_nmi()) |
851 |
+ nmi_exit(); |
852 |
++ else |
853 |
++ irq_exit(); |
854 |
+ die(str, regs, err); |
855 |
+ } |
856 |
+ |
857 |
+ /* |
858 |
+- * BOOK3S_64 does not call this handler as a non-maskable interrupt |
859 |
++ * BOOK3S_64 does not usually call this handler as a non-maskable interrupt |
860 |
+ * (it uses its own early real-mode handler to handle the MCE proper |
861 |
+ * and then raises irq_work to call this handler when interrupts are |
862 |
+- * enabled). |
863 |
++ * enabled). The only time when this is not true is if the early handler |
864 |
++ * is unrecoverable, then it does call this directly to try to get a |
865 |
++ * message out. |
866 |
+ */ |
867 |
+-#ifdef CONFIG_PPC_BOOK3S_64 |
868 |
+-DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception) |
869 |
+-#else |
870 |
+-DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception) |
871 |
+-#endif |
872 |
++static void __machine_check_exception(struct pt_regs *regs) |
873 |
+ { |
874 |
+ int recover = 0; |
875 |
+ |
876 |
+@@ -842,12 +846,19 @@ bail: |
877 |
+ /* Must die if the interrupt is not recoverable */ |
878 |
+ if (!(regs->msr & MSR_RI)) |
879 |
+ die_mce("Unrecoverable Machine check", regs, SIGBUS); |
880 |
++} |
881 |
+ |
882 |
+ #ifdef CONFIG_PPC_BOOK3S_64 |
883 |
+- return; |
884 |
+-#else |
885 |
+- return 0; |
886 |
++DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async) |
887 |
++{ |
888 |
++ __machine_check_exception(regs); |
889 |
++} |
890 |
+ #endif |
891 |
++DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception) |
892 |
++{ |
893 |
++ __machine_check_exception(regs); |
894 |
++ |
895 |
++ return 0; |
896 |
+ } |
897 |
+ |
898 |
+ DEFINE_INTERRUPT_HANDLER(SMIException) /* async? */ |
899 |
+diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c |
900 |
+index beb12cbc8c299..a7759aa8043d2 100644 |
901 |
+--- a/arch/powerpc/net/bpf_jit_comp32.c |
902 |
++++ b/arch/powerpc/net/bpf_jit_comp32.c |
903 |
+@@ -355,7 +355,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * |
904 |
+ PPC_LI32(_R0, imm); |
905 |
+ EMIT(PPC_RAW_ADDC(dst_reg, dst_reg, _R0)); |
906 |
+ } |
907 |
+- if (imm >= 0) |
908 |
++ if (imm >= 0 || (BPF_OP(code) == BPF_SUB && imm == 0x80000000)) |
909 |
+ EMIT(PPC_RAW_ADDZE(dst_reg_h, dst_reg_h)); |
910 |
+ else |
911 |
+ EMIT(PPC_RAW_ADDME(dst_reg_h, dst_reg_h)); |
912 |
+@@ -623,7 +623,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * |
913 |
+ EMIT(PPC_RAW_LI(dst_reg_h, 0)); |
914 |
+ break; |
915 |
+ case BPF_ALU | BPF_ARSH | BPF_X: /* (s32) dst >>= src */ |
916 |
+- EMIT(PPC_RAW_SRAW(dst_reg_h, dst_reg, src_reg)); |
917 |
++ EMIT(PPC_RAW_SRAW(dst_reg, dst_reg, src_reg)); |
918 |
+ break; |
919 |
+ case BPF_ALU64 | BPF_ARSH | BPF_X: /* (s64) dst >>= src */ |
920 |
+ bpf_set_seen_register(ctx, tmp_reg); |
921 |
+@@ -1073,7 +1073,7 @@ cond_branch: |
922 |
+ break; |
923 |
+ case BPF_JMP32 | BPF_JSET | BPF_K: |
924 |
+ /* andi does not sign-extend the immediate */ |
925 |
+- if (imm >= -32768 && imm < 32768) { |
926 |
++ if (imm >= 0 && imm < 32768) { |
927 |
+ /* PPC_ANDI is _only/always_ dot-form */ |
928 |
+ EMIT(PPC_RAW_ANDI(_R0, dst_reg, imm)); |
929 |
+ } else { |
930 |
+@@ -1103,7 +1103,7 @@ cond_branch: |
931 |
+ return -EOPNOTSUPP; |
932 |
+ } |
933 |
+ if (BPF_CLASS(code) == BPF_ALU && !fp->aux->verifier_zext && |
934 |
+- !insn_is_zext(&insn[i + 1])) |
935 |
++ !insn_is_zext(&insn[i + 1]) && !(BPF_OP(code) == BPF_END && imm == 64)) |
936 |
+ EMIT(PPC_RAW_LI(dst_reg_h, 0)); |
937 |
+ } |
938 |
+ |
939 |
+diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c |
940 |
+index b87a63dba9c8f..dff4a2930970b 100644 |
941 |
+--- a/arch/powerpc/net/bpf_jit_comp64.c |
942 |
++++ b/arch/powerpc/net/bpf_jit_comp64.c |
943 |
+@@ -328,18 +328,25 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * |
944 |
+ EMIT(PPC_RAW_SUB(dst_reg, dst_reg, src_reg)); |
945 |
+ goto bpf_alu32_trunc; |
946 |
+ case BPF_ALU | BPF_ADD | BPF_K: /* (u32) dst += (u32) imm */ |
947 |
+- case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */ |
948 |
+ case BPF_ALU64 | BPF_ADD | BPF_K: /* dst += imm */ |
949 |
++ if (!imm) { |
950 |
++ goto bpf_alu32_trunc; |
951 |
++ } else if (imm >= -32768 && imm < 32768) { |
952 |
++ EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm))); |
953 |
++ } else { |
954 |
++ PPC_LI32(b2p[TMP_REG_1], imm); |
955 |
++ EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1])); |
956 |
++ } |
957 |
++ goto bpf_alu32_trunc; |
958 |
++ case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */ |
959 |
+ case BPF_ALU64 | BPF_SUB | BPF_K: /* dst -= imm */ |
960 |
+- if (BPF_OP(code) == BPF_SUB) |
961 |
+- imm = -imm; |
962 |
+- if (imm) { |
963 |
+- if (imm >= -32768 && imm < 32768) |
964 |
+- EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm))); |
965 |
+- else { |
966 |
+- PPC_LI32(b2p[TMP_REG_1], imm); |
967 |
+- EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1])); |
968 |
+- } |
969 |
++ if (!imm) { |
970 |
++ goto bpf_alu32_trunc; |
971 |
++ } else if (imm > -32768 && imm <= 32768) { |
972 |
++ EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(-imm))); |
973 |
++ } else { |
974 |
++ PPC_LI32(b2p[TMP_REG_1], imm); |
975 |
++ EMIT(PPC_RAW_SUB(dst_reg, dst_reg, b2p[TMP_REG_1])); |
976 |
+ } |
977 |
+ goto bpf_alu32_trunc; |
978 |
+ case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */ |
979 |
+@@ -389,8 +396,14 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * |
980 |
+ case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */ |
981 |
+ if (imm == 0) |
982 |
+ return -EINVAL; |
983 |
+- else if (imm == 1) |
984 |
+- goto bpf_alu32_trunc; |
985 |
++ if (imm == 1) { |
986 |
++ if (BPF_OP(code) == BPF_DIV) { |
987 |
++ goto bpf_alu32_trunc; |
988 |
++ } else { |
989 |
++ EMIT(PPC_RAW_LI(dst_reg, 0)); |
990 |
++ break; |
991 |
++ } |
992 |
++ } |
993 |
+ |
994 |
+ PPC_LI32(b2p[TMP_REG_1], imm); |
995 |
+ switch (BPF_CLASS(code)) { |
996 |
+diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c |
997 |
+index bc15200852b7c..09fafcf2d3a06 100644 |
998 |
+--- a/arch/powerpc/platforms/pseries/eeh_pseries.c |
999 |
++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c |
1000 |
+@@ -867,6 +867,10 @@ static int __init eeh_pseries_init(void) |
1001 |
+ if (is_kdump_kernel() || reset_devices) { |
1002 |
+ pr_info("Issue PHB reset ...\n"); |
1003 |
+ list_for_each_entry(phb, &hose_list, list_node) { |
1004 |
++ // Skip if the slot is empty |
1005 |
++ if (list_empty(&PCI_DN(phb->dn)->child_list)) |
1006 |
++ continue; |
1007 |
++ |
1008 |
+ pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list); |
1009 |
+ config_addr = pseries_eeh_get_pe_config_addr(pdn); |
1010 |
+ |
1011 |
+diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile |
1012 |
+index bc74afdbf31e2..83ee0e71204cb 100644 |
1013 |
+--- a/arch/riscv/Makefile |
1014 |
++++ b/arch/riscv/Makefile |
1015 |
+@@ -108,6 +108,12 @@ PHONY += vdso_install |
1016 |
+ vdso_install: |
1017 |
+ $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@ |
1018 |
+ |
1019 |
++ifeq ($(CONFIG_MMU),y) |
1020 |
++prepare: vdso_prepare |
1021 |
++vdso_prepare: prepare0 |
1022 |
++ $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h |
1023 |
++endif |
1024 |
++ |
1025 |
+ ifneq ($(CONFIG_XIP_KERNEL),y) |
1026 |
+ ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN),yy) |
1027 |
+ KBUILD_IMAGE := $(boot)/loader.bin |
1028 |
+diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h |
1029 |
+index b933b1583c9fd..34fbb3ea21d5b 100644 |
1030 |
+--- a/arch/riscv/include/asm/syscall.h |
1031 |
++++ b/arch/riscv/include/asm/syscall.h |
1032 |
+@@ -82,4 +82,5 @@ static inline int syscall_get_arch(struct task_struct *task) |
1033 |
+ #endif |
1034 |
+ } |
1035 |
+ |
1036 |
++asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t); |
1037 |
+ #endif /* _ASM_RISCV_SYSCALL_H */ |
1038 |
+diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h |
1039 |
+index 1453a2f563bcc..208e31bc5d1c2 100644 |
1040 |
+--- a/arch/riscv/include/asm/vdso.h |
1041 |
++++ b/arch/riscv/include/asm/vdso.h |
1042 |
+@@ -8,27 +8,32 @@ |
1043 |
+ #ifndef _ASM_RISCV_VDSO_H |
1044 |
+ #define _ASM_RISCV_VDSO_H |
1045 |
+ |
1046 |
+-#include <linux/types.h> |
1047 |
+ |
1048 |
+-#ifndef CONFIG_GENERIC_TIME_VSYSCALL |
1049 |
+-struct vdso_data { |
1050 |
+-}; |
1051 |
+-#endif |
1052 |
++/* |
1053 |
++ * All systems with an MMU have a VDSO, but systems without an MMU don't |
1054 |
++ * support shared libraries and therefor don't have one. |
1055 |
++ */ |
1056 |
++#ifdef CONFIG_MMU |
1057 |
+ |
1058 |
++#include <linux/types.h> |
1059 |
+ /* |
1060 |
+- * The VDSO symbols are mapped into Linux so we can just use regular symbol |
1061 |
+- * addressing to get their offsets in userspace. The symbols are mapped at an |
1062 |
+- * offset of 0, but since the linker must support setting weak undefined |
1063 |
+- * symbols to the absolute address 0 it also happens to support other low |
1064 |
+- * addresses even when the code model suggests those low addresses would not |
1065 |
+- * otherwise be availiable. |
1066 |
++ * All systems with an MMU have a VDSO, but systems without an MMU don't |
1067 |
++ * support shared libraries and therefor don't have one. |
1068 |
+ */ |
1069 |
++#ifdef CONFIG_MMU |
1070 |
++ |
1071 |
++#define __VVAR_PAGES 1 |
1072 |
++ |
1073 |
++#ifndef __ASSEMBLY__ |
1074 |
++#include <generated/vdso-offsets.h> |
1075 |
++ |
1076 |
+ #define VDSO_SYMBOL(base, name) \ |
1077 |
+-({ \ |
1078 |
+- extern const char __vdso_##name[]; \ |
1079 |
+- (void __user *)((unsigned long)(base) + __vdso_##name); \ |
1080 |
+-}) |
1081 |
++ (void __user *)((unsigned long)(base) + __vdso_##name##_offset) |
1082 |
++ |
1083 |
++#endif /* CONFIG_MMU */ |
1084 |
++ |
1085 |
++#endif /* !__ASSEMBLY__ */ |
1086 |
+ |
1087 |
+-asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t); |
1088 |
++#endif /* CONFIG_MMU */ |
1089 |
+ |
1090 |
+ #endif /* _ASM_RISCV_VDSO_H */ |
1091 |
+diff --git a/arch/riscv/include/uapi/asm/unistd.h b/arch/riscv/include/uapi/asm/unistd.h |
1092 |
+index 4b989ae15d59f..8062996c2dfd0 100644 |
1093 |
+--- a/arch/riscv/include/uapi/asm/unistd.h |
1094 |
++++ b/arch/riscv/include/uapi/asm/unistd.h |
1095 |
+@@ -18,9 +18,10 @@ |
1096 |
+ #ifdef __LP64__ |
1097 |
+ #define __ARCH_WANT_NEW_STAT |
1098 |
+ #define __ARCH_WANT_SET_GET_RLIMIT |
1099 |
+-#define __ARCH_WANT_SYS_CLONE3 |
1100 |
+ #endif /* __LP64__ */ |
1101 |
+ |
1102 |
++#define __ARCH_WANT_SYS_CLONE3 |
1103 |
++ |
1104 |
+ #include <asm-generic/unistd.h> |
1105 |
+ |
1106 |
+ /* |
1107 |
+diff --git a/arch/riscv/kernel/syscall_table.c b/arch/riscv/kernel/syscall_table.c |
1108 |
+index a63c667c27b35..44b1420a22705 100644 |
1109 |
+--- a/arch/riscv/kernel/syscall_table.c |
1110 |
++++ b/arch/riscv/kernel/syscall_table.c |
1111 |
+@@ -7,7 +7,6 @@ |
1112 |
+ #include <linux/linkage.h> |
1113 |
+ #include <linux/syscalls.h> |
1114 |
+ #include <asm-generic/syscalls.h> |
1115 |
+-#include <asm/vdso.h> |
1116 |
+ #include <asm/syscall.h> |
1117 |
+ |
1118 |
+ #undef __SYSCALL |
1119 |
+diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c |
1120 |
+index 25a3b88495991..b70956d804081 100644 |
1121 |
+--- a/arch/riscv/kernel/vdso.c |
1122 |
++++ b/arch/riscv/kernel/vdso.c |
1123 |
+@@ -12,14 +12,24 @@ |
1124 |
+ #include <linux/binfmts.h> |
1125 |
+ #include <linux/err.h> |
1126 |
+ #include <asm/page.h> |
1127 |
++#include <asm/vdso.h> |
1128 |
++ |
1129 |
+ #ifdef CONFIG_GENERIC_TIME_VSYSCALL |
1130 |
+ #include <vdso/datapage.h> |
1131 |
+ #else |
1132 |
+-#include <asm/vdso.h> |
1133 |
++struct vdso_data { |
1134 |
++}; |
1135 |
+ #endif |
1136 |
+ |
1137 |
+ extern char vdso_start[], vdso_end[]; |
1138 |
+ |
1139 |
++enum vvar_pages { |
1140 |
++ VVAR_DATA_PAGE_OFFSET, |
1141 |
++ VVAR_NR_PAGES, |
1142 |
++}; |
1143 |
++ |
1144 |
++#define VVAR_SIZE (VVAR_NR_PAGES << PAGE_SHIFT) |
1145 |
++ |
1146 |
+ static unsigned int vdso_pages __ro_after_init; |
1147 |
+ static struct page **vdso_pagelist __ro_after_init; |
1148 |
+ |
1149 |
+@@ -38,7 +48,7 @@ static int __init vdso_init(void) |
1150 |
+ |
1151 |
+ vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; |
1152 |
+ vdso_pagelist = |
1153 |
+- kcalloc(vdso_pages + 1, sizeof(struct page *), GFP_KERNEL); |
1154 |
++ kcalloc(vdso_pages + VVAR_NR_PAGES, sizeof(struct page *), GFP_KERNEL); |
1155 |
+ if (unlikely(vdso_pagelist == NULL)) { |
1156 |
+ pr_err("vdso: pagelist allocation failed\n"); |
1157 |
+ return -ENOMEM; |
1158 |
+@@ -63,38 +73,41 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, |
1159 |
+ unsigned long vdso_base, vdso_len; |
1160 |
+ int ret; |
1161 |
+ |
1162 |
+- vdso_len = (vdso_pages + 1) << PAGE_SHIFT; |
1163 |
++ BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES); |
1164 |
++ |
1165 |
++ vdso_len = (vdso_pages + VVAR_NR_PAGES) << PAGE_SHIFT; |
1166 |
++ |
1167 |
++ if (mmap_write_lock_killable(mm)) |
1168 |
++ return -EINTR; |
1169 |
+ |
1170 |
+- mmap_write_lock(mm); |
1171 |
+ vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0); |
1172 |
+ if (IS_ERR_VALUE(vdso_base)) { |
1173 |
+ ret = vdso_base; |
1174 |
+ goto end; |
1175 |
+ } |
1176 |
+ |
1177 |
+- /* |
1178 |
+- * Put vDSO base into mm struct. We need to do this before calling |
1179 |
+- * install_special_mapping or the perf counter mmap tracking code |
1180 |
+- * will fail to recognise it as a vDSO (since arch_vma_name fails). |
1181 |
+- */ |
1182 |
+- mm->context.vdso = (void *)vdso_base; |
1183 |
++ mm->context.vdso = NULL; |
1184 |
++ ret = install_special_mapping(mm, vdso_base, VVAR_SIZE, |
1185 |
++ (VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]); |
1186 |
++ if (unlikely(ret)) |
1187 |
++ goto end; |
1188 |
+ |
1189 |
+ ret = |
1190 |
+- install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT, |
1191 |
++ install_special_mapping(mm, vdso_base + VVAR_SIZE, |
1192 |
++ vdso_pages << PAGE_SHIFT, |
1193 |
+ (VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC), |
1194 |
+ vdso_pagelist); |
1195 |
+ |
1196 |
+- if (unlikely(ret)) { |
1197 |
+- mm->context.vdso = NULL; |
1198 |
++ if (unlikely(ret)) |
1199 |
+ goto end; |
1200 |
+- } |
1201 |
+ |
1202 |
+- vdso_base += (vdso_pages << PAGE_SHIFT); |
1203 |
+- ret = install_special_mapping(mm, vdso_base, PAGE_SIZE, |
1204 |
+- (VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]); |
1205 |
++ /* |
1206 |
++ * Put vDSO base into mm struct. We need to do this before calling |
1207 |
++ * install_special_mapping or the perf counter mmap tracking code |
1208 |
++ * will fail to recognise it as a vDSO (since arch_vma_name fails). |
1209 |
++ */ |
1210 |
++ mm->context.vdso = (void *)vdso_base + VVAR_SIZE; |
1211 |
+ |
1212 |
+- if (unlikely(ret)) |
1213 |
+- mm->context.vdso = NULL; |
1214 |
+ end: |
1215 |
+ mmap_write_unlock(mm); |
1216 |
+ return ret; |
1217 |
+@@ -105,7 +118,7 @@ const char *arch_vma_name(struct vm_area_struct *vma) |
1218 |
+ if (vma->vm_mm && (vma->vm_start == (long)vma->vm_mm->context.vdso)) |
1219 |
+ return "[vdso]"; |
1220 |
+ if (vma->vm_mm && (vma->vm_start == |
1221 |
+- (long)vma->vm_mm->context.vdso + PAGE_SIZE)) |
1222 |
++ (long)vma->vm_mm->context.vdso - VVAR_SIZE)) |
1223 |
+ return "[vdso_data]"; |
1224 |
+ return NULL; |
1225 |
+ } |
1226 |
+diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile |
1227 |
+index 24d936c147cdf..f8cb9144a2842 100644 |
1228 |
+--- a/arch/riscv/kernel/vdso/Makefile |
1229 |
++++ b/arch/riscv/kernel/vdso/Makefile |
1230 |
+@@ -23,10 +23,10 @@ ifneq ($(c-gettimeofday-y),) |
1231 |
+ endif |
1232 |
+ |
1233 |
+ # Build rules |
1234 |
+-targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds vdso-syms.S |
1235 |
++targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds |
1236 |
+ obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) |
1237 |
+ |
1238 |
+-obj-y += vdso.o vdso-syms.o |
1239 |
++obj-y += vdso.o |
1240 |
+ CPPFLAGS_vdso.lds += -P -C -U$(ARCH) |
1241 |
+ |
1242 |
+ # Disable -pg to prevent insert call site |
1243 |
+@@ -43,20 +43,22 @@ $(obj)/vdso.o: $(obj)/vdso.so |
1244 |
+ # link rule for the .so file, .lds has to be first |
1245 |
+ $(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE |
1246 |
+ $(call if_changed,vdsold) |
1247 |
+-LDFLAGS_vdso.so.dbg = -shared -s -soname=linux-vdso.so.1 \ |
1248 |
++LDFLAGS_vdso.so.dbg = -shared -S -soname=linux-vdso.so.1 \ |
1249 |
+ --build-id=sha1 --hash-style=both --eh-frame-hdr |
1250 |
+ |
1251 |
+-# We also create a special relocatable object that should mirror the symbol |
1252 |
+-# table and layout of the linked DSO. With ld --just-symbols we can then |
1253 |
+-# refer to these symbols in the kernel code rather than hand-coded addresses. |
1254 |
+-$(obj)/vdso-syms.S: $(obj)/vdso.so FORCE |
1255 |
+- $(call if_changed,so2s) |
1256 |
+- |
1257 |
+ # strip rule for the .so file |
1258 |
+ $(obj)/%.so: OBJCOPYFLAGS := -S |
1259 |
+ $(obj)/%.so: $(obj)/%.so.dbg FORCE |
1260 |
+ $(call if_changed,objcopy) |
1261 |
+ |
1262 |
++# Generate VDSO offsets using helper script |
1263 |
++gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh |
1264 |
++quiet_cmd_vdsosym = VDSOSYM $@ |
1265 |
++ cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ |
1266 |
++ |
1267 |
++include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE |
1268 |
++ $(call if_changed,vdsosym) |
1269 |
++ |
1270 |
+ # actual build commands |
1271 |
+ # The DSO images are built using a special linker script |
1272 |
+ # Make sure only to export the intended __vdso_xxx symbol offsets. |
1273 |
+@@ -65,11 +67,6 @@ quiet_cmd_vdsold = VDSOLD $@ |
1274 |
+ $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \ |
1275 |
+ rm $@.tmp |
1276 |
+ |
1277 |
+-# Extracts symbol offsets from the VDSO, converting them into an assembly file |
1278 |
+-# that contains the same symbols at the same offsets. |
1279 |
+-quiet_cmd_so2s = SO2S $@ |
1280 |
+- cmd_so2s = $(NM) -D $< | $(srctree)/$(src)/so2s.sh > $@ |
1281 |
+- |
1282 |
+ # install commands for the unstripped file |
1283 |
+ quiet_cmd_vdso_install = INSTALL $@ |
1284 |
+ cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ |
1285 |
+diff --git a/arch/riscv/kernel/vdso/gen_vdso_offsets.sh b/arch/riscv/kernel/vdso/gen_vdso_offsets.sh |
1286 |
+new file mode 100755 |
1287 |
+index 0000000000000..c2e5613f34951 |
1288 |
+--- /dev/null |
1289 |
++++ b/arch/riscv/kernel/vdso/gen_vdso_offsets.sh |
1290 |
+@@ -0,0 +1,5 @@ |
1291 |
++#!/bin/sh |
1292 |
++# SPDX-License-Identifier: GPL-2.0 |
1293 |
++ |
1294 |
++LC_ALL=C |
1295 |
++sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define \2_offset\t0x\1/p' |
1296 |
+diff --git a/arch/riscv/kernel/vdso/so2s.sh b/arch/riscv/kernel/vdso/so2s.sh |
1297 |
+deleted file mode 100755 |
1298 |
+index e64cb6d9440e7..0000000000000 |
1299 |
+--- a/arch/riscv/kernel/vdso/so2s.sh |
1300 |
++++ /dev/null |
1301 |
+@@ -1,6 +0,0 @@ |
1302 |
+-#!/bin/sh |
1303 |
+-# SPDX-License-Identifier: GPL-2.0+ |
1304 |
+-# Copyright 2020 Palmer Dabbelt <palmerdabbelt@××××××.com> |
1305 |
+- |
1306 |
+-sed 's!\([0-9a-f]*\) T \([a-z0-9_]*\)\(@@LINUX_4.15\)*!.global \2\n.set \2,0x\1!' \ |
1307 |
+-| grep '^\.' |
1308 |
+diff --git a/arch/riscv/kernel/vdso/vdso.lds.S b/arch/riscv/kernel/vdso/vdso.lds.S |
1309 |
+index e6f558bca71bb..e9111f700af08 100644 |
1310 |
+--- a/arch/riscv/kernel/vdso/vdso.lds.S |
1311 |
++++ b/arch/riscv/kernel/vdso/vdso.lds.S |
1312 |
+@@ -3,12 +3,13 @@ |
1313 |
+ * Copyright (C) 2012 Regents of the University of California |
1314 |
+ */ |
1315 |
+ #include <asm/page.h> |
1316 |
++#include <asm/vdso.h> |
1317 |
+ |
1318 |
+ OUTPUT_ARCH(riscv) |
1319 |
+ |
1320 |
+ SECTIONS |
1321 |
+ { |
1322 |
+- PROVIDE(_vdso_data = . + PAGE_SIZE); |
1323 |
++ PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE); |
1324 |
+ . = SIZEOF_HEADERS; |
1325 |
+ |
1326 |
+ .hash : { *(.hash) } :text |
1327 |
+diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c |
1328 |
+index 094118663285d..89f81067e09ed 100644 |
1329 |
+--- a/arch/riscv/mm/cacheflush.c |
1330 |
++++ b/arch/riscv/mm/cacheflush.c |
1331 |
+@@ -16,6 +16,8 @@ static void ipi_remote_fence_i(void *info) |
1332 |
+ |
1333 |
+ void flush_icache_all(void) |
1334 |
+ { |
1335 |
++ local_flush_icache_all(); |
1336 |
++ |
1337 |
+ if (IS_ENABLED(CONFIG_RISCV_SBI)) |
1338 |
+ sbi_remote_fence_i(NULL); |
1339 |
+ else |
1340 |
+diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c |
1341 |
+index 840d8594437d5..1a374d021e256 100644 |
1342 |
+--- a/arch/s390/net/bpf_jit_comp.c |
1343 |
++++ b/arch/s390/net/bpf_jit_comp.c |
1344 |
+@@ -1826,7 +1826,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) |
1345 |
+ jit.addrs = kvcalloc(fp->len + 1, sizeof(*jit.addrs), GFP_KERNEL); |
1346 |
+ if (jit.addrs == NULL) { |
1347 |
+ fp = orig_fp; |
1348 |
+- goto out; |
1349 |
++ goto free_addrs; |
1350 |
+ } |
1351 |
+ /* |
1352 |
+ * Three initial passes: |
1353 |
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig |
1354 |
+index 88fb922c23a0a..51341f2e218de 100644 |
1355 |
+--- a/arch/x86/Kconfig |
1356 |
++++ b/arch/x86/Kconfig |
1357 |
+@@ -1400,7 +1400,7 @@ config HIGHMEM4G |
1358 |
+ |
1359 |
+ config HIGHMEM64G |
1360 |
+ bool "64GB" |
1361 |
+- depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6 |
1362 |
++ depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !MWINCHIP3D && !MK6 |
1363 |
+ select X86_PAE |
1364 |
+ help |
1365 |
+ Select this if you have a 32-bit processor and more than 4 |
1366 |
+diff --git a/arch/x86/include/asm/entry-common.h b/arch/x86/include/asm/entry-common.h |
1367 |
+index 14ebd21965691..43184640b579a 100644 |
1368 |
+--- a/arch/x86/include/asm/entry-common.h |
1369 |
++++ b/arch/x86/include/asm/entry-common.h |
1370 |
+@@ -25,7 +25,7 @@ static __always_inline void arch_check_user_regs(struct pt_regs *regs) |
1371 |
+ * For !SMAP hardware we patch out CLAC on entry. |
1372 |
+ */ |
1373 |
+ if (boot_cpu_has(X86_FEATURE_SMAP) || |
1374 |
+- (IS_ENABLED(CONFIG_64_BIT) && boot_cpu_has(X86_FEATURE_XENPV))) |
1375 |
++ (IS_ENABLED(CONFIG_64BIT) && boot_cpu_has(X86_FEATURE_XENPV))) |
1376 |
+ mask |= X86_EFLAGS_AC; |
1377 |
+ |
1378 |
+ WARN_ON_ONCE(flags & mask); |
1379 |
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c |
1380 |
+index 64b805bd6a542..340caa7aebfba 100644 |
1381 |
+--- a/arch/x86/kernel/cpu/common.c |
1382 |
++++ b/arch/x86/kernel/cpu/common.c |
1383 |
+@@ -320,6 +320,7 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c) |
1384 |
+ #ifdef CONFIG_X86_SMAP |
1385 |
+ cr4_set_bits(X86_CR4_SMAP); |
1386 |
+ #else |
1387 |
++ clear_cpu_cap(c, X86_FEATURE_SMAP); |
1388 |
+ cr4_clear_bits(X86_CR4_SMAP); |
1389 |
+ #endif |
1390 |
+ } |
1391 |
+diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c |
1392 |
+index 38837dad46e62..391a4e2b86049 100644 |
1393 |
+--- a/arch/x86/kernel/early-quirks.c |
1394 |
++++ b/arch/x86/kernel/early-quirks.c |
1395 |
+@@ -714,12 +714,6 @@ static struct chipset early_qrk[] __initdata = { |
1396 |
+ */ |
1397 |
+ { PCI_VENDOR_ID_INTEL, 0x0f00, |
1398 |
+ PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, |
1399 |
+- { PCI_VENDOR_ID_INTEL, 0x3e20, |
1400 |
+- PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, |
1401 |
+- { PCI_VENDOR_ID_INTEL, 0x3ec4, |
1402 |
+- PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, |
1403 |
+- { PCI_VENDOR_ID_INTEL, 0x8a12, |
1404 |
+- PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, |
1405 |
+ { PCI_VENDOR_ID_BROADCOM, 0x4331, |
1406 |
+ PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset}, |
1407 |
+ {} |
1408 |
+diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c |
1409 |
+index 445c57c9c5397..fa17a27390ab0 100644 |
1410 |
+--- a/arch/x86/kernel/fpu/signal.c |
1411 |
++++ b/arch/x86/kernel/fpu/signal.c |
1412 |
+@@ -379,9 +379,14 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, |
1413 |
+ sizeof(fpu->state.fxsave))) |
1414 |
+ return -EFAULT; |
1415 |
+ |
1416 |
+- /* Reject invalid MXCSR values. */ |
1417 |
+- if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask) |
1418 |
+- return -EINVAL; |
1419 |
++ if (IS_ENABLED(CONFIG_X86_64)) { |
1420 |
++ /* Reject invalid MXCSR values. */ |
1421 |
++ if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask) |
1422 |
++ return -EINVAL; |
1423 |
++ } else { |
1424 |
++ /* Mask invalid bits out for historical reasons (broken hardware). */ |
1425 |
++ fpu->state.fxsave.mxcsr &= ~mxcsr_feature_mask; |
1426 |
++ } |
1427 |
+ |
1428 |
+ /* Enforce XFEATURE_MASK_FPSSE when XSAVE is enabled */ |
1429 |
+ if (use_xsave()) |
1430 |
+diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c |
1431 |
+index 42fc41dd0e1f1..882213df37130 100644 |
1432 |
+--- a/arch/x86/kernel/hpet.c |
1433 |
++++ b/arch/x86/kernel/hpet.c |
1434 |
+@@ -10,6 +10,7 @@ |
1435 |
+ #include <asm/irq_remapping.h> |
1436 |
+ #include <asm/hpet.h> |
1437 |
+ #include <asm/time.h> |
1438 |
++#include <asm/mwait.h> |
1439 |
+ |
1440 |
+ #undef pr_fmt |
1441 |
+ #define pr_fmt(fmt) "hpet: " fmt |
1442 |
+@@ -916,6 +917,83 @@ static bool __init hpet_counting(void) |
1443 |
+ return false; |
1444 |
+ } |
1445 |
+ |
1446 |
++static bool __init mwait_pc10_supported(void) |
1447 |
++{ |
1448 |
++ unsigned int eax, ebx, ecx, mwait_substates; |
1449 |
++ |
1450 |
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) |
1451 |
++ return false; |
1452 |
++ |
1453 |
++ if (!cpu_feature_enabled(X86_FEATURE_MWAIT)) |
1454 |
++ return false; |
1455 |
++ |
1456 |
++ if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) |
1457 |
++ return false; |
1458 |
++ |
1459 |
++ cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates); |
1460 |
++ |
1461 |
++ return (ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) && |
1462 |
++ (ecx & CPUID5_ECX_INTERRUPT_BREAK) && |
1463 |
++ (mwait_substates & (0xF << 28)); |
1464 |
++} |
1465 |
++ |
1466 |
++/* |
1467 |
++ * Check whether the system supports PC10. If so force disable HPET as that |
1468 |
++ * stops counting in PC10. This check is overbroad as it does not take any |
1469 |
++ * of the following into account: |
1470 |
++ * |
1471 |
++ * - ACPI tables |
1472 |
++ * - Enablement of intel_idle |
1473 |
++ * - Command line arguments which limit intel_idle C-state support |
1474 |
++ * |
1475 |
++ * That's perfectly fine. HPET is a piece of hardware designed by committee |
1476 |
++ * and the only reasons why it is still in use on modern systems is the |
1477 |
++ * fact that it is impossible to reliably query TSC and CPU frequency via |
1478 |
++ * CPUID or firmware. |
1479 |
++ * |
1480 |
++ * If HPET is functional it is useful for calibrating TSC, but this can be |
1481 |
++ * done via PMTIMER as well which seems to be the last remaining timer on |
1482 |
++ * X86/INTEL platforms that has not been completely wreckaged by feature |
1483 |
++ * creep. |
1484 |
++ * |
1485 |
++ * In theory HPET support should be removed altogether, but there are older |
1486 |
++ * systems out there which depend on it because TSC and APIC timer are |
1487 |
++ * dysfunctional in deeper C-states. |
1488 |
++ * |
1489 |
++ * It's only 20 years now that hardware people have been asked to provide |
1490 |
++ * reliable and discoverable facilities which can be used for timekeeping |
1491 |
++ * and per CPU timer interrupts. |
1492 |
++ * |
1493 |
++ * The probability that this problem is going to be solved in the |
1494 |
++ * forseeable future is close to zero, so the kernel has to be cluttered |
1495 |
++ * with heuristics to keep up with the ever growing amount of hardware and |
1496 |
++ * firmware trainwrecks. Hopefully some day hardware people will understand |
1497 |
++ * that the approach of "This can be fixed in software" is not sustainable. |
1498 |
++ * Hope dies last... |
1499 |
++ */ |
1500 |
++static bool __init hpet_is_pc10_damaged(void) |
1501 |
++{ |
1502 |
++ unsigned long long pcfg; |
1503 |
++ |
1504 |
++ /* Check whether PC10 substates are supported */ |
1505 |
++ if (!mwait_pc10_supported()) |
1506 |
++ return false; |
1507 |
++ |
1508 |
++ /* Check whether PC10 is enabled in PKG C-state limit */ |
1509 |
++ rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, pcfg); |
1510 |
++ if ((pcfg & 0xF) < 8) |
1511 |
++ return false; |
1512 |
++ |
1513 |
++ if (hpet_force_user) { |
1514 |
++ pr_warn("HPET force enabled via command line, but dysfunctional in PC10.\n"); |
1515 |
++ return false; |
1516 |
++ } |
1517 |
++ |
1518 |
++ pr_info("HPET dysfunctional in PC10. Force disabled.\n"); |
1519 |
++ boot_hpet_disable = true; |
1520 |
++ return true; |
1521 |
++} |
1522 |
++ |
1523 |
+ /** |
1524 |
+ * hpet_enable - Try to setup the HPET timer. Returns 1 on success. |
1525 |
+ */ |
1526 |
+@@ -929,6 +1007,9 @@ int __init hpet_enable(void) |
1527 |
+ if (!is_hpet_capable()) |
1528 |
+ return 0; |
1529 |
+ |
1530 |
++ if (hpet_is_pc10_damaged()) |
1531 |
++ return 0; |
1532 |
++ |
1533 |
+ hpet_set_mapping(); |
1534 |
+ if (!hpet_virt_address) |
1535 |
+ return 0; |
1536 |
+diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c |
1537 |
+index 9f90f460a28cc..bf1033a62e480 100644 |
1538 |
+--- a/arch/x86/kernel/sev-shared.c |
1539 |
++++ b/arch/x86/kernel/sev-shared.c |
1540 |
+@@ -130,6 +130,8 @@ static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb, |
1541 |
+ } else { |
1542 |
+ ret = ES_VMM_ERROR; |
1543 |
+ } |
1544 |
++ } else if (ghcb->save.sw_exit_info_1 & 0xffffffff) { |
1545 |
++ ret = ES_VMM_ERROR; |
1546 |
+ } else { |
1547 |
+ ret = ES_OK; |
1548 |
+ } |
1549 |
+diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c |
1550 |
+index ee2beda590d0d..1d4a00e767ece 100644 |
1551 |
+--- a/arch/x86/platform/olpc/olpc.c |
1552 |
++++ b/arch/x86/platform/olpc/olpc.c |
1553 |
+@@ -274,7 +274,7 @@ static struct olpc_ec_driver ec_xo1_driver = { |
1554 |
+ |
1555 |
+ static struct olpc_ec_driver ec_xo1_5_driver = { |
1556 |
+ .ec_cmd = olpc_xo1_ec_cmd, |
1557 |
+-#ifdef CONFIG_OLPC_XO1_5_SCI |
1558 |
++#ifdef CONFIG_OLPC_XO15_SCI |
1559 |
+ /* |
1560 |
+ * XO-1.5 EC wakeups are available when olpc-xo15-sci driver is |
1561 |
+ * compiled in |
1562 |
+diff --git a/arch/xtensa/include/asm/kmem_layout.h b/arch/xtensa/include/asm/kmem_layout.h |
1563 |
+index 7cbf68ca71060..6fc05cba61a27 100644 |
1564 |
+--- a/arch/xtensa/include/asm/kmem_layout.h |
1565 |
++++ b/arch/xtensa/include/asm/kmem_layout.h |
1566 |
+@@ -78,7 +78,7 @@ |
1567 |
+ #endif |
1568 |
+ #define XCHAL_KIO_SIZE 0x10000000 |
1569 |
+ |
1570 |
+-#if (!XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY) && defined(CONFIG_OF) |
1571 |
++#if (!XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY) && defined(CONFIG_USE_OF) |
1572 |
+ #define XCHAL_KIO_PADDR xtensa_get_kio_paddr() |
1573 |
+ #ifndef __ASSEMBLY__ |
1574 |
+ extern unsigned long xtensa_kio_paddr; |
1575 |
+diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c |
1576 |
+index a48bf2d10ac2d..80cc9770a8d2d 100644 |
1577 |
+--- a/arch/xtensa/kernel/irq.c |
1578 |
++++ b/arch/xtensa/kernel/irq.c |
1579 |
+@@ -145,7 +145,7 @@ unsigned xtensa_get_ext_irq_no(unsigned irq) |
1580 |
+ |
1581 |
+ void __init init_IRQ(void) |
1582 |
+ { |
1583 |
+-#ifdef CONFIG_OF |
1584 |
++#ifdef CONFIG_USE_OF |
1585 |
+ irqchip_init(); |
1586 |
+ #else |
1587 |
+ #ifdef CONFIG_HAVE_SMP |
1588 |
+diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c |
1589 |
+index ed184106e4cf9..ee9082a142feb 100644 |
1590 |
+--- a/arch/xtensa/kernel/setup.c |
1591 |
++++ b/arch/xtensa/kernel/setup.c |
1592 |
+@@ -63,7 +63,7 @@ extern unsigned long initrd_end; |
1593 |
+ extern int initrd_below_start_ok; |
1594 |
+ #endif |
1595 |
+ |
1596 |
+-#ifdef CONFIG_OF |
1597 |
++#ifdef CONFIG_USE_OF |
1598 |
+ void *dtb_start = __dtb_start; |
1599 |
+ #endif |
1600 |
+ |
1601 |
+@@ -125,7 +125,7 @@ __tagtable(BP_TAG_INITRD, parse_tag_initrd); |
1602 |
+ |
1603 |
+ #endif /* CONFIG_BLK_DEV_INITRD */ |
1604 |
+ |
1605 |
+-#ifdef CONFIG_OF |
1606 |
++#ifdef CONFIG_USE_OF |
1607 |
+ |
1608 |
+ static int __init parse_tag_fdt(const bp_tag_t *tag) |
1609 |
+ { |
1610 |
+@@ -135,7 +135,7 @@ static int __init parse_tag_fdt(const bp_tag_t *tag) |
1611 |
+ |
1612 |
+ __tagtable(BP_TAG_FDT, parse_tag_fdt); |
1613 |
+ |
1614 |
+-#endif /* CONFIG_OF */ |
1615 |
++#endif /* CONFIG_USE_OF */ |
1616 |
+ |
1617 |
+ static int __init parse_tag_cmdline(const bp_tag_t* tag) |
1618 |
+ { |
1619 |
+@@ -183,7 +183,7 @@ static int __init parse_bootparam(const bp_tag_t *tag) |
1620 |
+ } |
1621 |
+ #endif |
1622 |
+ |
1623 |
+-#ifdef CONFIG_OF |
1624 |
++#ifdef CONFIG_USE_OF |
1625 |
+ |
1626 |
+ #if !XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY |
1627 |
+ unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR; |
1628 |
+@@ -232,7 +232,7 @@ void __init early_init_devtree(void *params) |
1629 |
+ strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
1630 |
+ } |
1631 |
+ |
1632 |
+-#endif /* CONFIG_OF */ |
1633 |
++#endif /* CONFIG_USE_OF */ |
1634 |
+ |
1635 |
+ /* |
1636 |
+ * Initialize architecture. (Early stage) |
1637 |
+@@ -253,7 +253,7 @@ void __init init_arch(bp_tag_t *bp_start) |
1638 |
+ if (bp_start) |
1639 |
+ parse_bootparam(bp_start); |
1640 |
+ |
1641 |
+-#ifdef CONFIG_OF |
1642 |
++#ifdef CONFIG_USE_OF |
1643 |
+ early_init_devtree(dtb_start); |
1644 |
+ #endif |
1645 |
+ |
1646 |
+diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c |
1647 |
+index 7e4d97dc8bd8f..38acda4f04e85 100644 |
1648 |
+--- a/arch/xtensa/mm/mmu.c |
1649 |
++++ b/arch/xtensa/mm/mmu.c |
1650 |
+@@ -101,7 +101,7 @@ void init_mmu(void) |
1651 |
+ |
1652 |
+ void init_kio(void) |
1653 |
+ { |
1654 |
+-#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF) |
1655 |
++#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_USE_OF) |
1656 |
+ /* |
1657 |
+ * Update the IO area mapping in case xtensa_kio_paddr has changed |
1658 |
+ */ |
1659 |
+diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c |
1660 |
+index 148a4dd8cb9ac..418ada474a85d 100644 |
1661 |
+--- a/drivers/bus/ti-sysc.c |
1662 |
++++ b/drivers/bus/ti-sysc.c |
1663 |
+@@ -1468,6 +1468,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { |
1664 |
+ /* Quirks that need to be set based on detected module */ |
1665 |
+ SYSC_QUIRK("aess", 0, 0, 0x10, -ENODEV, 0x40000000, 0xffffffff, |
1666 |
+ SYSC_MODULE_QUIRK_AESS), |
1667 |
++ /* Errata i893 handling for dra7 dcan1 and 2 */ |
1668 |
++ SYSC_QUIRK("dcan", 0x4ae3c000, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff, |
1669 |
++ SYSC_QUIRK_CLKDM_NOAUTO), |
1670 |
+ SYSC_QUIRK("dcan", 0x48480000, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff, |
1671 |
+ SYSC_QUIRK_CLKDM_NOAUTO), |
1672 |
+ SYSC_QUIRK("dss", 0x4832a000, 0, 0x10, 0x14, 0x00000020, 0xffffffff, |
1673 |
+@@ -2955,6 +2958,7 @@ static int sysc_init_soc(struct sysc *ddata) |
1674 |
+ break; |
1675 |
+ case SOC_AM3: |
1676 |
+ sysc_add_disabled(0x48310000); /* rng */ |
1677 |
++ break; |
1678 |
+ default: |
1679 |
+ break; |
1680 |
+ } |
1681 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h |
1682 |
+index 177a663a6a691..a1c5bd2859fc3 100644 |
1683 |
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h |
1684 |
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h |
1685 |
+@@ -1082,6 +1082,7 @@ struct amdgpu_device { |
1686 |
+ |
1687 |
+ bool no_hw_access; |
1688 |
+ struct pci_saved_state *pci_state; |
1689 |
++ pci_channel_state_t pci_channel_state; |
1690 |
+ |
1691 |
+ struct amdgpu_reset_control *reset_cntl; |
1692 |
+ }; |
1693 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |
1694 |
+index 4fb15750b9bb4..b18c0697356c1 100644 |
1695 |
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |
1696 |
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |
1697 |
+@@ -563,6 +563,7 @@ kfd_mem_dmaunmap_userptr(struct kgd_mem *mem, |
1698 |
+ |
1699 |
+ dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0); |
1700 |
+ sg_free_table(ttm->sg); |
1701 |
++ kfree(ttm->sg); |
1702 |
+ ttm->sg = NULL; |
1703 |
+ } |
1704 |
+ |
1705 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |
1706 |
+index d3247a5cceb4c..d60096b3b2c2a 100644 |
1707 |
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |
1708 |
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |
1709 |
+@@ -5329,6 +5329,8 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta |
1710 |
+ return PCI_ERS_RESULT_DISCONNECT; |
1711 |
+ } |
1712 |
+ |
1713 |
++ adev->pci_channel_state = state; |
1714 |
++ |
1715 |
+ switch (state) { |
1716 |
+ case pci_channel_io_normal: |
1717 |
+ return PCI_ERS_RESULT_CAN_RECOVER; |
1718 |
+@@ -5471,6 +5473,10 @@ void amdgpu_pci_resume(struct pci_dev *pdev) |
1719 |
+ |
1720 |
+ DRM_INFO("PCI error: resume callback!!\n"); |
1721 |
+ |
1722 |
++ /* Only continue execution for the case of pci_channel_io_frozen */ |
1723 |
++ if (adev->pci_channel_state != pci_channel_io_frozen) |
1724 |
++ return; |
1725 |
++ |
1726 |
+ for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
1727 |
+ struct amdgpu_ring *ring = adev->rings[i]; |
1728 |
+ |
1729 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c |
1730 |
+index b4ced45301bec..1795d448c7000 100644 |
1731 |
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c |
1732 |
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c |
1733 |
+@@ -31,6 +31,8 @@ |
1734 |
+ /* delay 0.1 second to enable gfx off feature */ |
1735 |
+ #define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(100) |
1736 |
+ |
1737 |
++#define GFX_OFF_NO_DELAY 0 |
1738 |
++ |
1739 |
+ /* |
1740 |
+ * GPU GFX IP block helpers function. |
1741 |
+ */ |
1742 |
+@@ -558,6 +560,8 @@ int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev) |
1743 |
+ |
1744 |
+ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) |
1745 |
+ { |
1746 |
++ unsigned long delay = GFX_OFF_DELAY_ENABLE; |
1747 |
++ |
1748 |
+ if (!(adev->pm.pp_feature & PP_GFXOFF_MASK)) |
1749 |
+ return; |
1750 |
+ |
1751 |
+@@ -573,8 +577,14 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) |
1752 |
+ |
1753 |
+ adev->gfx.gfx_off_req_count--; |
1754 |
+ |
1755 |
+- if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state) |
1756 |
+- schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE); |
1757 |
++ if (adev->gfx.gfx_off_req_count == 0 && |
1758 |
++ !adev->gfx.gfx_off_state) { |
1759 |
++ /* If going to s2idle, no need to wait */ |
1760 |
++ if (adev->in_s0ix) |
1761 |
++ delay = GFX_OFF_NO_DELAY; |
1762 |
++ schedule_delayed_work(&adev->gfx.gfx_off_delay_work, |
1763 |
++ delay); |
1764 |
++ } |
1765 |
+ } else { |
1766 |
+ if (adev->gfx.gfx_off_req_count == 0) { |
1767 |
+ cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); |
1768 |
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h |
1769 |
+index d8b22618b79e8..c337588231ff0 100644 |
1770 |
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h |
1771 |
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h |
1772 |
+@@ -118,6 +118,7 @@ struct dcn10_link_enc_registers { |
1773 |
+ uint32_t RDPCSTX_PHY_CNTL4; |
1774 |
+ uint32_t RDPCSTX_PHY_CNTL5; |
1775 |
+ uint32_t RDPCSTX_PHY_CNTL6; |
1776 |
++ uint32_t RDPCSPIPE_PHY_CNTL6; |
1777 |
+ uint32_t RDPCSTX_PHY_CNTL7; |
1778 |
+ uint32_t RDPCSTX_PHY_CNTL8; |
1779 |
+ uint32_t RDPCSTX_PHY_CNTL9; |
1780 |
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c |
1781 |
+index 90127c1f9e35d..b0892443fbd57 100644 |
1782 |
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c |
1783 |
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c |
1784 |
+@@ -37,6 +37,7 @@ |
1785 |
+ |
1786 |
+ #include "link_enc_cfg.h" |
1787 |
+ #include "dc_dmub_srv.h" |
1788 |
++#include "dal_asic_id.h" |
1789 |
+ |
1790 |
+ #define CTX \ |
1791 |
+ enc10->base.ctx |
1792 |
+@@ -62,6 +63,10 @@ |
1793 |
+ #define AUX_REG_WRITE(reg_name, val) \ |
1794 |
+ dm_write_reg(CTX, AUX_REG(reg_name), val) |
1795 |
+ |
1796 |
++#ifndef MIN |
1797 |
++#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) |
1798 |
++#endif |
1799 |
++ |
1800 |
+ void dcn31_link_encoder_set_dio_phy_mux( |
1801 |
+ struct link_encoder *enc, |
1802 |
+ enum encoder_type_select sel, |
1803 |
+@@ -215,8 +220,8 @@ static const struct link_encoder_funcs dcn31_link_enc_funcs = { |
1804 |
+ .fec_is_active = enc2_fec_is_active, |
1805 |
+ .get_dig_frontend = dcn10_get_dig_frontend, |
1806 |
+ .get_dig_mode = dcn10_get_dig_mode, |
1807 |
+- .is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode, |
1808 |
+- .get_max_link_cap = dcn20_link_encoder_get_max_link_cap, |
1809 |
++ .is_in_alt_mode = dcn31_link_encoder_is_in_alt_mode, |
1810 |
++ .get_max_link_cap = dcn31_link_encoder_get_max_link_cap, |
1811 |
+ .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux, |
1812 |
+ }; |
1813 |
+ |
1814 |
+@@ -404,3 +409,60 @@ void dcn31_link_encoder_disable_output( |
1815 |
+ } |
1816 |
+ } |
1817 |
+ |
1818 |
++bool dcn31_link_encoder_is_in_alt_mode(struct link_encoder *enc) |
1819 |
++{ |
1820 |
++ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); |
1821 |
++ uint32_t dp_alt_mode_disable; |
1822 |
++ bool is_usb_c_alt_mode = false; |
1823 |
++ |
1824 |
++ if (enc->features.flags.bits.DP_IS_USB_C) { |
1825 |
++ if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) { |
1826 |
++ // [Note] no need to check hw_internal_rev once phy mux selection is ready |
1827 |
++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable); |
1828 |
++ } else { |
1829 |
++ /* |
1830 |
++ * B0 phys use a new set of registers to check whether alt mode is disabled. |
1831 |
++ * if value == 1 alt mode is disabled, otherwise it is enabled. |
1832 |
++ */ |
1833 |
++ if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A) |
1834 |
++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B) |
1835 |
++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) { |
1836 |
++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable); |
1837 |
++ } else { |
1838 |
++ // [Note] need to change TRANSMITTER_UNIPHY_C/D to F/G once phy mux selection is ready |
1839 |
++ REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable); |
1840 |
++ } |
1841 |
++ } |
1842 |
++ |
1843 |
++ is_usb_c_alt_mode = (dp_alt_mode_disable == 0); |
1844 |
++ } |
1845 |
++ |
1846 |
++ return is_usb_c_alt_mode; |
1847 |
++} |
1848 |
++ |
1849 |
++void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc, |
1850 |
++ struct dc_link_settings *link_settings) |
1851 |
++{ |
1852 |
++ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); |
1853 |
++ uint32_t is_in_usb_c_dp4_mode = 0; |
1854 |
++ |
1855 |
++ dcn10_link_encoder_get_max_link_cap(enc, link_settings); |
1856 |
++ |
1857 |
++ /* in usb c dp2 mode, max lane count is 2 */ |
1858 |
++ if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) { |
1859 |
++ if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) { |
1860 |
++ // [Note] no need to check hw_internal_rev once phy mux selection is ready |
1861 |
++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode); |
1862 |
++ } else { |
1863 |
++ if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A) |
1864 |
++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B) |
1865 |
++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) { |
1866 |
++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode); |
1867 |
++ } else { |
1868 |
++ REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode); |
1869 |
++ } |
1870 |
++ } |
1871 |
++ if (!is_in_usb_c_dp4_mode) |
1872 |
++ link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count); |
1873 |
++ } |
1874 |
++} |
1875 |
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h |
1876 |
+index 32d146312838b..3454f1e7c1f17 100644 |
1877 |
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h |
1878 |
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h |
1879 |
+@@ -69,6 +69,7 @@ |
1880 |
+ SRI(RDPCSTX_PHY_CNTL4, RDPCSTX, id), \ |
1881 |
+ SRI(RDPCSTX_PHY_CNTL5, RDPCSTX, id), \ |
1882 |
+ SRI(RDPCSTX_PHY_CNTL6, RDPCSTX, id), \ |
1883 |
++ SRI(RDPCSPIPE_PHY_CNTL6, RDPCSPIPE, id), \ |
1884 |
+ SRI(RDPCSTX_PHY_CNTL7, RDPCSTX, id), \ |
1885 |
+ SRI(RDPCSTX_PHY_CNTL8, RDPCSTX, id), \ |
1886 |
+ SRI(RDPCSTX_PHY_CNTL9, RDPCSTX, id), \ |
1887 |
+@@ -115,7 +116,9 @@ |
1888 |
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX2_MPLL_EN, mask_sh),\ |
1889 |
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX3_MPLL_EN, mask_sh),\ |
1890 |
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\ |
1891 |
+- LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\ |
1892 |
++ LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\ |
1893 |
++ LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\ |
1894 |
++ LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE_ACK, mask_sh),\ |
1895 |
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_QUOT, mask_sh),\ |
1896 |
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_DEN, mask_sh),\ |
1897 |
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL8, RDPCS_PHY_DP_MPLLB_SSC_PEAK, mask_sh),\ |
1898 |
+@@ -243,4 +246,13 @@ void dcn31_link_encoder_disable_output( |
1899 |
+ struct link_encoder *enc, |
1900 |
+ enum signal_type signal); |
1901 |
+ |
1902 |
++/* |
1903 |
++ * Check whether USB-C DP Alt mode is disabled |
1904 |
++ */ |
1905 |
++bool dcn31_link_encoder_is_in_alt_mode( |
1906 |
++ struct link_encoder *enc); |
1907 |
++ |
1908 |
++void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc, |
1909 |
++ struct dc_link_settings *link_settings); |
1910 |
++ |
1911 |
+ #endif /* __DC_LINK_ENCODER__DCN31_H__ */ |
1912 |
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c |
1913 |
+index cd3248dc31d87..7ea362a864c43 100644 |
1914 |
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c |
1915 |
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c |
1916 |
+@@ -928,7 +928,7 @@ static const struct dc_debug_options debug_defaults_drv = { |
1917 |
+ .disable_dcc = DCC_ENABLE, |
1918 |
+ .vsr_support = true, |
1919 |
+ .performance_trace = false, |
1920 |
+- .max_downscale_src_width = 7680,/*upto 8K*/ |
1921 |
++ .max_downscale_src_width = 3840,/*upto 4K*/ |
1922 |
+ .disable_pplib_wm_range = false, |
1923 |
+ .scl_reset_length10 = true, |
1924 |
+ .sanity_checks = false, |
1925 |
+@@ -1284,6 +1284,12 @@ static struct stream_encoder *dcn31_stream_encoder_create( |
1926 |
+ if (!enc1 || !vpg || !afmt) |
1927 |
+ return NULL; |
1928 |
+ |
1929 |
++ if (ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && |
1930 |
++ ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { |
1931 |
++ if ((eng_id == ENGINE_ID_DIGC) || (eng_id == ENGINE_ID_DIGD)) |
1932 |
++ eng_id = eng_id + 3; // For B0 only. C->F, D->G. |
1933 |
++ } |
1934 |
++ |
1935 |
+ dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, |
1936 |
+ eng_id, vpg, afmt, |
1937 |
+ &stream_enc_regs[eng_id], |
1938 |
+diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h |
1939 |
+index 381c17caace18..5adc471bef57f 100644 |
1940 |
+--- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h |
1941 |
++++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h |
1942 |
+@@ -227,7 +227,7 @@ enum { |
1943 |
+ #define FAMILY_YELLOW_CARP 146 |
1944 |
+ |
1945 |
+ #define YELLOW_CARP_A0 0x01 |
1946 |
+-#define YELLOW_CARP_B0 0x02 // TODO: DCN31 - update with correct B0 ID |
1947 |
++#define YELLOW_CARP_B0 0x1A |
1948 |
+ #define YELLOW_CARP_UNKNOWN 0xFF |
1949 |
+ |
1950 |
+ #ifndef ASICREV_IS_YELLOW_CARP |
1951 |
+diff --git a/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h |
1952 |
+index 92caf8441d1e0..01a56556cde13 100644 |
1953 |
+--- a/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h |
1954 |
++++ b/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h |
1955 |
+@@ -11932,5 +11932,32 @@ |
1956 |
+ #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_RX_OVRD_OUT_2 0xe0c7 |
1957 |
+ #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_TX_OVRD_IN_2 0xe0c8 |
1958 |
+ |
1959 |
++//RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6 |
1960 |
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT 0x10 |
1961 |
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT 0x11 |
1962 |
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT 0x12 |
1963 |
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK 0x00010000L |
1964 |
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK 0x00020000L |
1965 |
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK 0x00040000L |
1966 |
++ |
1967 |
++//RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6 |
1968 |
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT 0x10 |
1969 |
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT 0x11 |
1970 |
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT 0x12 |
1971 |
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK 0x00010000L |
1972 |
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK 0x00020000L |
1973 |
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK 0x00040000L |
1974 |
++ |
1975 |
++//[Note] Hack. RDPCSPIPE only has 2 instances. |
1976 |
++#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6 0x2d73 |
1977 |
++#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2 |
1978 |
++#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6 0x2e4b |
1979 |
++#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2 |
1980 |
++#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6 0x2d73 |
1981 |
++#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2 |
1982 |
++#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6 0x2e4b |
1983 |
++#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2 |
1984 |
++#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6 0x2d73 |
1985 |
++#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2 |
1986 |
+ |
1987 |
+ #endif |
1988 |
+diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c |
1989 |
+index 16812488c5ddc..13bafa9d49c01 100644 |
1990 |
+--- a/drivers/gpu/drm/i915/display/icl_dsi.c |
1991 |
++++ b/drivers/gpu/drm/i915/display/icl_dsi.c |
1992 |
+@@ -1253,15 +1253,36 @@ static void gen11_dsi_pre_enable(struct intel_atomic_state *state, |
1993 |
+ gen11_dsi_set_transcoder_timings(encoder, pipe_config); |
1994 |
+ } |
1995 |
+ |
1996 |
++/* |
1997 |
++ * Wa_1409054076:icl,jsl,ehl |
1998 |
++ * When pipe A is disabled and MIPI DSI is enabled on pipe B, |
1999 |
++ * the AMT KVMR feature will incorrectly see pipe A as enabled. |
2000 |
++ * Set 0x42080 bit 23=1 before enabling DSI on pipe B and leave |
2001 |
++ * it set while DSI is enabled on pipe B |
2002 |
++ */ |
2003 |
++static void icl_apply_kvmr_pipe_a_wa(struct intel_encoder *encoder, |
2004 |
++ enum pipe pipe, bool enable) |
2005 |
++{ |
2006 |
++ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2007 |
++ |
2008 |
++ if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B) |
2009 |
++ intel_de_rmw(dev_priv, CHICKEN_PAR1_1, |
2010 |
++ IGNORE_KVMR_PIPE_A, |
2011 |
++ enable ? IGNORE_KVMR_PIPE_A : 0); |
2012 |
++} |
2013 |
+ static void gen11_dsi_enable(struct intel_atomic_state *state, |
2014 |
+ struct intel_encoder *encoder, |
2015 |
+ const struct intel_crtc_state *crtc_state, |
2016 |
+ const struct drm_connector_state *conn_state) |
2017 |
+ { |
2018 |
+ struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
2019 |
++ struct intel_crtc *crtc = to_intel_crtc(conn_state->crtc); |
2020 |
+ |
2021 |
+ drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder); |
2022 |
+ |
2023 |
++ /* Wa_1409054076:icl,jsl,ehl */ |
2024 |
++ icl_apply_kvmr_pipe_a_wa(encoder, crtc->pipe, true); |
2025 |
++ |
2026 |
+ /* step6d: enable dsi transcoder */ |
2027 |
+ gen11_dsi_enable_transcoder(encoder); |
2028 |
+ |
2029 |
+@@ -1415,6 +1436,7 @@ static void gen11_dsi_disable(struct intel_atomic_state *state, |
2030 |
+ const struct drm_connector_state *old_conn_state) |
2031 |
+ { |
2032 |
+ struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
2033 |
++ struct intel_crtc *crtc = to_intel_crtc(old_conn_state->crtc); |
2034 |
+ |
2035 |
+ /* step1: turn off backlight */ |
2036 |
+ intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); |
2037 |
+@@ -1423,6 +1445,9 @@ static void gen11_dsi_disable(struct intel_atomic_state *state, |
2038 |
+ /* step2d,e: disable transcoder and wait */ |
2039 |
+ gen11_dsi_disable_transcoder(encoder); |
2040 |
+ |
2041 |
++ /* Wa_1409054076:icl,jsl,ehl */ |
2042 |
++ icl_apply_kvmr_pipe_a_wa(encoder, crtc->pipe, false); |
2043 |
++ |
2044 |
+ /* step2f,g: powerdown panel */ |
2045 |
+ gen11_dsi_powerdown_panel(encoder); |
2046 |
+ |
2047 |
+@@ -1548,6 +1573,28 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder, |
2048 |
+ pipe_config->mode_flags |= I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE; |
2049 |
+ } |
2050 |
+ |
2051 |
++static void gen11_dsi_sync_state(struct intel_encoder *encoder, |
2052 |
++ const struct intel_crtc_state *crtc_state) |
2053 |
++{ |
2054 |
++ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2055 |
++ struct intel_crtc *intel_crtc; |
2056 |
++ enum pipe pipe; |
2057 |
++ |
2058 |
++ if (!crtc_state) |
2059 |
++ return; |
2060 |
++ |
2061 |
++ intel_crtc = to_intel_crtc(crtc_state->uapi.crtc); |
2062 |
++ pipe = intel_crtc->pipe; |
2063 |
++ |
2064 |
++ /* wa verify 1409054076:icl,jsl,ehl */ |
2065 |
++ if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B && |
2066 |
++ !(intel_de_read(dev_priv, CHICKEN_PAR1_1) & IGNORE_KVMR_PIPE_A)) |
2067 |
++ drm_dbg_kms(&dev_priv->drm, |
2068 |
++ "[ENCODER:%d:%s] BIOS left IGNORE_KVMR_PIPE_A cleared with pipe B enabled\n", |
2069 |
++ encoder->base.base.id, |
2070 |
++ encoder->base.name); |
2071 |
++} |
2072 |
++ |
2073 |
+ static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder, |
2074 |
+ struct intel_crtc_state *crtc_state) |
2075 |
+ { |
2076 |
+@@ -1966,6 +2013,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) |
2077 |
+ encoder->post_disable = gen11_dsi_post_disable; |
2078 |
+ encoder->port = port; |
2079 |
+ encoder->get_config = gen11_dsi_get_config; |
2080 |
++ encoder->sync_state = gen11_dsi_sync_state; |
2081 |
+ encoder->update_pipe = intel_panel_update_backlight; |
2082 |
+ encoder->compute_config = gen11_dsi_compute_config; |
2083 |
+ encoder->get_hw_state = gen11_dsi_get_hw_state; |
2084 |
+diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c |
2085 |
+index 5f4f316b3ab5c..4e4429535f9e4 100644 |
2086 |
+--- a/drivers/gpu/drm/i915/display/intel_audio.c |
2087 |
++++ b/drivers/gpu/drm/i915/display/intel_audio.c |
2088 |
+@@ -1308,8 +1308,9 @@ static void i915_audio_component_init(struct drm_i915_private *dev_priv) |
2089 |
+ else |
2090 |
+ aud_freq = aud_freq_init; |
2091 |
+ |
2092 |
+- /* use BIOS provided value for TGL unless it is a known bad value */ |
2093 |
+- if (IS_TIGERLAKE(dev_priv) && aud_freq_init != AUD_FREQ_TGL_BROKEN) |
2094 |
++ /* use BIOS provided value for TGL and RKL unless it is a known bad value */ |
2095 |
++ if ((IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv)) && |
2096 |
++ aud_freq_init != AUD_FREQ_TGL_BROKEN) |
2097 |
+ aud_freq = aud_freq_init; |
2098 |
+ |
2099 |
+ drm_dbg_kms(&dev_priv->drm, "use AUD_FREQ_CNTRL of 0x%x (init value 0x%x)\n", |
2100 |
+diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c |
2101 |
+index aa667fa711584..106f696e50a0e 100644 |
2102 |
+--- a/drivers/gpu/drm/i915/display/intel_bios.c |
2103 |
++++ b/drivers/gpu/drm/i915/display/intel_bios.c |
2104 |
+@@ -451,13 +451,23 @@ parse_lfp_backlight(struct drm_i915_private *i915, |
2105 |
+ } |
2106 |
+ |
2107 |
+ i915->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI; |
2108 |
+- if (bdb->version >= 191 && |
2109 |
+- get_blocksize(backlight_data) >= sizeof(*backlight_data)) { |
2110 |
+- const struct lfp_backlight_control_method *method; |
2111 |
++ if (bdb->version >= 191) { |
2112 |
++ size_t exp_size; |
2113 |
+ |
2114 |
+- method = &backlight_data->backlight_control[panel_type]; |
2115 |
+- i915->vbt.backlight.type = method->type; |
2116 |
+- i915->vbt.backlight.controller = method->controller; |
2117 |
++ if (bdb->version >= 236) |
2118 |
++ exp_size = sizeof(struct bdb_lfp_backlight_data); |
2119 |
++ else if (bdb->version >= 234) |
2120 |
++ exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234; |
2121 |
++ else |
2122 |
++ exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191; |
2123 |
++ |
2124 |
++ if (get_blocksize(backlight_data) >= exp_size) { |
2125 |
++ const struct lfp_backlight_control_method *method; |
2126 |
++ |
2127 |
++ method = &backlight_data->backlight_control[panel_type]; |
2128 |
++ i915->vbt.backlight.type = method->type; |
2129 |
++ i915->vbt.backlight.controller = method->controller; |
2130 |
++ } |
2131 |
+ } |
2132 |
+ |
2133 |
+ i915->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz; |
2134 |
+diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c |
2135 |
+index 00dade49665b8..89a109f65f389 100644 |
2136 |
+--- a/drivers/gpu/drm/i915/display/intel_ddi.c |
2137 |
++++ b/drivers/gpu/drm/i915/display/intel_ddi.c |
2138 |
+@@ -3899,7 +3899,13 @@ void hsw_ddi_get_config(struct intel_encoder *encoder, |
2139 |
+ static void intel_ddi_sync_state(struct intel_encoder *encoder, |
2140 |
+ const struct intel_crtc_state *crtc_state) |
2141 |
+ { |
2142 |
+- if (intel_crtc_has_dp_encoder(crtc_state)) |
2143 |
++ struct drm_i915_private *i915 = to_i915(encoder->base.dev); |
2144 |
++ enum phy phy = intel_port_to_phy(i915, encoder->port); |
2145 |
++ |
2146 |
++ if (intel_phy_is_tc(i915, phy)) |
2147 |
++ intel_tc_port_sanitize(enc_to_dig_port(encoder)); |
2148 |
++ |
2149 |
++ if (crtc_state && intel_crtc_has_dp_encoder(crtc_state)) |
2150 |
+ intel_dp_sync_state(encoder, crtc_state); |
2151 |
+ } |
2152 |
+ |
2153 |
+diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c |
2154 |
+index 0a8a2395c8aca..bb1d2b19be151 100644 |
2155 |
+--- a/drivers/gpu/drm/i915/display/intel_display.c |
2156 |
++++ b/drivers/gpu/drm/i915/display/intel_display.c |
2157 |
+@@ -12933,18 +12933,16 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) |
2158 |
+ readout_plane_state(dev_priv); |
2159 |
+ |
2160 |
+ for_each_intel_encoder(dev, encoder) { |
2161 |
++ struct intel_crtc_state *crtc_state = NULL; |
2162 |
++ |
2163 |
+ pipe = 0; |
2164 |
+ |
2165 |
+ if (encoder->get_hw_state(encoder, &pipe)) { |
2166 |
+- struct intel_crtc_state *crtc_state; |
2167 |
+- |
2168 |
+ crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
2169 |
+ crtc_state = to_intel_crtc_state(crtc->base.state); |
2170 |
+ |
2171 |
+ encoder->base.crtc = &crtc->base; |
2172 |
+ intel_encoder_get_config(encoder, crtc_state); |
2173 |
+- if (encoder->sync_state) |
2174 |
+- encoder->sync_state(encoder, crtc_state); |
2175 |
+ |
2176 |
+ /* read out to slave crtc as well for bigjoiner */ |
2177 |
+ if (crtc_state->bigjoiner) { |
2178 |
+@@ -12959,6 +12957,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) |
2179 |
+ encoder->base.crtc = NULL; |
2180 |
+ } |
2181 |
+ |
2182 |
++ if (encoder->sync_state) |
2183 |
++ encoder->sync_state(encoder, crtc_state); |
2184 |
++ |
2185 |
+ drm_dbg_kms(&dev_priv->drm, |
2186 |
+ "[ENCODER:%d:%s] hw state readout: %s, pipe %c\n", |
2187 |
+ encoder->base.base.id, encoder->base.name, |
2188 |
+@@ -13241,17 +13242,6 @@ intel_modeset_setup_hw_state(struct drm_device *dev, |
2189 |
+ intel_modeset_readout_hw_state(dev); |
2190 |
+ |
2191 |
+ /* HW state is read out, now we need to sanitize this mess. */ |
2192 |
+- |
2193 |
+- /* Sanitize the TypeC port mode upfront, encoders depend on this */ |
2194 |
+- for_each_intel_encoder(dev, encoder) { |
2195 |
+- enum phy phy = intel_port_to_phy(dev_priv, encoder->port); |
2196 |
+- |
2197 |
+- /* We need to sanitize only the MST primary port. */ |
2198 |
+- if (encoder->type != INTEL_OUTPUT_DP_MST && |
2199 |
+- intel_phy_is_tc(dev_priv, phy)) |
2200 |
+- intel_tc_port_sanitize(enc_to_dig_port(encoder)); |
2201 |
+- } |
2202 |
+- |
2203 |
+ get_encoder_power_domains(dev_priv); |
2204 |
+ |
2205 |
+ if (HAS_PCH_IBX(dev_priv)) |
2206 |
+diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h |
2207 |
+index dbe24d7e73759..cf1ffe4a0e46a 100644 |
2208 |
+--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h |
2209 |
++++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h |
2210 |
+@@ -814,6 +814,11 @@ struct lfp_brightness_level { |
2211 |
+ u16 reserved; |
2212 |
+ } __packed; |
2213 |
+ |
2214 |
++#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \ |
2215 |
++ offsetof(struct bdb_lfp_backlight_data, brightness_level) |
2216 |
++#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \ |
2217 |
++ offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits) |
2218 |
++ |
2219 |
+ struct bdb_lfp_backlight_data { |
2220 |
+ u8 entry_size; |
2221 |
+ struct lfp_backlight_data_entry data[16]; |
2222 |
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |
2223 |
+index e382b7f2353b8..5ab136ffdeb2d 100644 |
2224 |
+--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |
2225 |
++++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |
2226 |
+@@ -118,7 +118,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww, |
2227 |
+ intel_wakeref_t wakeref = 0; |
2228 |
+ unsigned long count = 0; |
2229 |
+ unsigned long scanned = 0; |
2230 |
+- int err; |
2231 |
++ int err = 0; |
2232 |
+ |
2233 |
+ /* CHV + VTD workaround use stop_machine(); need to trylock vm->mutex */ |
2234 |
+ bool trylock_vm = !ww && intel_vm_no_concurrent_access_wa(i915); |
2235 |
+@@ -242,12 +242,15 @@ skip: |
2236 |
+ list_splice_tail(&still_in_list, phase->list); |
2237 |
+ spin_unlock_irqrestore(&i915->mm.obj_lock, flags); |
2238 |
+ if (err) |
2239 |
+- return err; |
2240 |
++ break; |
2241 |
+ } |
2242 |
+ |
2243 |
+ if (shrink & I915_SHRINK_BOUND) |
2244 |
+ intel_runtime_pm_put(&i915->runtime_pm, wakeref); |
2245 |
+ |
2246 |
++ if (err) |
2247 |
++ return err; |
2248 |
++ |
2249 |
+ if (nr_scanned) |
2250 |
+ *nr_scanned += scanned; |
2251 |
+ return count; |
2252 |
+diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h |
2253 |
+index 476bb3b9ad11a..5aa5ddefd22d2 100644 |
2254 |
+--- a/drivers/gpu/drm/i915/i915_reg.h |
2255 |
++++ b/drivers/gpu/drm/i915/i915_reg.h |
2256 |
+@@ -8113,6 +8113,7 @@ enum { |
2257 |
+ # define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2) |
2258 |
+ |
2259 |
+ #define CHICKEN_PAR1_1 _MMIO(0x42080) |
2260 |
++#define IGNORE_KVMR_PIPE_A REG_BIT(23) |
2261 |
+ #define KBL_ARB_FILL_SPARE_22 REG_BIT(22) |
2262 |
+ #define DIS_RAM_BYPASS_PSR2_MAN_TRACK (1 << 16) |
2263 |
+ #define SKL_DE_COMPRESSED_HASH_MODE (1 << 15) |
2264 |
+@@ -8150,6 +8151,11 @@ enum { |
2265 |
+ #define HSW_SPR_STRETCH_MAX_X1 REG_FIELD_PREP(HSW_SPR_STRETCH_MAX_MASK, 3) |
2266 |
+ #define HSW_FBCQ_DIS (1 << 22) |
2267 |
+ #define BDW_DPRS_MASK_VBLANK_SRD (1 << 0) |
2268 |
++#define SKL_PLANE1_STRETCH_MAX_MASK REG_GENMASK(1, 0) |
2269 |
++#define SKL_PLANE1_STRETCH_MAX_X8 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 0) |
2270 |
++#define SKL_PLANE1_STRETCH_MAX_X4 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 1) |
2271 |
++#define SKL_PLANE1_STRETCH_MAX_X2 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 2) |
2272 |
++#define SKL_PLANE1_STRETCH_MAX_X1 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 3) |
2273 |
+ #define CHICKEN_PIPESL_1(pipe) _MMIO_PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B) |
2274 |
+ |
2275 |
+ #define _CHICKEN_TRANS_A 0x420c0 |
2276 |
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c |
2277 |
+index 45fefa0ed1607..28959e67c00ee 100644 |
2278 |
+--- a/drivers/gpu/drm/i915/intel_pm.c |
2279 |
++++ b/drivers/gpu/drm/i915/intel_pm.c |
2280 |
+@@ -76,6 +76,8 @@ struct intel_wm_config { |
2281 |
+ |
2282 |
+ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) |
2283 |
+ { |
2284 |
++ enum pipe pipe; |
2285 |
++ |
2286 |
+ if (HAS_LLC(dev_priv)) { |
2287 |
+ /* |
2288 |
+ * WaCompressedResourceDisplayNewHashMode:skl,kbl |
2289 |
+@@ -89,6 +91,16 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) |
2290 |
+ SKL_DE_COMPRESSED_HASH_MODE); |
2291 |
+ } |
2292 |
+ |
2293 |
++ for_each_pipe(dev_priv, pipe) { |
2294 |
++ /* |
2295 |
++ * "Plane N strech max must be programmed to 11b (x1) |
2296 |
++ * when Async flips are enabled on that plane." |
2297 |
++ */ |
2298 |
++ if (!IS_GEMINILAKE(dev_priv) && intel_vtd_active()) |
2299 |
++ intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe), |
2300 |
++ SKL_PLANE1_STRETCH_MAX_MASK, SKL_PLANE1_STRETCH_MAX_X1); |
2301 |
++ } |
2302 |
++ |
2303 |
+ /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */ |
2304 |
+ intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1, |
2305 |
+ intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP); |
2306 |
+diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc.c b/drivers/gpu/drm/nouveau/dispnv50/crc.c |
2307 |
+index b8c31b697797e..66f32d965c723 100644 |
2308 |
+--- a/drivers/gpu/drm/nouveau/dispnv50/crc.c |
2309 |
++++ b/drivers/gpu/drm/nouveau/dispnv50/crc.c |
2310 |
+@@ -704,6 +704,7 @@ static const struct file_operations nv50_crc_flip_threshold_fops = { |
2311 |
+ .open = nv50_crc_debugfs_flip_threshold_open, |
2312 |
+ .read = seq_read, |
2313 |
+ .write = nv50_crc_debugfs_flip_threshold_set, |
2314 |
++ .release = single_release, |
2315 |
+ }; |
2316 |
+ |
2317 |
+ int nv50_head_crc_late_register(struct nv50_head *head) |
2318 |
+diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c |
2319 |
+index d66f97280282a..72099d1e48169 100644 |
2320 |
+--- a/drivers/gpu/drm/nouveau/dispnv50/head.c |
2321 |
++++ b/drivers/gpu/drm/nouveau/dispnv50/head.c |
2322 |
+@@ -52,6 +52,7 @@ nv50_head_flush_clr(struct nv50_head *head, |
2323 |
+ void |
2324 |
+ nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh) |
2325 |
+ { |
2326 |
++ if (asyh->set.curs ) head->func->curs_set(head, asyh); |
2327 |
+ if (asyh->set.olut ) { |
2328 |
+ asyh->olut.offset = nv50_lut_load(&head->olut, |
2329 |
+ asyh->olut.buffer, |
2330 |
+@@ -67,7 +68,6 @@ nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) |
2331 |
+ if (asyh->set.view ) head->func->view (head, asyh); |
2332 |
+ if (asyh->set.mode ) head->func->mode (head, asyh); |
2333 |
+ if (asyh->set.core ) head->func->core_set(head, asyh); |
2334 |
+- if (asyh->set.curs ) head->func->curs_set(head, asyh); |
2335 |
+ if (asyh->set.base ) head->func->base (head, asyh); |
2336 |
+ if (asyh->set.ovly ) head->func->ovly (head, asyh); |
2337 |
+ if (asyh->set.dither ) head->func->dither (head, asyh); |
2338 |
+diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h |
2339 |
+index c68cc957248e2..a582c0cb0cb0d 100644 |
2340 |
+--- a/drivers/gpu/drm/nouveau/include/nvif/class.h |
2341 |
++++ b/drivers/gpu/drm/nouveau/include/nvif/class.h |
2342 |
+@@ -71,6 +71,7 @@ |
2343 |
+ #define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c06f |
2344 |
+ #define VOLTA_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c36f |
2345 |
+ #define TURING_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c46f |
2346 |
++#define AMPERE_CHANNEL_GPFIFO_B /* clc36f.h */ 0x0000c76f |
2347 |
+ |
2348 |
+ #define NV50_DISP /* cl5070.h */ 0x00005070 |
2349 |
+ #define G82_DISP /* cl5070.h */ 0x00008270 |
2350 |
+@@ -200,6 +201,7 @@ |
2351 |
+ #define PASCAL_DMA_COPY_B 0x0000c1b5 |
2352 |
+ #define VOLTA_DMA_COPY_A 0x0000c3b5 |
2353 |
+ #define TURING_DMA_COPY_A 0x0000c5b5 |
2354 |
++#define AMPERE_DMA_COPY_B 0x0000c7b5 |
2355 |
+ |
2356 |
+ #define FERMI_DECOMPRESS 0x000090b8 |
2357 |
+ |
2358 |
+diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h |
2359 |
+index 54fab7cc36c1b..64ee82c7c1be5 100644 |
2360 |
+--- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h |
2361 |
++++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h |
2362 |
+@@ -77,4 +77,5 @@ int gp100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct |
2363 |
+ int gp10b_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); |
2364 |
+ int gv100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); |
2365 |
+ int tu102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); |
2366 |
++int ga102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); |
2367 |
+ #endif |
2368 |
+diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c |
2369 |
+index 6d07e653f82d5..c58bcdba2c7aa 100644 |
2370 |
+--- a/drivers/gpu/drm/nouveau/nouveau_bo.c |
2371 |
++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c |
2372 |
+@@ -844,6 +844,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) |
2373 |
+ struct ttm_resource *, struct ttm_resource *); |
2374 |
+ int (*init)(struct nouveau_channel *, u32 handle); |
2375 |
+ } _methods[] = { |
2376 |
++ { "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init }, |
2377 |
+ { "COPY", 4, 0xc5b5, nve0_bo_move_copy, nve0_bo_move_init }, |
2378 |
+ { "GRCE", 0, 0xc5b5, nve0_bo_move_copy, nvc0_bo_move_init }, |
2379 |
+ { "COPY", 4, 0xc3b5, nve0_bo_move_copy, nve0_bo_move_init }, |
2380 |
+diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c |
2381 |
+index 80099ef757022..ea7769135b0dc 100644 |
2382 |
+--- a/drivers/gpu/drm/nouveau/nouveau_chan.c |
2383 |
++++ b/drivers/gpu/drm/nouveau/nouveau_chan.c |
2384 |
+@@ -250,7 +250,8 @@ static int |
2385 |
+ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, |
2386 |
+ u64 runlist, bool priv, struct nouveau_channel **pchan) |
2387 |
+ { |
2388 |
+- static const u16 oclasses[] = { TURING_CHANNEL_GPFIFO_A, |
2389 |
++ static const u16 oclasses[] = { AMPERE_CHANNEL_GPFIFO_B, |
2390 |
++ TURING_CHANNEL_GPFIFO_A, |
2391 |
+ VOLTA_CHANNEL_GPFIFO_A, |
2392 |
+ PASCAL_CHANNEL_GPFIFO_A, |
2393 |
+ MAXWELL_CHANNEL_GPFIFO_A, |
2394 |
+@@ -386,7 +387,8 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) |
2395 |
+ |
2396 |
+ nvif_object_map(&chan->user, NULL, 0); |
2397 |
+ |
2398 |
+- if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO) { |
2399 |
++ if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO && |
2400 |
++ chan->user.oclass < AMPERE_CHANNEL_GPFIFO_B) { |
2401 |
+ ret = nvif_notify_ctor(&chan->user, "abi16ChanKilled", |
2402 |
+ nouveau_channel_killed, |
2403 |
+ true, NV906F_V0_NTFY_KILLED, |
2404 |
+diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c |
2405 |
+index c2bc05eb2e54a..1cbe01048b930 100644 |
2406 |
+--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c |
2407 |
++++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c |
2408 |
+@@ -207,6 +207,7 @@ static const struct file_operations nouveau_pstate_fops = { |
2409 |
+ .open = nouveau_debugfs_pstate_open, |
2410 |
+ .read = seq_read, |
2411 |
+ .write = nouveau_debugfs_pstate_set, |
2412 |
++ .release = single_release, |
2413 |
+ }; |
2414 |
+ |
2415 |
+ static struct drm_info_list nouveau_debugfs_list[] = { |
2416 |
+diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c |
2417 |
+index ba4cd5f837259..9b0084e4bbcfb 100644 |
2418 |
+--- a/drivers/gpu/drm/nouveau/nouveau_drm.c |
2419 |
++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c |
2420 |
+@@ -345,6 +345,9 @@ nouveau_accel_gr_init(struct nouveau_drm *drm) |
2421 |
+ u32 arg0, arg1; |
2422 |
+ int ret; |
2423 |
+ |
2424 |
++ if (device->info.family >= NV_DEVICE_INFO_V0_AMPERE) |
2425 |
++ return; |
2426 |
++ |
2427 |
+ /* Allocate channel that has access to the graphics engine. */ |
2428 |
+ if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) { |
2429 |
+ arg0 = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR); |
2430 |
+@@ -469,6 +472,7 @@ nouveau_accel_init(struct nouveau_drm *drm) |
2431 |
+ case PASCAL_CHANNEL_GPFIFO_A: |
2432 |
+ case VOLTA_CHANNEL_GPFIFO_A: |
2433 |
+ case TURING_CHANNEL_GPFIFO_A: |
2434 |
++ case AMPERE_CHANNEL_GPFIFO_B: |
2435 |
+ ret = nvc0_fence_create(drm); |
2436 |
+ break; |
2437 |
+ default: |
2438 |
+diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c |
2439 |
+index 5b27845075a1c..8c2ecc2827232 100644 |
2440 |
+--- a/drivers/gpu/drm/nouveau/nouveau_gem.c |
2441 |
++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c |
2442 |
+@@ -247,10 +247,8 @@ nouveau_gem_new(struct nouveau_cli *cli, u64 size, int align, uint32_t domain, |
2443 |
+ } |
2444 |
+ |
2445 |
+ ret = nouveau_bo_init(nvbo, size, align, domain, NULL, NULL); |
2446 |
+- if (ret) { |
2447 |
+- nouveau_bo_ref(NULL, &nvbo); |
2448 |
++ if (ret) |
2449 |
+ return ret; |
2450 |
+- } |
2451 |
+ |
2452 |
+ /* we restrict allowed domains on nv50+ to only the types |
2453 |
+ * that were requested at creation time. not possibly on |
2454 |
+diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c |
2455 |
+index 7c9c928c31966..c3526a8622e3e 100644 |
2456 |
+--- a/drivers/gpu/drm/nouveau/nv84_fence.c |
2457 |
++++ b/drivers/gpu/drm/nouveau/nv84_fence.c |
2458 |
+@@ -204,7 +204,7 @@ nv84_fence_create(struct nouveau_drm *drm) |
2459 |
+ priv->base.context_new = nv84_fence_context_new; |
2460 |
+ priv->base.context_del = nv84_fence_context_del; |
2461 |
+ |
2462 |
+- priv->base.uevent = true; |
2463 |
++ priv->base.uevent = drm->client.device.info.family < NV_DEVICE_INFO_V0_AMPERE; |
2464 |
+ |
2465 |
+ mutex_init(&priv->mutex); |
2466 |
+ |
2467 |
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c |
2468 |
+index 93ddf63d11140..ca75c5f6ecaf8 100644 |
2469 |
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c |
2470 |
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c |
2471 |
+@@ -2602,6 +2602,7 @@ nv172_chipset = { |
2472 |
+ .top = { 0x00000001, ga100_top_new }, |
2473 |
+ .disp = { 0x00000001, ga102_disp_new }, |
2474 |
+ .dma = { 0x00000001, gv100_dma_new }, |
2475 |
++ .fifo = { 0x00000001, ga102_fifo_new }, |
2476 |
+ }; |
2477 |
+ |
2478 |
+ static const struct nvkm_device_chip |
2479 |
+@@ -2622,6 +2623,7 @@ nv174_chipset = { |
2480 |
+ .top = { 0x00000001, ga100_top_new }, |
2481 |
+ .disp = { 0x00000001, ga102_disp_new }, |
2482 |
+ .dma = { 0x00000001, gv100_dma_new }, |
2483 |
++ .fifo = { 0x00000001, ga102_fifo_new }, |
2484 |
+ }; |
2485 |
+ |
2486 |
+ static const struct nvkm_device_chip |
2487 |
+@@ -2642,6 +2644,7 @@ nv177_chipset = { |
2488 |
+ .top = { 0x00000001, ga100_top_new }, |
2489 |
+ .disp = { 0x00000001, ga102_disp_new }, |
2490 |
+ .dma = { 0x00000001, gv100_dma_new }, |
2491 |
++ .fifo = { 0x00000001, ga102_fifo_new }, |
2492 |
+ }; |
2493 |
+ |
2494 |
+ static int |
2495 |
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild |
2496 |
+index 3209eb7af65fb..5e831d347a957 100644 |
2497 |
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild |
2498 |
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild |
2499 |
+@@ -18,6 +18,7 @@ nvkm-y += nvkm/engine/fifo/gp100.o |
2500 |
+ nvkm-y += nvkm/engine/fifo/gp10b.o |
2501 |
+ nvkm-y += nvkm/engine/fifo/gv100.o |
2502 |
+ nvkm-y += nvkm/engine/fifo/tu102.o |
2503 |
++nvkm-y += nvkm/engine/fifo/ga102.o |
2504 |
+ |
2505 |
+ nvkm-y += nvkm/engine/fifo/chan.o |
2506 |
+ nvkm-y += nvkm/engine/fifo/channv50.o |
2507 |
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c |
2508 |
+new file mode 100644 |
2509 |
+index 0000000000000..c630dbd2911ae |
2510 |
+--- /dev/null |
2511 |
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c |
2512 |
+@@ -0,0 +1,311 @@ |
2513 |
++/* |
2514 |
++ * Copyright 2021 Red Hat Inc. |
2515 |
++ * |
2516 |
++ * Permission is hereby granted, free of charge, to any person obtaining a |
2517 |
++ * copy of this software and associated documentation files (the "Software"), |
2518 |
++ * to deal in the Software without restriction, including without limitation |
2519 |
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
2520 |
++ * and/or sell copies of the Software, and to permit persons to whom the |
2521 |
++ * Software is furnished to do so, subject to the following conditions: |
2522 |
++ * |
2523 |
++ * The above copyright notice and this permission notice shall be included in |
2524 |
++ * all copies or substantial portions of the Software. |
2525 |
++ * |
2526 |
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
2527 |
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
2528 |
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
2529 |
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
2530 |
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
2531 |
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
2532 |
++ * OTHER DEALINGS IN THE SOFTWARE. |
2533 |
++ */ |
2534 |
++#define ga102_fifo(p) container_of((p), struct ga102_fifo, base.engine) |
2535 |
++#define ga102_chan(p) container_of((p), struct ga102_chan, object) |
2536 |
++#include <engine/fifo.h> |
2537 |
++#include "user.h" |
2538 |
++ |
2539 |
++#include <core/memory.h> |
2540 |
++#include <subdev/mmu.h> |
2541 |
++#include <subdev/timer.h> |
2542 |
++#include <subdev/top.h> |
2543 |
++ |
2544 |
++#include <nvif/cl0080.h> |
2545 |
++#include <nvif/clc36f.h> |
2546 |
++#include <nvif/class.h> |
2547 |
++ |
2548 |
++struct ga102_fifo { |
2549 |
++ struct nvkm_fifo base; |
2550 |
++}; |
2551 |
++ |
2552 |
++struct ga102_chan { |
2553 |
++ struct nvkm_object object; |
2554 |
++ |
2555 |
++ struct { |
2556 |
++ u32 runl; |
2557 |
++ u32 chan; |
2558 |
++ } ctrl; |
2559 |
++ |
2560 |
++ struct nvkm_memory *mthd; |
2561 |
++ struct nvkm_memory *inst; |
2562 |
++ struct nvkm_memory *user; |
2563 |
++ struct nvkm_memory *runl; |
2564 |
++ |
2565 |
++ struct nvkm_vmm *vmm; |
2566 |
++}; |
2567 |
++ |
2568 |
++static int |
2569 |
++ga102_chan_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *oclass) |
2570 |
++{ |
2571 |
++ if (index == 0) { |
2572 |
++ oclass->ctor = nvkm_object_new; |
2573 |
++ oclass->base = (struct nvkm_sclass) { -1, -1, AMPERE_DMA_COPY_B }; |
2574 |
++ return 0; |
2575 |
++ } |
2576 |
++ |
2577 |
++ return -EINVAL; |
2578 |
++} |
2579 |
++ |
2580 |
++static int |
2581 |
++ga102_chan_map(struct nvkm_object *object, void *argv, u32 argc, |
2582 |
++ enum nvkm_object_map *type, u64 *addr, u64 *size) |
2583 |
++{ |
2584 |
++ struct ga102_chan *chan = ga102_chan(object); |
2585 |
++ struct nvkm_device *device = chan->object.engine->subdev.device; |
2586 |
++ u64 bar2 = nvkm_memory_bar2(chan->user); |
2587 |
++ |
2588 |
++ if (bar2 == ~0ULL) |
2589 |
++ return -EFAULT; |
2590 |
++ |
2591 |
++ *type = NVKM_OBJECT_MAP_IO; |
2592 |
++ *addr = device->func->resource_addr(device, 3) + bar2; |
2593 |
++ *size = 0x1000; |
2594 |
++ return 0; |
2595 |
++} |
2596 |
++ |
2597 |
++static int |
2598 |
++ga102_chan_fini(struct nvkm_object *object, bool suspend) |
2599 |
++{ |
2600 |
++ struct ga102_chan *chan = ga102_chan(object); |
2601 |
++ struct nvkm_device *device = chan->object.engine->subdev.device; |
2602 |
++ |
2603 |
++ nvkm_wr32(device, chan->ctrl.chan, 0x00000003); |
2604 |
++ |
2605 |
++ nvkm_wr32(device, chan->ctrl.runl + 0x098, 0x01000000); |
2606 |
++ nvkm_msec(device, 2000, |
2607 |
++ if (!(nvkm_rd32(device, chan->ctrl.runl + 0x098) & 0x00100000)) |
2608 |
++ break; |
2609 |
++ ); |
2610 |
++ |
2611 |
++ nvkm_wr32(device, chan->ctrl.runl + 0x088, 0); |
2612 |
++ |
2613 |
++ nvkm_wr32(device, chan->ctrl.chan, 0xffffffff); |
2614 |
++ return 0; |
2615 |
++} |
2616 |
++ |
2617 |
++static int |
2618 |
++ga102_chan_init(struct nvkm_object *object) |
2619 |
++{ |
2620 |
++ struct ga102_chan *chan = ga102_chan(object); |
2621 |
++ struct nvkm_device *device = chan->object.engine->subdev.device; |
2622 |
++ |
2623 |
++ nvkm_mask(device, chan->ctrl.runl + 0x300, 0x80000000, 0x80000000); |
2624 |
++ |
2625 |
++ nvkm_wr32(device, chan->ctrl.runl + 0x080, lower_32_bits(nvkm_memory_addr(chan->runl))); |
2626 |
++ nvkm_wr32(device, chan->ctrl.runl + 0x084, upper_32_bits(nvkm_memory_addr(chan->runl))); |
2627 |
++ nvkm_wr32(device, chan->ctrl.runl + 0x088, 2); |
2628 |
++ |
2629 |
++ nvkm_wr32(device, chan->ctrl.chan, 0x00000002); |
2630 |
++ nvkm_wr32(device, chan->ctrl.runl + 0x0090, 0); |
2631 |
++ return 0; |
2632 |
++} |
2633 |
++ |
2634 |
++static void * |
2635 |
++ga102_chan_dtor(struct nvkm_object *object) |
2636 |
++{ |
2637 |
++ struct ga102_chan *chan = ga102_chan(object); |
2638 |
++ |
2639 |
++ if (chan->vmm) { |
2640 |
++ nvkm_vmm_part(chan->vmm, chan->inst); |
2641 |
++ nvkm_vmm_unref(&chan->vmm); |
2642 |
++ } |
2643 |
++ |
2644 |
++ nvkm_memory_unref(&chan->runl); |
2645 |
++ nvkm_memory_unref(&chan->user); |
2646 |
++ nvkm_memory_unref(&chan->inst); |
2647 |
++ nvkm_memory_unref(&chan->mthd); |
2648 |
++ return chan; |
2649 |
++} |
2650 |
++ |
2651 |
++static const struct nvkm_object_func |
2652 |
++ga102_chan = { |
2653 |
++ .dtor = ga102_chan_dtor, |
2654 |
++ .init = ga102_chan_init, |
2655 |
++ .fini = ga102_chan_fini, |
2656 |
++ .map = ga102_chan_map, |
2657 |
++ .sclass = ga102_chan_sclass, |
2658 |
++}; |
2659 |
++ |
2660 |
++static int |
2661 |
++ga102_chan_new(struct nvkm_device *device, |
2662 |
++ const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject) |
2663 |
++{ |
2664 |
++ struct volta_channel_gpfifo_a_v0 *args = argv; |
2665 |
++ struct nvkm_top_device *tdev; |
2666 |
++ struct nvkm_vmm *vmm; |
2667 |
++ struct ga102_chan *chan; |
2668 |
++ int ret; |
2669 |
++ |
2670 |
++ if (argc != sizeof(*args)) |
2671 |
++ return -ENOSYS; |
2672 |
++ |
2673 |
++ vmm = nvkm_uvmm_search(oclass->client, args->vmm); |
2674 |
++ if (IS_ERR(vmm)) |
2675 |
++ return PTR_ERR(vmm); |
2676 |
++ |
2677 |
++ if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) |
2678 |
++ return -ENOMEM; |
2679 |
++ |
2680 |
++ nvkm_object_ctor(&ga102_chan, oclass, &chan->object); |
2681 |
++ *pobject = &chan->object; |
2682 |
++ |
2683 |
++ list_for_each_entry(tdev, &device->top->device, head) { |
2684 |
++ if (tdev->type == NVKM_ENGINE_CE) { |
2685 |
++ chan->ctrl.runl = tdev->runlist; |
2686 |
++ break; |
2687 |
++ } |
2688 |
++ } |
2689 |
++ |
2690 |
++ if (!chan->ctrl.runl) |
2691 |
++ return -ENODEV; |
2692 |
++ |
2693 |
++ chan->ctrl.chan = nvkm_rd32(device, chan->ctrl.runl + 0x004) & 0xfffffff0; |
2694 |
++ |
2695 |
++ args->chid = 0; |
2696 |
++ args->inst = 0; |
2697 |
++ args->token = nvkm_rd32(device, chan->ctrl.runl + 0x008) & 0xffff0000; |
2698 |
++ |
2699 |
++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->mthd); |
2700 |
++ if (ret) |
2701 |
++ return ret; |
2702 |
++ |
2703 |
++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->inst); |
2704 |
++ if (ret) |
2705 |
++ return ret; |
2706 |
++ |
2707 |
++ nvkm_kmap(chan->inst); |
2708 |
++ nvkm_wo32(chan->inst, 0x010, 0x0000face); |
2709 |
++ nvkm_wo32(chan->inst, 0x030, 0x7ffff902); |
2710 |
++ nvkm_wo32(chan->inst, 0x048, lower_32_bits(args->ioffset)); |
2711 |
++ nvkm_wo32(chan->inst, 0x04c, upper_32_bits(args->ioffset) | |
2712 |
++ (order_base_2(args->ilength / 8) << 16)); |
2713 |
++ nvkm_wo32(chan->inst, 0x084, 0x20400000); |
2714 |
++ nvkm_wo32(chan->inst, 0x094, 0x30000001); |
2715 |
++ nvkm_wo32(chan->inst, 0x0ac, 0x00020000); |
2716 |
++ nvkm_wo32(chan->inst, 0x0e4, 0x00000000); |
2717 |
++ nvkm_wo32(chan->inst, 0x0e8, 0); |
2718 |
++ nvkm_wo32(chan->inst, 0x0f4, 0x00001000); |
2719 |
++ nvkm_wo32(chan->inst, 0x0f8, 0x10003080); |
2720 |
++ nvkm_mo32(chan->inst, 0x218, 0x00000000, 0x00000000); |
2721 |
++ nvkm_wo32(chan->inst, 0x220, lower_32_bits(nvkm_memory_bar2(chan->mthd))); |
2722 |
++ nvkm_wo32(chan->inst, 0x224, upper_32_bits(nvkm_memory_bar2(chan->mthd))); |
2723 |
++ nvkm_done(chan->inst); |
2724 |
++ |
2725 |
++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->user); |
2726 |
++ if (ret) |
2727 |
++ return ret; |
2728 |
++ |
2729 |
++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->runl); |
2730 |
++ if (ret) |
2731 |
++ return ret; |
2732 |
++ |
2733 |
++ nvkm_kmap(chan->runl); |
2734 |
++ nvkm_wo32(chan->runl, 0x00, 0x80030001); |
2735 |
++ nvkm_wo32(chan->runl, 0x04, 1); |
2736 |
++ nvkm_wo32(chan->runl, 0x08, 0); |
2737 |
++ nvkm_wo32(chan->runl, 0x0c, 0x00000000); |
2738 |
++ nvkm_wo32(chan->runl, 0x10, lower_32_bits(nvkm_memory_addr(chan->user))); |
2739 |
++ nvkm_wo32(chan->runl, 0x14, upper_32_bits(nvkm_memory_addr(chan->user))); |
2740 |
++ nvkm_wo32(chan->runl, 0x18, lower_32_bits(nvkm_memory_addr(chan->inst))); |
2741 |
++ nvkm_wo32(chan->runl, 0x1c, upper_32_bits(nvkm_memory_addr(chan->inst))); |
2742 |
++ nvkm_done(chan->runl); |
2743 |
++ |
2744 |
++ ret = nvkm_vmm_join(vmm, chan->inst); |
2745 |
++ if (ret) |
2746 |
++ return ret; |
2747 |
++ |
2748 |
++ chan->vmm = nvkm_vmm_ref(vmm); |
2749 |
++ return 0; |
2750 |
++} |
2751 |
++ |
2752 |
++static const struct nvkm_device_oclass |
2753 |
++ga102_chan_oclass = { |
2754 |
++ .ctor = ga102_chan_new, |
2755 |
++}; |
2756 |
++ |
2757 |
++static int |
2758 |
++ga102_user_new(struct nvkm_device *device, |
2759 |
++ const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject) |
2760 |
++{ |
2761 |
++ return tu102_fifo_user_new(oclass, argv, argc, pobject); |
2762 |
++} |
2763 |
++ |
2764 |
++static const struct nvkm_device_oclass |
2765 |
++ga102_user_oclass = { |
2766 |
++ .ctor = ga102_user_new, |
2767 |
++}; |
2768 |
++ |
2769 |
++static int |
2770 |
++ga102_fifo_sclass(struct nvkm_oclass *oclass, int index, const struct nvkm_device_oclass **class) |
2771 |
++{ |
2772 |
++ if (index == 0) { |
2773 |
++ oclass->base = (struct nvkm_sclass) { -1, -1, VOLTA_USERMODE_A }; |
2774 |
++ *class = &ga102_user_oclass; |
2775 |
++ return 0; |
2776 |
++ } else |
2777 |
++ if (index == 1) { |
2778 |
++ oclass->base = (struct nvkm_sclass) { 0, 0, AMPERE_CHANNEL_GPFIFO_B }; |
2779 |
++ *class = &ga102_chan_oclass; |
2780 |
++ return 0; |
2781 |
++ } |
2782 |
++ |
2783 |
++ return 2; |
2784 |
++} |
2785 |
++ |
2786 |
++static int |
2787 |
++ga102_fifo_info(struct nvkm_engine *engine, u64 mthd, u64 *data) |
2788 |
++{ |
2789 |
++ switch (mthd) { |
2790 |
++ case NV_DEVICE_HOST_CHANNELS: *data = 1; return 0; |
2791 |
++ default: |
2792 |
++ break; |
2793 |
++ } |
2794 |
++ |
2795 |
++ return -ENOSYS; |
2796 |
++} |
2797 |
++ |
2798 |
++static void * |
2799 |
++ga102_fifo_dtor(struct nvkm_engine *engine) |
2800 |
++{ |
2801 |
++ return ga102_fifo(engine); |
2802 |
++} |
2803 |
++ |
2804 |
++static const struct nvkm_engine_func |
2805 |
++ga102_fifo = { |
2806 |
++ .dtor = ga102_fifo_dtor, |
2807 |
++ .info = ga102_fifo_info, |
2808 |
++ .base.sclass = ga102_fifo_sclass, |
2809 |
++}; |
2810 |
++ |
2811 |
++int |
2812 |
++ga102_fifo_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, |
2813 |
++ struct nvkm_fifo **pfifo) |
2814 |
++{ |
2815 |
++ struct ga102_fifo *fifo; |
2816 |
++ |
2817 |
++ if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL))) |
2818 |
++ return -ENOMEM; |
2819 |
++ |
2820 |
++ nvkm_engine_ctor(&ga102_fifo, device, type, inst, true, &fifo->base.engine); |
2821 |
++ *pfifo = &fifo->base; |
2822 |
++ return 0; |
2823 |
++} |
2824 |
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c |
2825 |
+index 31933f3e5a076..c982d834c8d98 100644 |
2826 |
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c |
2827 |
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c |
2828 |
+@@ -54,7 +54,7 @@ ga100_top_oneinit(struct nvkm_top *top) |
2829 |
+ info->reset = (data & 0x0000001f); |
2830 |
+ break; |
2831 |
+ case 2: |
2832 |
+- info->runlist = (data & 0x0000fc00) >> 10; |
2833 |
++ info->runlist = (data & 0x00fffc00); |
2834 |
+ info->engine = (data & 0x00000003); |
2835 |
+ break; |
2836 |
+ default: |
2837 |
+@@ -85,9 +85,10 @@ ga100_top_oneinit(struct nvkm_top *top) |
2838 |
+ } |
2839 |
+ |
2840 |
+ nvkm_debug(subdev, "%02x.%d (%8s): addr %06x fault %2d " |
2841 |
+- "runlist %2d engine %2d reset %2d\n", type, inst, |
2842 |
++ "runlist %6x engine %2d reset %2d\n", type, inst, |
2843 |
+ info->type == NVKM_SUBDEV_NR ? "????????" : nvkm_subdev_type[info->type], |
2844 |
+- info->addr, info->fault, info->runlist, info->engine, info->reset); |
2845 |
++ info->addr, info->fault, info->runlist < 0 ? 0 : info->runlist, |
2846 |
++ info->engine, info->reset); |
2847 |
+ info = NULL; |
2848 |
+ } |
2849 |
+ |
2850 |
+diff --git a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c |
2851 |
+index 2d8794d495d08..3d8a9ab47cae2 100644 |
2852 |
+--- a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c |
2853 |
++++ b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c |
2854 |
+@@ -146,8 +146,8 @@ static const struct reg_sequence y030xx067a_init_sequence[] = { |
2855 |
+ { 0x09, REG09_SUB_BRIGHT_R(0x20) }, |
2856 |
+ { 0x0a, REG0A_SUB_BRIGHT_B(0x20) }, |
2857 |
+ { 0x0b, REG0B_HD_FREERUN | REG0B_VD_FREERUN }, |
2858 |
+- { 0x0c, REG0C_CONTRAST_R(0x10) }, |
2859 |
+- { 0x0d, REG0D_CONTRAST_G(0x10) }, |
2860 |
++ { 0x0c, REG0C_CONTRAST_R(0x00) }, |
2861 |
++ { 0x0d, REG0D_CONTRAST_G(0x00) }, |
2862 |
+ { 0x0e, REG0E_CONTRAST_B(0x10) }, |
2863 |
+ { 0x0f, 0 }, |
2864 |
+ { 0x10, REG10_BRIGHT(0x7f) }, |
2865 |
+diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c |
2866 |
+index f75fb157f2ff7..016b877051dab 100644 |
2867 |
+--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c |
2868 |
++++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c |
2869 |
+@@ -216,11 +216,13 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, |
2870 |
+ goto err_disable_clk_tmds; |
2871 |
+ } |
2872 |
+ |
2873 |
++ ret = sun8i_hdmi_phy_init(hdmi->phy); |
2874 |
++ if (ret) |
2875 |
++ goto err_disable_clk_tmds; |
2876 |
++ |
2877 |
+ drm_encoder_helper_add(encoder, &sun8i_dw_hdmi_encoder_helper_funcs); |
2878 |
+ drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); |
2879 |
+ |
2880 |
+- sun8i_hdmi_phy_init(hdmi->phy); |
2881 |
+- |
2882 |
+ plat_data->mode_valid = hdmi->quirks->mode_valid; |
2883 |
+ plat_data->use_drm_infoframe = hdmi->quirks->use_drm_infoframe; |
2884 |
+ sun8i_hdmi_phy_set_ops(hdmi->phy, plat_data); |
2885 |
+@@ -262,6 +264,7 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master, |
2886 |
+ struct sun8i_dw_hdmi *hdmi = dev_get_drvdata(dev); |
2887 |
+ |
2888 |
+ dw_hdmi_unbind(hdmi->hdmi); |
2889 |
++ sun8i_hdmi_phy_deinit(hdmi->phy); |
2890 |
+ clk_disable_unprepare(hdmi->clk_tmds); |
2891 |
+ reset_control_assert(hdmi->rst_ctrl); |
2892 |
+ gpiod_set_value(hdmi->ddc_en, 0); |
2893 |
+diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h |
2894 |
+index 74f6ed0e25709..bffe1b9cd3dcb 100644 |
2895 |
+--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h |
2896 |
++++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h |
2897 |
+@@ -169,6 +169,7 @@ struct sun8i_hdmi_phy { |
2898 |
+ struct clk *clk_phy; |
2899 |
+ struct clk *clk_pll0; |
2900 |
+ struct clk *clk_pll1; |
2901 |
++ struct device *dev; |
2902 |
+ unsigned int rcal; |
2903 |
+ struct regmap *regs; |
2904 |
+ struct reset_control *rst_phy; |
2905 |
+@@ -205,7 +206,8 @@ encoder_to_sun8i_dw_hdmi(struct drm_encoder *encoder) |
2906 |
+ |
2907 |
+ int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node); |
2908 |
+ |
2909 |
+-void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy); |
2910 |
++int sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy); |
2911 |
++void sun8i_hdmi_phy_deinit(struct sun8i_hdmi_phy *phy); |
2912 |
+ void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy, |
2913 |
+ struct dw_hdmi_plat_data *plat_data); |
2914 |
+ |
2915 |
+diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c |
2916 |
+index c9239708d398c..b64d93da651d2 100644 |
2917 |
+--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c |
2918 |
++++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c |
2919 |
+@@ -506,9 +506,60 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy) |
2920 |
+ phy->rcal = (val & SUN8I_HDMI_PHY_ANA_STS_RCAL_MASK) >> 2; |
2921 |
+ } |
2922 |
+ |
2923 |
+-void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy) |
2924 |
++int sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy) |
2925 |
+ { |
2926 |
++ int ret; |
2927 |
++ |
2928 |
++ ret = reset_control_deassert(phy->rst_phy); |
2929 |
++ if (ret) { |
2930 |
++ dev_err(phy->dev, "Cannot deassert phy reset control: %d\n", ret); |
2931 |
++ return ret; |
2932 |
++ } |
2933 |
++ |
2934 |
++ ret = clk_prepare_enable(phy->clk_bus); |
2935 |
++ if (ret) { |
2936 |
++ dev_err(phy->dev, "Cannot enable bus clock: %d\n", ret); |
2937 |
++ goto err_assert_rst_phy; |
2938 |
++ } |
2939 |
++ |
2940 |
++ ret = clk_prepare_enable(phy->clk_mod); |
2941 |
++ if (ret) { |
2942 |
++ dev_err(phy->dev, "Cannot enable mod clock: %d\n", ret); |
2943 |
++ goto err_disable_clk_bus; |
2944 |
++ } |
2945 |
++ |
2946 |
++ if (phy->variant->has_phy_clk) { |
2947 |
++ ret = sun8i_phy_clk_create(phy, phy->dev, |
2948 |
++ phy->variant->has_second_pll); |
2949 |
++ if (ret) { |
2950 |
++ dev_err(phy->dev, "Couldn't create the PHY clock\n"); |
2951 |
++ goto err_disable_clk_mod; |
2952 |
++ } |
2953 |
++ |
2954 |
++ clk_prepare_enable(phy->clk_phy); |
2955 |
++ } |
2956 |
++ |
2957 |
+ phy->variant->phy_init(phy); |
2958 |
++ |
2959 |
++ return 0; |
2960 |
++ |
2961 |
++err_disable_clk_mod: |
2962 |
++ clk_disable_unprepare(phy->clk_mod); |
2963 |
++err_disable_clk_bus: |
2964 |
++ clk_disable_unprepare(phy->clk_bus); |
2965 |
++err_assert_rst_phy: |
2966 |
++ reset_control_assert(phy->rst_phy); |
2967 |
++ |
2968 |
++ return ret; |
2969 |
++} |
2970 |
++ |
2971 |
++void sun8i_hdmi_phy_deinit(struct sun8i_hdmi_phy *phy) |
2972 |
++{ |
2973 |
++ clk_disable_unprepare(phy->clk_mod); |
2974 |
++ clk_disable_unprepare(phy->clk_bus); |
2975 |
++ clk_disable_unprepare(phy->clk_phy); |
2976 |
++ |
2977 |
++ reset_control_assert(phy->rst_phy); |
2978 |
+ } |
2979 |
+ |
2980 |
+ void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy, |
2981 |
+@@ -638,6 +689,7 @@ static int sun8i_hdmi_phy_probe(struct platform_device *pdev) |
2982 |
+ return -ENOMEM; |
2983 |
+ |
2984 |
+ phy->variant = (struct sun8i_hdmi_phy_variant *)match->data; |
2985 |
++ phy->dev = dev; |
2986 |
+ |
2987 |
+ ret = of_address_to_resource(node, 0, &res); |
2988 |
+ if (ret) { |
2989 |
+@@ -696,47 +748,10 @@ static int sun8i_hdmi_phy_probe(struct platform_device *pdev) |
2990 |
+ goto err_put_clk_pll1; |
2991 |
+ } |
2992 |
+ |
2993 |
+- ret = reset_control_deassert(phy->rst_phy); |
2994 |
+- if (ret) { |
2995 |
+- dev_err(dev, "Cannot deassert phy reset control: %d\n", ret); |
2996 |
+- goto err_put_rst_phy; |
2997 |
+- } |
2998 |
+- |
2999 |
+- ret = clk_prepare_enable(phy->clk_bus); |
3000 |
+- if (ret) { |
3001 |
+- dev_err(dev, "Cannot enable bus clock: %d\n", ret); |
3002 |
+- goto err_deassert_rst_phy; |
3003 |
+- } |
3004 |
+- |
3005 |
+- ret = clk_prepare_enable(phy->clk_mod); |
3006 |
+- if (ret) { |
3007 |
+- dev_err(dev, "Cannot enable mod clock: %d\n", ret); |
3008 |
+- goto err_disable_clk_bus; |
3009 |
+- } |
3010 |
+- |
3011 |
+- if (phy->variant->has_phy_clk) { |
3012 |
+- ret = sun8i_phy_clk_create(phy, dev, |
3013 |
+- phy->variant->has_second_pll); |
3014 |
+- if (ret) { |
3015 |
+- dev_err(dev, "Couldn't create the PHY clock\n"); |
3016 |
+- goto err_disable_clk_mod; |
3017 |
+- } |
3018 |
+- |
3019 |
+- clk_prepare_enable(phy->clk_phy); |
3020 |
+- } |
3021 |
+- |
3022 |
+ platform_set_drvdata(pdev, phy); |
3023 |
+ |
3024 |
+ return 0; |
3025 |
+ |
3026 |
+-err_disable_clk_mod: |
3027 |
+- clk_disable_unprepare(phy->clk_mod); |
3028 |
+-err_disable_clk_bus: |
3029 |
+- clk_disable_unprepare(phy->clk_bus); |
3030 |
+-err_deassert_rst_phy: |
3031 |
+- reset_control_assert(phy->rst_phy); |
3032 |
+-err_put_rst_phy: |
3033 |
+- reset_control_put(phy->rst_phy); |
3034 |
+ err_put_clk_pll1: |
3035 |
+ clk_put(phy->clk_pll1); |
3036 |
+ err_put_clk_pll0: |
3037 |
+@@ -753,12 +768,6 @@ static int sun8i_hdmi_phy_remove(struct platform_device *pdev) |
3038 |
+ { |
3039 |
+ struct sun8i_hdmi_phy *phy = platform_get_drvdata(pdev); |
3040 |
+ |
3041 |
+- clk_disable_unprepare(phy->clk_mod); |
3042 |
+- clk_disable_unprepare(phy->clk_bus); |
3043 |
+- clk_disable_unprepare(phy->clk_phy); |
3044 |
+- |
3045 |
+- reset_control_assert(phy->rst_phy); |
3046 |
+- |
3047 |
+ reset_control_put(phy->rst_phy); |
3048 |
+ |
3049 |
+ clk_put(phy->clk_pll0); |
3050 |
+diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c |
3051 |
+index 4e0b7c2882ced..015e11c4663f3 100644 |
3052 |
+--- a/drivers/i2c/busses/i2c-mlxcpld.c |
3053 |
++++ b/drivers/i2c/busses/i2c-mlxcpld.c |
3054 |
+@@ -49,7 +49,7 @@ |
3055 |
+ #define MLXCPLD_LPCI2C_NACK_IND 2 |
3056 |
+ |
3057 |
+ #define MLXCPLD_I2C_FREQ_1000KHZ_SET 0x04 |
3058 |
+-#define MLXCPLD_I2C_FREQ_400KHZ_SET 0x0f |
3059 |
++#define MLXCPLD_I2C_FREQ_400KHZ_SET 0x0c |
3060 |
+ #define MLXCPLD_I2C_FREQ_100KHZ_SET 0x42 |
3061 |
+ |
3062 |
+ enum mlxcpld_i2c_frequency { |
3063 |
+@@ -495,7 +495,7 @@ mlxcpld_i2c_set_frequency(struct mlxcpld_i2c_priv *priv, |
3064 |
+ return err; |
3065 |
+ |
3066 |
+ /* Set frequency only if it is not 100KHz, which is default. */ |
3067 |
+- switch ((data->reg & data->mask) >> data->bit) { |
3068 |
++ switch ((regval & data->mask) >> data->bit) { |
3069 |
+ case MLXCPLD_I2C_FREQ_1000KHZ: |
3070 |
+ freq = MLXCPLD_I2C_FREQ_1000KHZ_SET; |
3071 |
+ break; |
3072 |
+diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c |
3073 |
+index 477480d1de6bd..7d4b3eb7077ad 100644 |
3074 |
+--- a/drivers/i2c/busses/i2c-mt65xx.c |
3075 |
++++ b/drivers/i2c/busses/i2c-mt65xx.c |
3076 |
+@@ -41,6 +41,8 @@ |
3077 |
+ #define I2C_HANDSHAKE_RST 0x0020 |
3078 |
+ #define I2C_FIFO_ADDR_CLR 0x0001 |
3079 |
+ #define I2C_DELAY_LEN 0x0002 |
3080 |
++#define I2C_ST_START_CON 0x8001 |
3081 |
++#define I2C_FS_START_CON 0x1800 |
3082 |
+ #define I2C_TIME_CLR_VALUE 0x0000 |
3083 |
+ #define I2C_TIME_DEFAULT_VALUE 0x0003 |
3084 |
+ #define I2C_WRRD_TRANAC_VALUE 0x0002 |
3085 |
+@@ -480,6 +482,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c) |
3086 |
+ { |
3087 |
+ u16 control_reg; |
3088 |
+ u16 intr_stat_reg; |
3089 |
++ u16 ext_conf_val; |
3090 |
+ |
3091 |
+ mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_START); |
3092 |
+ intr_stat_reg = mtk_i2c_readw(i2c, OFFSET_INTR_STAT); |
3093 |
+@@ -518,8 +521,13 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c) |
3094 |
+ if (i2c->dev_comp->ltiming_adjust) |
3095 |
+ mtk_i2c_writew(i2c, i2c->ltiming_reg, OFFSET_LTIMING); |
3096 |
+ |
3097 |
++ if (i2c->speed_hz <= I2C_MAX_STANDARD_MODE_FREQ) |
3098 |
++ ext_conf_val = I2C_ST_START_CON; |
3099 |
++ else |
3100 |
++ ext_conf_val = I2C_FS_START_CON; |
3101 |
++ |
3102 |
+ if (i2c->dev_comp->timing_adjust) { |
3103 |
+- mtk_i2c_writew(i2c, i2c->ac_timing.ext, OFFSET_EXT_CONF); |
3104 |
++ ext_conf_val = i2c->ac_timing.ext; |
3105 |
+ mtk_i2c_writew(i2c, i2c->ac_timing.inter_clk_div, |
3106 |
+ OFFSET_CLOCK_DIV); |
3107 |
+ mtk_i2c_writew(i2c, I2C_SCL_MIS_COMP_VALUE, |
3108 |
+@@ -544,6 +552,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c) |
3109 |
+ OFFSET_HS_STA_STO_AC_TIMING); |
3110 |
+ } |
3111 |
+ } |
3112 |
++ mtk_i2c_writew(i2c, ext_conf_val, OFFSET_EXT_CONF); |
3113 |
+ |
3114 |
+ /* If use i2c pin from PMIC mt6397 side, need set PATH_DIR first */ |
3115 |
+ if (i2c->have_pmic) |
3116 |
+diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c |
3117 |
+index 6f0aa0ed3241e..74925621f2395 100644 |
3118 |
+--- a/drivers/i2c/i2c-core-acpi.c |
3119 |
++++ b/drivers/i2c/i2c-core-acpi.c |
3120 |
+@@ -422,6 +422,7 @@ static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, |
3121 |
+ break; |
3122 |
+ |
3123 |
+ i2c_acpi_register_device(adapter, adev, &info); |
3124 |
++ put_device(&adapter->dev); |
3125 |
+ break; |
3126 |
+ case ACPI_RECONFIG_DEVICE_REMOVE: |
3127 |
+ if (!acpi_device_enumerated(adev)) |
3128 |
+diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c |
3129 |
+index 3f28eb4d17fe7..8f36536cb1b6d 100644 |
3130 |
+--- a/drivers/mmc/host/meson-gx-mmc.c |
3131 |
++++ b/drivers/mmc/host/meson-gx-mmc.c |
3132 |
+@@ -746,7 +746,7 @@ static void meson_mmc_desc_chain_transfer(struct mmc_host *mmc, u32 cmd_cfg) |
3133 |
+ writel(start, host->regs + SD_EMMC_START); |
3134 |
+ } |
3135 |
+ |
3136 |
+-/* local sg copy to buffer version with _to/fromio usage for dram_access_quirk */ |
3137 |
++/* local sg copy for dram_access_quirk */ |
3138 |
+ static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data, |
3139 |
+ size_t buflen, bool to_buffer) |
3140 |
+ { |
3141 |
+@@ -764,21 +764,27 @@ static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data |
3142 |
+ sg_miter_start(&miter, sgl, nents, sg_flags); |
3143 |
+ |
3144 |
+ while ((offset < buflen) && sg_miter_next(&miter)) { |
3145 |
+- unsigned int len; |
3146 |
++ unsigned int buf_offset = 0; |
3147 |
++ unsigned int len, left; |
3148 |
++ u32 *buf = miter.addr; |
3149 |
+ |
3150 |
+ len = min(miter.length, buflen - offset); |
3151 |
++ left = len; |
3152 |
+ |
3153 |
+- /* When dram_access_quirk, the bounce buffer is a iomem mapping */ |
3154 |
+- if (host->dram_access_quirk) { |
3155 |
+- if (to_buffer) |
3156 |
+- memcpy_toio(host->bounce_iomem_buf + offset, miter.addr, len); |
3157 |
+- else |
3158 |
+- memcpy_fromio(miter.addr, host->bounce_iomem_buf + offset, len); |
3159 |
++ if (to_buffer) { |
3160 |
++ do { |
3161 |
++ writel(*buf++, host->bounce_iomem_buf + offset + buf_offset); |
3162 |
++ |
3163 |
++ buf_offset += 4; |
3164 |
++ left -= 4; |
3165 |
++ } while (left); |
3166 |
+ } else { |
3167 |
+- if (to_buffer) |
3168 |
+- memcpy(host->bounce_buf + offset, miter.addr, len); |
3169 |
+- else |
3170 |
+- memcpy(miter.addr, host->bounce_buf + offset, len); |
3171 |
++ do { |
3172 |
++ *buf++ = readl(host->bounce_iomem_buf + offset + buf_offset); |
3173 |
++ |
3174 |
++ buf_offset += 4; |
3175 |
++ left -= 4; |
3176 |
++ } while (left); |
3177 |
+ } |
3178 |
+ |
3179 |
+ offset += len; |
3180 |
+@@ -830,7 +836,11 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) |
3181 |
+ if (data->flags & MMC_DATA_WRITE) { |
3182 |
+ cmd_cfg |= CMD_CFG_DATA_WR; |
3183 |
+ WARN_ON(xfer_bytes > host->bounce_buf_size); |
3184 |
+- meson_mmc_copy_buffer(host, data, xfer_bytes, true); |
3185 |
++ if (host->dram_access_quirk) |
3186 |
++ meson_mmc_copy_buffer(host, data, xfer_bytes, true); |
3187 |
++ else |
3188 |
++ sg_copy_to_buffer(data->sg, data->sg_len, |
3189 |
++ host->bounce_buf, xfer_bytes); |
3190 |
+ dma_wmb(); |
3191 |
+ } |
3192 |
+ |
3193 |
+@@ -849,12 +859,43 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) |
3194 |
+ writel(cmd->arg, host->regs + SD_EMMC_CMD_ARG); |
3195 |
+ } |
3196 |
+ |
3197 |
++static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data *data) |
3198 |
++{ |
3199 |
++ struct scatterlist *sg; |
3200 |
++ int i; |
3201 |
++ |
3202 |
++ /* Reject request if any element offset or size is not 32bit aligned */ |
3203 |
++ for_each_sg(data->sg, sg, data->sg_len, i) { |
3204 |
++ if (!IS_ALIGNED(sg->offset, sizeof(u32)) || |
3205 |
++ !IS_ALIGNED(sg->length, sizeof(u32))) { |
3206 |
++ dev_err(mmc_dev(mmc), "unaligned sg offset %u len %u\n", |
3207 |
++ data->sg->offset, data->sg->length); |
3208 |
++ return -EINVAL; |
3209 |
++ } |
3210 |
++ } |
3211 |
++ |
3212 |
++ return 0; |
3213 |
++} |
3214 |
++ |
3215 |
+ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) |
3216 |
+ { |
3217 |
+ struct meson_host *host = mmc_priv(mmc); |
3218 |
+ bool needs_pre_post_req = mrq->data && |
3219 |
+ !(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE); |
3220 |
+ |
3221 |
++ /* |
3222 |
++ * The memory at the end of the controller used as bounce buffer for |
3223 |
++ * the dram_access_quirk only accepts 32bit read/write access, |
3224 |
++ * check the aligment and length of the data before starting the request. |
3225 |
++ */ |
3226 |
++ if (host->dram_access_quirk && mrq->data) { |
3227 |
++ mrq->cmd->error = meson_mmc_validate_dram_access(mmc, mrq->data); |
3228 |
++ if (mrq->cmd->error) { |
3229 |
++ mmc_request_done(mmc, mrq); |
3230 |
++ return; |
3231 |
++ } |
3232 |
++ } |
3233 |
++ |
3234 |
+ if (needs_pre_post_req) { |
3235 |
+ meson_mmc_get_transfer_mode(mmc, mrq); |
3236 |
+ if (!meson_mmc_desc_chain_mode(mrq->data)) |
3237 |
+@@ -999,7 +1040,11 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) |
3238 |
+ if (meson_mmc_bounce_buf_read(data)) { |
3239 |
+ xfer_bytes = data->blksz * data->blocks; |
3240 |
+ WARN_ON(xfer_bytes > host->bounce_buf_size); |
3241 |
+- meson_mmc_copy_buffer(host, data, xfer_bytes, false); |
3242 |
++ if (host->dram_access_quirk) |
3243 |
++ meson_mmc_copy_buffer(host, data, xfer_bytes, false); |
3244 |
++ else |
3245 |
++ sg_copy_from_buffer(data->sg, data->sg_len, |
3246 |
++ host->bounce_buf, xfer_bytes); |
3247 |
+ } |
3248 |
+ |
3249 |
+ next_cmd = meson_mmc_get_next_command(cmd); |
3250 |
+diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c |
3251 |
+index 5564d7b23e7cd..d1a1c548c515f 100644 |
3252 |
+--- a/drivers/mmc/host/sdhci-of-at91.c |
3253 |
++++ b/drivers/mmc/host/sdhci-of-at91.c |
3254 |
+@@ -11,6 +11,7 @@ |
3255 |
+ #include <linux/delay.h> |
3256 |
+ #include <linux/err.h> |
3257 |
+ #include <linux/io.h> |
3258 |
++#include <linux/iopoll.h> |
3259 |
+ #include <linux/kernel.h> |
3260 |
+ #include <linux/mmc/host.h> |
3261 |
+ #include <linux/mmc/slot-gpio.h> |
3262 |
+@@ -61,7 +62,6 @@ static void sdhci_at91_set_force_card_detect(struct sdhci_host *host) |
3263 |
+ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock) |
3264 |
+ { |
3265 |
+ u16 clk; |
3266 |
+- unsigned long timeout; |
3267 |
+ |
3268 |
+ host->mmc->actual_clock = 0; |
3269 |
+ |
3270 |
+@@ -86,16 +86,11 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock) |
3271 |
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); |
3272 |
+ |
3273 |
+ /* Wait max 20 ms */ |
3274 |
+- timeout = 20; |
3275 |
+- while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) |
3276 |
+- & SDHCI_CLOCK_INT_STABLE)) { |
3277 |
+- if (timeout == 0) { |
3278 |
+- pr_err("%s: Internal clock never stabilised.\n", |
3279 |
+- mmc_hostname(host->mmc)); |
3280 |
+- return; |
3281 |
+- } |
3282 |
+- timeout--; |
3283 |
+- mdelay(1); |
3284 |
++ if (read_poll_timeout(sdhci_readw, clk, (clk & SDHCI_CLOCK_INT_STABLE), |
3285 |
++ 1000, 20000, false, host, SDHCI_CLOCK_CONTROL)) { |
3286 |
++ pr_err("%s: Internal clock never stabilised.\n", |
3287 |
++ mmc_hostname(host->mmc)); |
3288 |
++ return; |
3289 |
+ } |
3290 |
+ |
3291 |
+ clk |= SDHCI_CLOCK_CARD_EN; |
3292 |
+@@ -114,6 +109,7 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask) |
3293 |
+ { |
3294 |
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
3295 |
+ struct sdhci_at91_priv *priv = sdhci_pltfm_priv(pltfm_host); |
3296 |
++ unsigned int tmp; |
3297 |
+ |
3298 |
+ sdhci_reset(host, mask); |
3299 |
+ |
3300 |
+@@ -126,6 +122,10 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask) |
3301 |
+ |
3302 |
+ sdhci_writel(host, calcr | SDMMC_CALCR_ALWYSON | SDMMC_CALCR_EN, |
3303 |
+ SDMMC_CALCR); |
3304 |
++ |
3305 |
++ if (read_poll_timeout(sdhci_readl, tmp, !(tmp & SDMMC_CALCR_EN), |
3306 |
++ 10, 20000, false, host, SDMMC_CALCR)) |
3307 |
++ dev_err(mmc_dev(host->mmc), "Failed to calibrate\n"); |
3308 |
+ } |
3309 |
+ } |
3310 |
+ |
3311 |
+diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h |
3312 |
+index 1d3188e8e3b3c..92dc18a4bcc41 100644 |
3313 |
+--- a/drivers/net/ethernet/google/gve/gve.h |
3314 |
++++ b/drivers/net/ethernet/google/gve/gve.h |
3315 |
+@@ -780,7 +780,7 @@ struct gve_queue_page_list *gve_assign_rx_qpl(struct gve_priv *priv) |
3316 |
+ gve_num_tx_qpls(priv)); |
3317 |
+ |
3318 |
+ /* we are out of rx qpls */ |
3319 |
+- if (id == priv->qpl_cfg.qpl_map_size) |
3320 |
++ if (id == gve_num_tx_qpls(priv) + gve_num_rx_qpls(priv)) |
3321 |
+ return NULL; |
3322 |
+ |
3323 |
+ set_bit(id, priv->qpl_cfg.qpl_id_map); |
3324 |
+diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c |
3325 |
+index 099a2bc5ae670..bf8a4a7c43f78 100644 |
3326 |
+--- a/drivers/net/ethernet/google/gve/gve_main.c |
3327 |
++++ b/drivers/net/ethernet/google/gve/gve_main.c |
3328 |
+@@ -41,6 +41,7 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) |
3329 |
+ { |
3330 |
+ struct gve_priv *priv = netdev_priv(dev); |
3331 |
+ unsigned int start; |
3332 |
++ u64 packets, bytes; |
3333 |
+ int ring; |
3334 |
+ |
3335 |
+ if (priv->rx) { |
3336 |
+@@ -48,10 +49,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) |
3337 |
+ do { |
3338 |
+ start = |
3339 |
+ u64_stats_fetch_begin(&priv->rx[ring].statss); |
3340 |
+- s->rx_packets += priv->rx[ring].rpackets; |
3341 |
+- s->rx_bytes += priv->rx[ring].rbytes; |
3342 |
++ packets = priv->rx[ring].rpackets; |
3343 |
++ bytes = priv->rx[ring].rbytes; |
3344 |
+ } while (u64_stats_fetch_retry(&priv->rx[ring].statss, |
3345 |
+ start)); |
3346 |
++ s->rx_packets += packets; |
3347 |
++ s->rx_bytes += bytes; |
3348 |
+ } |
3349 |
+ } |
3350 |
+ if (priv->tx) { |
3351 |
+@@ -59,10 +62,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) |
3352 |
+ do { |
3353 |
+ start = |
3354 |
+ u64_stats_fetch_begin(&priv->tx[ring].statss); |
3355 |
+- s->tx_packets += priv->tx[ring].pkt_done; |
3356 |
+- s->tx_bytes += priv->tx[ring].bytes_done; |
3357 |
++ packets = priv->tx[ring].pkt_done; |
3358 |
++ bytes = priv->tx[ring].bytes_done; |
3359 |
+ } while (u64_stats_fetch_retry(&priv->tx[ring].statss, |
3360 |
+ start)); |
3361 |
++ s->tx_packets += packets; |
3362 |
++ s->tx_bytes += bytes; |
3363 |
+ } |
3364 |
+ } |
3365 |
+ } |
3366 |
+@@ -82,6 +87,9 @@ static int gve_alloc_counter_array(struct gve_priv *priv) |
3367 |
+ |
3368 |
+ static void gve_free_counter_array(struct gve_priv *priv) |
3369 |
+ { |
3370 |
++ if (!priv->counter_array) |
3371 |
++ return; |
3372 |
++ |
3373 |
+ dma_free_coherent(&priv->pdev->dev, |
3374 |
+ priv->num_event_counters * |
3375 |
+ sizeof(*priv->counter_array), |
3376 |
+@@ -142,6 +150,9 @@ static int gve_alloc_stats_report(struct gve_priv *priv) |
3377 |
+ |
3378 |
+ static void gve_free_stats_report(struct gve_priv *priv) |
3379 |
+ { |
3380 |
++ if (!priv->stats_report) |
3381 |
++ return; |
3382 |
++ |
3383 |
+ del_timer_sync(&priv->stats_report_timer); |
3384 |
+ dma_free_coherent(&priv->pdev->dev, priv->stats_report_len, |
3385 |
+ priv->stats_report, priv->stats_report_bus); |
3386 |
+@@ -370,18 +381,19 @@ static void gve_free_notify_blocks(struct gve_priv *priv) |
3387 |
+ { |
3388 |
+ int i; |
3389 |
+ |
3390 |
+- if (priv->msix_vectors) { |
3391 |
+- /* Free the irqs */ |
3392 |
+- for (i = 0; i < priv->num_ntfy_blks; i++) { |
3393 |
+- struct gve_notify_block *block = &priv->ntfy_blocks[i]; |
3394 |
+- int msix_idx = i; |
3395 |
++ if (!priv->msix_vectors) |
3396 |
++ return; |
3397 |
+ |
3398 |
+- irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, |
3399 |
+- NULL); |
3400 |
+- free_irq(priv->msix_vectors[msix_idx].vector, block); |
3401 |
+- } |
3402 |
+- free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); |
3403 |
++ /* Free the irqs */ |
3404 |
++ for (i = 0; i < priv->num_ntfy_blks; i++) { |
3405 |
++ struct gve_notify_block *block = &priv->ntfy_blocks[i]; |
3406 |
++ int msix_idx = i; |
3407 |
++ |
3408 |
++ irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, |
3409 |
++ NULL); |
3410 |
++ free_irq(priv->msix_vectors[msix_idx].vector, block); |
3411 |
+ } |
3412 |
++ free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); |
3413 |
+ dma_free_coherent(&priv->pdev->dev, |
3414 |
+ priv->num_ntfy_blks * sizeof(*priv->ntfy_blocks), |
3415 |
+ priv->ntfy_blocks, priv->ntfy_block_bus); |
3416 |
+@@ -1185,9 +1197,10 @@ static void gve_handle_reset(struct gve_priv *priv) |
3417 |
+ |
3418 |
+ void gve_handle_report_stats(struct gve_priv *priv) |
3419 |
+ { |
3420 |
+- int idx, stats_idx = 0, tx_bytes; |
3421 |
+- unsigned int start = 0; |
3422 |
+ struct stats *stats = priv->stats_report->stats; |
3423 |
++ int idx, stats_idx = 0; |
3424 |
++ unsigned int start = 0; |
3425 |
++ u64 tx_bytes; |
3426 |
+ |
3427 |
+ if (!gve_get_report_stats(priv)) |
3428 |
+ return; |
3429 |
+diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c |
3430 |
+index bb82613682502..94941d4e47449 100644 |
3431 |
+--- a/drivers/net/ethernet/google/gve/gve_rx.c |
3432 |
++++ b/drivers/net/ethernet/google/gve/gve_rx.c |
3433 |
+@@ -104,8 +104,14 @@ static int gve_prefill_rx_pages(struct gve_rx_ring *rx) |
3434 |
+ if (!rx->data.page_info) |
3435 |
+ return -ENOMEM; |
3436 |
+ |
3437 |
+- if (!rx->data.raw_addressing) |
3438 |
++ if (!rx->data.raw_addressing) { |
3439 |
+ rx->data.qpl = gve_assign_rx_qpl(priv); |
3440 |
++ if (!rx->data.qpl) { |
3441 |
++ kvfree(rx->data.page_info); |
3442 |
++ rx->data.page_info = NULL; |
3443 |
++ return -ENOMEM; |
3444 |
++ } |
3445 |
++ } |
3446 |
+ for (i = 0; i < slots; i++) { |
3447 |
+ if (!rx->data.raw_addressing) { |
3448 |
+ struct page *page = rx->data.qpl->pages[i]; |
3449 |
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c |
3450 |
+index 1d1f52756a932..5d3d6b1dae7b0 100644 |
3451 |
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c |
3452 |
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c |
3453 |
+@@ -4868,7 +4868,8 @@ static void i40e_clear_interrupt_scheme(struct i40e_pf *pf) |
3454 |
+ { |
3455 |
+ int i; |
3456 |
+ |
3457 |
+- i40e_free_misc_vector(pf); |
3458 |
++ if (test_bit(__I40E_MISC_IRQ_REQUESTED, pf->state)) |
3459 |
++ i40e_free_misc_vector(pf); |
3460 |
+ |
3461 |
+ i40e_put_lump(pf->irq_pile, pf->iwarp_base_vector, |
3462 |
+ I40E_IWARP_IRQ_PILE_ID); |
3463 |
+@@ -10110,7 +10111,7 @@ static int i40e_get_capabilities(struct i40e_pf *pf, |
3464 |
+ if (pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOMEM) { |
3465 |
+ /* retry with a larger buffer */ |
3466 |
+ buf_len = data_size; |
3467 |
+- } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK) { |
3468 |
++ } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK || err) { |
3469 |
+ dev_info(&pf->pdev->dev, |
3470 |
+ "capability discovery failed, err %s aq_err %s\n", |
3471 |
+ i40e_stat_str(&pf->hw, err), |
3472 |
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c |
3473 |
+index 23762a7ef740b..cada4e0e40b48 100644 |
3474 |
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c |
3475 |
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c |
3476 |
+@@ -1965,7 +1965,6 @@ static void iavf_watchdog_task(struct work_struct *work) |
3477 |
+ } |
3478 |
+ adapter->aq_required = 0; |
3479 |
+ adapter->current_op = VIRTCHNL_OP_UNKNOWN; |
3480 |
+- mutex_unlock(&adapter->crit_lock); |
3481 |
+ queue_delayed_work(iavf_wq, |
3482 |
+ &adapter->watchdog_task, |
3483 |
+ msecs_to_jiffies(10)); |
3484 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h |
3485 |
+index 3f67efbe12fc5..dcbdf746be35c 100644 |
3486 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h |
3487 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h |
3488 |
+@@ -863,6 +863,7 @@ struct mlx5e_priv { |
3489 |
+ struct mlx5e_channel_stats channel_stats[MLX5E_MAX_NUM_CHANNELS]; |
3490 |
+ struct mlx5e_channel_stats trap_stats; |
3491 |
+ struct mlx5e_ptp_stats ptp_stats; |
3492 |
++ u16 stats_nch; |
3493 |
+ u16 max_nch; |
3494 |
+ u8 max_opened_tc; |
3495 |
+ bool tx_ptp_opened; |
3496 |
+@@ -1156,12 +1157,6 @@ int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv, |
3497 |
+ struct ethtool_pauseparam *pauseparam); |
3498 |
+ |
3499 |
+ /* mlx5e generic netdev management API */ |
3500 |
+-static inline unsigned int |
3501 |
+-mlx5e_calc_max_nch(struct mlx5e_priv *priv, const struct mlx5e_profile *profile) |
3502 |
+-{ |
3503 |
+- return priv->netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1); |
3504 |
+-} |
3505 |
+- |
3506 |
+ static inline bool |
3507 |
+ mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev) |
3508 |
+ { |
3509 |
+@@ -1170,11 +1165,13 @@ mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev) |
3510 |
+ } |
3511 |
+ |
3512 |
+ int mlx5e_priv_init(struct mlx5e_priv *priv, |
3513 |
++ const struct mlx5e_profile *profile, |
3514 |
+ struct net_device *netdev, |
3515 |
+ struct mlx5_core_dev *mdev); |
3516 |
+ void mlx5e_priv_cleanup(struct mlx5e_priv *priv); |
3517 |
+ struct net_device * |
3518 |
+-mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs); |
3519 |
++mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile, |
3520 |
++ unsigned int txqs, unsigned int rxqs); |
3521 |
+ int mlx5e_attach_netdev(struct mlx5e_priv *priv); |
3522 |
+ void mlx5e_detach_netdev(struct mlx5e_priv *priv); |
3523 |
+ void mlx5e_destroy_netdev(struct mlx5e_priv *priv); |
3524 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c |
3525 |
+index ac44bbe95c5c1..d290d7276b8d9 100644 |
3526 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c |
3527 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c |
3528 |
+@@ -35,7 +35,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data, |
3529 |
+ { |
3530 |
+ int ch, i = 0; |
3531 |
+ |
3532 |
+- for (ch = 0; ch < priv->max_nch; ch++) { |
3533 |
++ for (ch = 0; ch < priv->stats_nch; ch++) { |
3534 |
+ void *buf = data + i; |
3535 |
+ |
3536 |
+ if (WARN_ON_ONCE(buf + |
3537 |
+@@ -51,7 +51,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data, |
3538 |
+ static int mlx5e_hv_vhca_stats_buf_size(struct mlx5e_priv *priv) |
3539 |
+ { |
3540 |
+ return (sizeof(struct mlx5e_hv_vhca_per_ring_stats) * |
3541 |
+- priv->max_nch); |
3542 |
++ priv->stats_nch); |
3543 |
+ } |
3544 |
+ |
3545 |
+ static void mlx5e_hv_vhca_stats_work(struct work_struct *work) |
3546 |
+@@ -100,7 +100,7 @@ static void mlx5e_hv_vhca_stats_control(struct mlx5_hv_vhca_agent *agent, |
3547 |
+ sagent = &priv->stats_agent; |
3548 |
+ |
3549 |
+ block->version = MLX5_HV_VHCA_STATS_VERSION; |
3550 |
+- block->rings = priv->max_nch; |
3551 |
++ block->rings = priv->stats_nch; |
3552 |
+ |
3553 |
+ if (!block->command) { |
3554 |
+ cancel_delayed_work_sync(&priv->stats_agent.work); |
3555 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c |
3556 |
+index efef4adce086a..93a8fa31255d0 100644 |
3557 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c |
3558 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c |
3559 |
+@@ -13,8 +13,6 @@ struct mlx5e_ptp_fs { |
3560 |
+ bool valid; |
3561 |
+ }; |
3562 |
+ |
3563 |
+-#define MLX5E_PTP_CHANNEL_IX 0 |
3564 |
+- |
3565 |
+ struct mlx5e_ptp_params { |
3566 |
+ struct mlx5e_params params; |
3567 |
+ struct mlx5e_sq_param txq_sq_param; |
3568 |
+@@ -505,6 +503,7 @@ static int mlx5e_init_ptp_rq(struct mlx5e_ptp *c, struct mlx5e_params *params, |
3569 |
+ rq->mdev = mdev; |
3570 |
+ rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); |
3571 |
+ rq->stats = &c->priv->ptp_stats.rq; |
3572 |
++ rq->ix = MLX5E_PTP_CHANNEL_IX; |
3573 |
+ rq->ptp_cyc2time = mlx5_rq_ts_translator(mdev); |
3574 |
+ err = mlx5e_rq_set_handlers(rq, params, false); |
3575 |
+ if (err) |
3576 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h |
3577 |
+index c96668bd701cd..a71a32e00ebb9 100644 |
3578 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h |
3579 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h |
3580 |
+@@ -8,6 +8,8 @@ |
3581 |
+ #include "en_stats.h" |
3582 |
+ #include <linux/ptp_classify.h> |
3583 |
+ |
3584 |
++#define MLX5E_PTP_CHANNEL_IX 0 |
3585 |
++ |
3586 |
+ struct mlx5e_ptpsq { |
3587 |
+ struct mlx5e_txqsq txqsq; |
3588 |
+ struct mlx5e_cq ts_cq; |
3589 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
3590 |
+index fa718e71db2d4..548e8e7fc956e 100644 |
3591 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
3592 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
3593 |
+@@ -3515,7 +3515,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s) |
3594 |
+ { |
3595 |
+ int i; |
3596 |
+ |
3597 |
+- for (i = 0; i < priv->max_nch; i++) { |
3598 |
++ for (i = 0; i < priv->stats_nch; i++) { |
3599 |
+ struct mlx5e_channel_stats *channel_stats = &priv->channel_stats[i]; |
3600 |
+ struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq; |
3601 |
+ struct mlx5e_rq_stats *rq_stats = &channel_stats->rq; |
3602 |
+@@ -4661,8 +4661,6 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16 |
3603 |
+ struct mlx5_core_dev *mdev = priv->mdev; |
3604 |
+ u8 rx_cq_period_mode; |
3605 |
+ |
3606 |
+- priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile); |
3607 |
+- |
3608 |
+ params->sw_mtu = mtu; |
3609 |
+ params->hard_mtu = MLX5E_ETH_HARD_MTU; |
3610 |
+ params->num_channels = min_t(unsigned int, MLX5E_MAX_NUM_CHANNELS / 2, |
3611 |
+@@ -5203,8 +5201,35 @@ static const struct mlx5e_profile mlx5e_nic_profile = { |
3612 |
+ .rx_ptp_support = true, |
3613 |
+ }; |
3614 |
+ |
3615 |
++static unsigned int |
3616 |
++mlx5e_calc_max_nch(struct mlx5_core_dev *mdev, struct net_device *netdev, |
3617 |
++ const struct mlx5e_profile *profile) |
3618 |
++ |
3619 |
++{ |
3620 |
++ unsigned int max_nch, tmp; |
3621 |
++ |
3622 |
++ /* core resources */ |
3623 |
++ max_nch = mlx5e_get_max_num_channels(mdev); |
3624 |
++ |
3625 |
++ /* netdev rx queues */ |
3626 |
++ tmp = netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1); |
3627 |
++ max_nch = min_t(unsigned int, max_nch, tmp); |
3628 |
++ |
3629 |
++ /* netdev tx queues */ |
3630 |
++ tmp = netdev->num_tx_queues; |
3631 |
++ if (mlx5_qos_is_supported(mdev)) |
3632 |
++ tmp -= mlx5e_qos_max_leaf_nodes(mdev); |
3633 |
++ if (MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn)) |
3634 |
++ tmp -= profile->max_tc; |
3635 |
++ tmp = tmp / profile->max_tc; |
3636 |
++ max_nch = min_t(unsigned int, max_nch, tmp); |
3637 |
++ |
3638 |
++ return max_nch; |
3639 |
++} |
3640 |
++ |
3641 |
+ /* mlx5e generic netdev management API (move to en_common.c) */ |
3642 |
+ int mlx5e_priv_init(struct mlx5e_priv *priv, |
3643 |
++ const struct mlx5e_profile *profile, |
3644 |
+ struct net_device *netdev, |
3645 |
+ struct mlx5_core_dev *mdev) |
3646 |
+ { |
3647 |
+@@ -5212,6 +5237,8 @@ int mlx5e_priv_init(struct mlx5e_priv *priv, |
3648 |
+ priv->mdev = mdev; |
3649 |
+ priv->netdev = netdev; |
3650 |
+ priv->msglevel = MLX5E_MSG_LEVEL; |
3651 |
++ priv->max_nch = mlx5e_calc_max_nch(mdev, netdev, profile); |
3652 |
++ priv->stats_nch = priv->max_nch; |
3653 |
+ priv->max_opened_tc = 1; |
3654 |
+ |
3655 |
+ if (!alloc_cpumask_var(&priv->scratchpad.cpumask, GFP_KERNEL)) |
3656 |
+@@ -5255,7 +5282,8 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv) |
3657 |
+ } |
3658 |
+ |
3659 |
+ struct net_device * |
3660 |
+-mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs) |
3661 |
++mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile, |
3662 |
++ unsigned int txqs, unsigned int rxqs) |
3663 |
+ { |
3664 |
+ struct net_device *netdev; |
3665 |
+ int err; |
3666 |
+@@ -5266,7 +5294,7 @@ mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int |
3667 |
+ return NULL; |
3668 |
+ } |
3669 |
+ |
3670 |
+- err = mlx5e_priv_init(netdev_priv(netdev), netdev, mdev); |
3671 |
++ err = mlx5e_priv_init(netdev_priv(netdev), profile, netdev, mdev); |
3672 |
+ if (err) { |
3673 |
+ mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err); |
3674 |
+ goto err_free_netdev; |
3675 |
+@@ -5308,7 +5336,7 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv) |
3676 |
+ clear_bit(MLX5E_STATE_DESTROYING, &priv->state); |
3677 |
+ |
3678 |
+ /* max number of channels may have changed */ |
3679 |
+- max_nch = mlx5e_get_max_num_channels(priv->mdev); |
3680 |
++ max_nch = mlx5e_calc_max_nch(priv->mdev, priv->netdev, profile); |
3681 |
+ if (priv->channels.params.num_channels > max_nch) { |
3682 |
+ mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch); |
3683 |
+ /* Reducing the number of channels - RXFH has to be reset, and |
3684 |
+@@ -5317,6 +5345,13 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv) |
3685 |
+ priv->netdev->priv_flags &= ~IFF_RXFH_CONFIGURED; |
3686 |
+ priv->channels.params.num_channels = max_nch; |
3687 |
+ } |
3688 |
++ if (max_nch != priv->max_nch) { |
3689 |
++ mlx5_core_warn(priv->mdev, |
3690 |
++ "MLX5E: Updating max number of channels from %u to %u\n", |
3691 |
++ priv->max_nch, max_nch); |
3692 |
++ priv->max_nch = max_nch; |
3693 |
++ } |
3694 |
++ |
3695 |
+ /* 1. Set the real number of queues in the kernel the first time. |
3696 |
+ * 2. Set our default XPS cpumask. |
3697 |
+ * 3. Build the RQT. |
3698 |
+@@ -5381,7 +5416,7 @@ mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mde |
3699 |
+ struct mlx5e_priv *priv = netdev_priv(netdev); |
3700 |
+ int err; |
3701 |
+ |
3702 |
+- err = mlx5e_priv_init(priv, netdev, mdev); |
3703 |
++ err = mlx5e_priv_init(priv, new_profile, netdev, mdev); |
3704 |
+ if (err) { |
3705 |
+ mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err); |
3706 |
+ return err; |
3707 |
+@@ -5407,20 +5442,12 @@ priv_cleanup: |
3708 |
+ int mlx5e_netdev_change_profile(struct mlx5e_priv *priv, |
3709 |
+ const struct mlx5e_profile *new_profile, void *new_ppriv) |
3710 |
+ { |
3711 |
+- unsigned int new_max_nch = mlx5e_calc_max_nch(priv, new_profile); |
3712 |
+ const struct mlx5e_profile *orig_profile = priv->profile; |
3713 |
+ struct net_device *netdev = priv->netdev; |
3714 |
+ struct mlx5_core_dev *mdev = priv->mdev; |
3715 |
+ void *orig_ppriv = priv->ppriv; |
3716 |
+ int err, rollback_err; |
3717 |
+ |
3718 |
+- /* sanity */ |
3719 |
+- if (new_max_nch != priv->max_nch) { |
3720 |
+- netdev_warn(netdev, "%s: Replacing profile with different max channels\n", |
3721 |
+- __func__); |
3722 |
+- return -EINVAL; |
3723 |
+- } |
3724 |
+- |
3725 |
+ /* cleanup old profile */ |
3726 |
+ mlx5e_detach_netdev(priv); |
3727 |
+ priv->profile->cleanup(priv); |
3728 |
+@@ -5516,7 +5543,7 @@ static int mlx5e_probe(struct auxiliary_device *adev, |
3729 |
+ nch = mlx5e_get_max_num_channels(mdev); |
3730 |
+ txqs = nch * profile->max_tc + ptp_txqs + qos_sqs; |
3731 |
+ rxqs = nch * profile->rq_groups; |
3732 |
+- netdev = mlx5e_create_netdev(mdev, txqs, rxqs); |
3733 |
++ netdev = mlx5e_create_netdev(mdev, profile, txqs, rxqs); |
3734 |
+ if (!netdev) { |
3735 |
+ mlx5_core_err(mdev, "mlx5e_create_netdev failed\n"); |
3736 |
+ return -ENOMEM; |
3737 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c |
3738 |
+index bf94bcb6fa5d2..bec1d344481cd 100644 |
3739 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c |
3740 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c |
3741 |
+@@ -561,7 +561,6 @@ static void mlx5e_build_rep_params(struct net_device *netdev) |
3742 |
+ MLX5_CQ_PERIOD_MODE_START_FROM_CQE : |
3743 |
+ MLX5_CQ_PERIOD_MODE_START_FROM_EQE; |
3744 |
+ |
3745 |
+- priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile); |
3746 |
+ params = &priv->channels.params; |
3747 |
+ |
3748 |
+ params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS; |
3749 |
+@@ -1151,7 +1150,7 @@ mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) |
3750 |
+ nch = mlx5e_get_max_num_channels(dev); |
3751 |
+ txqs = nch * profile->max_tc; |
3752 |
+ rxqs = nch * profile->rq_groups; |
3753 |
+- netdev = mlx5e_create_netdev(dev, txqs, rxqs); |
3754 |
++ netdev = mlx5e_create_netdev(dev, profile, txqs, rxqs); |
3755 |
+ if (!netdev) { |
3756 |
+ mlx5_core_warn(dev, |
3757 |
+ "Failed to create representor netdev for vport %d\n", |
3758 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c |
3759 |
+index 3c65fd0bcf31c..29a6586ef28dc 100644 |
3760 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c |
3761 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c |
3762 |
+@@ -1001,14 +1001,9 @@ static inline void mlx5e_handle_csum(struct net_device *netdev, |
3763 |
+ goto csum_unnecessary; |
3764 |
+ |
3765 |
+ if (likely(is_last_ethertype_ip(skb, &network_depth, &proto))) { |
3766 |
+- u8 ipproto = get_ip_proto(skb, network_depth, proto); |
3767 |
+- |
3768 |
+- if (unlikely(ipproto == IPPROTO_SCTP)) |
3769 |
++ if (unlikely(get_ip_proto(skb, network_depth, proto) == IPPROTO_SCTP)) |
3770 |
+ goto csum_unnecessary; |
3771 |
+ |
3772 |
+- if (unlikely(mlx5_ipsec_is_rx_flow(cqe))) |
3773 |
+- goto csum_none; |
3774 |
+- |
3775 |
+ stats->csum_complete++; |
3776 |
+ skb->ip_summed = CHECKSUM_COMPLETE; |
3777 |
+ skb->csum = csum_unfold((__force __sum16)cqe->check_sum); |
3778 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c |
3779 |
+index e4f5b63951482..e1dd17019030e 100644 |
3780 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c |
3781 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c |
3782 |
+@@ -34,6 +34,7 @@ |
3783 |
+ #include "en.h" |
3784 |
+ #include "en_accel/tls.h" |
3785 |
+ #include "en_accel/en_accel.h" |
3786 |
++#include "en/ptp.h" |
3787 |
+ |
3788 |
+ static unsigned int stats_grps_num(struct mlx5e_priv *priv) |
3789 |
+ { |
3790 |
+@@ -450,7 +451,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw) |
3791 |
+ |
3792 |
+ memset(s, 0, sizeof(*s)); |
3793 |
+ |
3794 |
+- for (i = 0; i < priv->max_nch; i++) { |
3795 |
++ for (i = 0; i < priv->stats_nch; i++) { |
3796 |
+ struct mlx5e_channel_stats *channel_stats = |
3797 |
+ &priv->channel_stats[i]; |
3798 |
+ int j; |
3799 |
+@@ -2076,7 +2077,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(ptp) |
3800 |
+ if (priv->rx_ptp_opened) { |
3801 |
+ for (i = 0; i < NUM_PTP_RQ_STATS; i++) |
3802 |
+ sprintf(data + (idx++) * ETH_GSTRING_LEN, |
3803 |
+- ptp_rq_stats_desc[i].format); |
3804 |
++ ptp_rq_stats_desc[i].format, MLX5E_PTP_CHANNEL_IX); |
3805 |
+ } |
3806 |
+ return idx; |
3807 |
+ } |
3808 |
+@@ -2119,7 +2120,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ptp) { return; } |
3809 |
+ |
3810 |
+ static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels) |
3811 |
+ { |
3812 |
+- int max_nch = priv->max_nch; |
3813 |
++ int max_nch = priv->stats_nch; |
3814 |
+ |
3815 |
+ return (NUM_RQ_STATS * max_nch) + |
3816 |
+ (NUM_CH_STATS * max_nch) + |
3817 |
+@@ -2133,7 +2134,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels) |
3818 |
+ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels) |
3819 |
+ { |
3820 |
+ bool is_xsk = priv->xsk.ever_used; |
3821 |
+- int max_nch = priv->max_nch; |
3822 |
++ int max_nch = priv->stats_nch; |
3823 |
+ int i, j, tc; |
3824 |
+ |
3825 |
+ for (i = 0; i < max_nch; i++) |
3826 |
+@@ -2175,7 +2176,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels) |
3827 |
+ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(channels) |
3828 |
+ { |
3829 |
+ bool is_xsk = priv->xsk.ever_used; |
3830 |
+- int max_nch = priv->max_nch; |
3831 |
++ int max_nch = priv->stats_nch; |
3832 |
+ int i, j, tc; |
3833 |
+ |
3834 |
+ for (i = 0; i < max_nch; i++) |
3835 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c |
3836 |
+index 0399a396d1662..60a73990017c2 100644 |
3837 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c |
3838 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c |
3839 |
+@@ -79,12 +79,16 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw, |
3840 |
+ int dest_num = 0; |
3841 |
+ int err = 0; |
3842 |
+ |
3843 |
+- if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) { |
3844 |
++ if (vport->egress.legacy.drop_counter) { |
3845 |
++ drop_counter = vport->egress.legacy.drop_counter; |
3846 |
++ } else if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) { |
3847 |
+ drop_counter = mlx5_fc_create(esw->dev, false); |
3848 |
+- if (IS_ERR(drop_counter)) |
3849 |
++ if (IS_ERR(drop_counter)) { |
3850 |
+ esw_warn(esw->dev, |
3851 |
+ "vport[%d] configure egress drop rule counter err(%ld)\n", |
3852 |
+ vport->vport, PTR_ERR(drop_counter)); |
3853 |
++ drop_counter = NULL; |
3854 |
++ } |
3855 |
+ vport->egress.legacy.drop_counter = drop_counter; |
3856 |
+ } |
3857 |
+ |
3858 |
+@@ -123,7 +127,7 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw, |
3859 |
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP; |
3860 |
+ |
3861 |
+ /* Attach egress drop flow counter */ |
3862 |
+- if (!IS_ERR_OR_NULL(drop_counter)) { |
3863 |
++ if (drop_counter) { |
3864 |
+ flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT; |
3865 |
+ drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; |
3866 |
+ drop_ctr_dst.counter_id = mlx5_fc_id(drop_counter); |
3867 |
+@@ -162,7 +166,7 @@ void esw_acl_egress_lgcy_cleanup(struct mlx5_eswitch *esw, |
3868 |
+ esw_acl_egress_table_destroy(vport); |
3869 |
+ |
3870 |
+ clean_drop_counter: |
3871 |
+- if (!IS_ERR_OR_NULL(vport->egress.legacy.drop_counter)) { |
3872 |
++ if (vport->egress.legacy.drop_counter) { |
3873 |
+ mlx5_fc_destroy(esw->dev, vport->egress.legacy.drop_counter); |
3874 |
+ vport->egress.legacy.drop_counter = NULL; |
3875 |
+ } |
3876 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c |
3877 |
+index f75b86abaf1cd..b1a5199260f69 100644 |
3878 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c |
3879 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c |
3880 |
+@@ -160,7 +160,9 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw, |
3881 |
+ |
3882 |
+ esw_acl_ingress_lgcy_rules_destroy(vport); |
3883 |
+ |
3884 |
+- if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) { |
3885 |
++ if (vport->ingress.legacy.drop_counter) { |
3886 |
++ counter = vport->ingress.legacy.drop_counter; |
3887 |
++ } else if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) { |
3888 |
+ counter = mlx5_fc_create(esw->dev, false); |
3889 |
+ if (IS_ERR(counter)) { |
3890 |
+ esw_warn(esw->dev, |
3891 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c |
3892 |
+index 620d638e1e8ff..1c9de6eddef86 100644 |
3893 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c |
3894 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c |
3895 |
+@@ -113,7 +113,7 @@ static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv) |
3896 |
+ struct mlx5e_sw_stats s = { 0 }; |
3897 |
+ int i, j; |
3898 |
+ |
3899 |
+- for (i = 0; i < priv->max_nch; i++) { |
3900 |
++ for (i = 0; i < priv->stats_nch; i++) { |
3901 |
+ struct mlx5e_channel_stats *channel_stats; |
3902 |
+ struct mlx5e_rq_stats *rq_stats; |
3903 |
+ |
3904 |
+@@ -729,7 +729,7 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u32 port_num, |
3905 |
+ goto destroy_ht; |
3906 |
+ } |
3907 |
+ |
3908 |
+- err = mlx5e_priv_init(epriv, netdev, mdev); |
3909 |
++ err = mlx5e_priv_init(epriv, prof, netdev, mdev); |
3910 |
+ if (err) |
3911 |
+ goto destroy_mdev_resources; |
3912 |
+ |
3913 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c |
3914 |
+index ce696d5234931..c009ccc88df49 100644 |
3915 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c |
3916 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c |
3917 |
+@@ -448,22 +448,20 @@ static u64 find_target_cycles(struct mlx5_core_dev *mdev, s64 target_ns) |
3918 |
+ return cycles_now + cycles_delta; |
3919 |
+ } |
3920 |
+ |
3921 |
+-static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev, |
3922 |
+- s64 sec, u32 nsec) |
3923 |
++static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev, s64 sec) |
3924 |
+ { |
3925 |
+- struct timespec64 ts; |
3926 |
++ struct timespec64 ts = {}; |
3927 |
+ s64 target_ns; |
3928 |
+ |
3929 |
+ ts.tv_sec = sec; |
3930 |
+- ts.tv_nsec = nsec; |
3931 |
+ target_ns = timespec64_to_ns(&ts); |
3932 |
+ |
3933 |
+ return find_target_cycles(mdev, target_ns); |
3934 |
+ } |
3935 |
+ |
3936 |
+-static u64 perout_conf_real_time(s64 sec, u32 nsec) |
3937 |
++static u64 perout_conf_real_time(s64 sec) |
3938 |
+ { |
3939 |
+- return (u64)nsec | (u64)sec << 32; |
3940 |
++ return (u64)sec << 32; |
3941 |
+ } |
3942 |
+ |
3943 |
+ static int mlx5_perout_configure(struct ptp_clock_info *ptp, |
3944 |
+@@ -474,6 +472,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, |
3945 |
+ container_of(ptp, struct mlx5_clock, ptp_info); |
3946 |
+ struct mlx5_core_dev *mdev = |
3947 |
+ container_of(clock, struct mlx5_core_dev, clock); |
3948 |
++ bool rt_mode = mlx5_real_time_mode(mdev); |
3949 |
+ u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; |
3950 |
+ struct timespec64 ts; |
3951 |
+ u32 field_select = 0; |
3952 |
+@@ -501,8 +500,10 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, |
3953 |
+ |
3954 |
+ if (on) { |
3955 |
+ bool rt_mode = mlx5_real_time_mode(mdev); |
3956 |
+- u32 nsec; |
3957 |
+- s64 sec; |
3958 |
++ s64 sec = rq->perout.start.sec; |
3959 |
++ |
3960 |
++ if (rq->perout.start.nsec) |
3961 |
++ return -EINVAL; |
3962 |
+ |
3963 |
+ pin_mode = MLX5_PIN_MODE_OUT; |
3964 |
+ pattern = MLX5_OUT_PATTERN_PERIODIC; |
3965 |
+@@ -513,14 +514,11 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, |
3966 |
+ if ((ns >> 1) != 500000000LL) |
3967 |
+ return -EINVAL; |
3968 |
+ |
3969 |
+- nsec = rq->perout.start.nsec; |
3970 |
+- sec = rq->perout.start.sec; |
3971 |
+- |
3972 |
+ if (rt_mode && sec > U32_MAX) |
3973 |
+ return -EINVAL; |
3974 |
+ |
3975 |
+- time_stamp = rt_mode ? perout_conf_real_time(sec, nsec) : |
3976 |
+- perout_conf_internal_timer(mdev, sec, nsec); |
3977 |
++ time_stamp = rt_mode ? perout_conf_real_time(sec) : |
3978 |
++ perout_conf_internal_timer(mdev, sec); |
3979 |
+ |
3980 |
+ field_select |= MLX5_MTPPS_FS_PIN_MODE | |
3981 |
+ MLX5_MTPPS_FS_PATTERN | |
3982 |
+@@ -538,6 +536,9 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, |
3983 |
+ if (err) |
3984 |
+ return err; |
3985 |
+ |
3986 |
++ if (rt_mode) |
3987 |
++ return 0; |
3988 |
++ |
3989 |
+ return mlx5_set_mtppse(mdev, pin, 0, |
3990 |
+ MLX5_EVENT_MODE_REPETETIVE & on); |
3991 |
+ } |
3992 |
+@@ -705,20 +706,14 @@ static void ts_next_sec(struct timespec64 *ts) |
3993 |
+ static u64 perout_conf_next_event_timer(struct mlx5_core_dev *mdev, |
3994 |
+ struct mlx5_clock *clock) |
3995 |
+ { |
3996 |
+- bool rt_mode = mlx5_real_time_mode(mdev); |
3997 |
+ struct timespec64 ts; |
3998 |
+ s64 target_ns; |
3999 |
+ |
4000 |
+- if (rt_mode) |
4001 |
+- ts = mlx5_ptp_gettimex_real_time(mdev, NULL); |
4002 |
+- else |
4003 |
+- mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL); |
4004 |
+- |
4005 |
++ mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL); |
4006 |
+ ts_next_sec(&ts); |
4007 |
+ target_ns = timespec64_to_ns(&ts); |
4008 |
+ |
4009 |
+- return rt_mode ? perout_conf_real_time(ts.tv_sec, ts.tv_nsec) : |
4010 |
+- find_target_cycles(mdev, target_ns); |
4011 |
++ return find_target_cycles(mdev, target_ns); |
4012 |
+ } |
4013 |
+ |
4014 |
+ static int mlx5_pps_event(struct notifier_block *nb, |
4015 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c |
4016 |
+index 3465b363fc2fe..d9345c9ebbff1 100644 |
4017 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c |
4018 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c |
4019 |
+@@ -13,8 +13,8 @@ |
4020 |
+ #endif |
4021 |
+ |
4022 |
+ #define MLX5_MAX_IRQ_NAME (32) |
4023 |
+-/* max irq_index is 255. three chars */ |
4024 |
+-#define MLX5_MAX_IRQ_IDX_CHARS (3) |
4025 |
++/* max irq_index is 2047, so four chars */ |
4026 |
++#define MLX5_MAX_IRQ_IDX_CHARS (4) |
4027 |
+ |
4028 |
+ #define MLX5_SFS_PER_CTRL_IRQ 64 |
4029 |
+ #define MLX5_IRQ_CTRL_SF_MAX 8 |
4030 |
+@@ -610,8 +610,9 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev) |
4031 |
+ int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table) |
4032 |
+ { |
4033 |
+ if (table->sf_comp_pool) |
4034 |
+- return table->sf_comp_pool->xa_num_irqs.max - |
4035 |
+- table->sf_comp_pool->xa_num_irqs.min + 1; |
4036 |
++ return min_t(int, num_online_cpus(), |
4037 |
++ table->sf_comp_pool->xa_num_irqs.max - |
4038 |
++ table->sf_comp_pool->xa_num_irqs.min + 1); |
4039 |
+ else |
4040 |
+ return mlx5_irq_table_get_num_comp(table); |
4041 |
+ } |
4042 |
+diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.c b/drivers/net/ethernet/mscc/ocelot_vcap.c |
4043 |
+index 7945393a06557..99d7376a70a74 100644 |
4044 |
+--- a/drivers/net/ethernet/mscc/ocelot_vcap.c |
4045 |
++++ b/drivers/net/ethernet/mscc/ocelot_vcap.c |
4046 |
+@@ -998,8 +998,8 @@ ocelot_vcap_block_find_filter_by_index(struct ocelot_vcap_block *block, |
4047 |
+ } |
4048 |
+ |
4049 |
+ struct ocelot_vcap_filter * |
4050 |
+-ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int cookie, |
4051 |
+- bool tc_offload) |
4052 |
++ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, |
4053 |
++ unsigned long cookie, bool tc_offload) |
4054 |
+ { |
4055 |
+ struct ocelot_vcap_filter *filter; |
4056 |
+ |
4057 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c |
4058 |
+index ed817011a94a0..6924a6aacbd53 100644 |
4059 |
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c |
4060 |
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c |
4061 |
+@@ -21,6 +21,7 @@ |
4062 |
+ #include <linux/delay.h> |
4063 |
+ #include <linux/mfd/syscon.h> |
4064 |
+ #include <linux/regmap.h> |
4065 |
++#include <linux/pm_runtime.h> |
4066 |
+ |
4067 |
+ #include "stmmac_platform.h" |
4068 |
+ |
4069 |
+@@ -1528,6 +1529,8 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) |
4070 |
+ return ret; |
4071 |
+ } |
4072 |
+ |
4073 |
++ pm_runtime_get_sync(dev); |
4074 |
++ |
4075 |
+ if (bsp_priv->integrated_phy) |
4076 |
+ rk_gmac_integrated_phy_powerup(bsp_priv); |
4077 |
+ |
4078 |
+@@ -1539,6 +1542,8 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac) |
4079 |
+ if (gmac->integrated_phy) |
4080 |
+ rk_gmac_integrated_phy_powerdown(gmac); |
4081 |
+ |
4082 |
++ pm_runtime_put_sync(&gmac->pdev->dev); |
4083 |
++ |
4084 |
+ phy_power_on(gmac, false); |
4085 |
+ gmac_clk_enable(gmac, false); |
4086 |
+ } |
4087 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
4088 |
+index 86151a817b79a..6b2a5e5769e89 100644 |
4089 |
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
4090 |
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
4091 |
+@@ -477,6 +477,10 @@ bool stmmac_eee_init(struct stmmac_priv *priv) |
4092 |
+ stmmac_lpi_entry_timer_config(priv, 0); |
4093 |
+ del_timer_sync(&priv->eee_ctrl_timer); |
4094 |
+ stmmac_set_eee_timer(priv, priv->hw, 0, eee_tw_timer); |
4095 |
++ if (priv->hw->xpcs) |
4096 |
++ xpcs_config_eee(priv->hw->xpcs, |
4097 |
++ priv->plat->mult_fact_100ns, |
4098 |
++ false); |
4099 |
+ } |
4100 |
+ mutex_unlock(&priv->lock); |
4101 |
+ return false; |
4102 |
+@@ -1038,7 +1042,7 @@ static void stmmac_mac_link_down(struct phylink_config *config, |
4103 |
+ stmmac_mac_set(priv, priv->ioaddr, false); |
4104 |
+ priv->eee_active = false; |
4105 |
+ priv->tx_lpi_enabled = false; |
4106 |
+- stmmac_eee_init(priv); |
4107 |
++ priv->eee_enabled = stmmac_eee_init(priv); |
4108 |
+ stmmac_set_eee_pls(priv, priv->hw, false); |
4109 |
+ |
4110 |
+ if (priv->dma_cap.fpesel) |
4111 |
+diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c |
4112 |
+index 4bd61339823ce..d4ab03a92fb59 100644 |
4113 |
+--- a/drivers/net/pcs/pcs-xpcs.c |
4114 |
++++ b/drivers/net/pcs/pcs-xpcs.c |
4115 |
+@@ -662,6 +662,10 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) |
4116 |
+ { |
4117 |
+ int ret; |
4118 |
+ |
4119 |
++ ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0); |
4120 |
++ if (ret < 0) |
4121 |
++ return ret; |
4122 |
++ |
4123 |
+ if (enable) { |
4124 |
+ /* Enable EEE */ |
4125 |
+ ret = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | |
4126 |
+@@ -669,9 +673,6 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) |
4127 |
+ DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | |
4128 |
+ mult_fact_100ns << DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT; |
4129 |
+ } else { |
4130 |
+- ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0); |
4131 |
+- if (ret < 0) |
4132 |
+- return ret; |
4133 |
+ ret &= ~(DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | |
4134 |
+ DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN | |
4135 |
+ DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | |
4136 |
+@@ -686,21 +687,28 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) |
4137 |
+ if (ret < 0) |
4138 |
+ return ret; |
4139 |
+ |
4140 |
+- ret |= DW_VR_MII_EEE_TRN_LPI; |
4141 |
++ if (enable) |
4142 |
++ ret |= DW_VR_MII_EEE_TRN_LPI; |
4143 |
++ else |
4144 |
++ ret &= ~DW_VR_MII_EEE_TRN_LPI; |
4145 |
++ |
4146 |
+ return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret); |
4147 |
+ } |
4148 |
+ EXPORT_SYMBOL_GPL(xpcs_config_eee); |
4149 |
+ |
4150 |
+ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) |
4151 |
+ { |
4152 |
+- int ret; |
4153 |
++ int ret, mdio_ctrl; |
4154 |
+ |
4155 |
+ /* For AN for C37 SGMII mode, the settings are :- |
4156 |
+- * 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN) |
4157 |
+- * 2) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII) |
4158 |
++ * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case |
4159 |
++ it is already enabled) |
4160 |
++ * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN) |
4161 |
++ * 3) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII) |
4162 |
+ * DW xPCS used with DW EQoS MAC is always MAC side SGMII. |
4163 |
+- * 3) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic |
4164 |
++ * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic |
4165 |
+ * speed/duplex mode change by HW after SGMII AN complete) |
4166 |
++ * 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN) |
4167 |
+ * |
4168 |
+ * Note: Since it is MAC side SGMII, there is no need to set |
4169 |
+ * SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from |
4170 |
+@@ -708,6 +716,17 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) |
4171 |
+ * between PHY and Link Partner. There is also no need to |
4172 |
+ * trigger AN restart for MAC-side SGMII. |
4173 |
+ */ |
4174 |
++ mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL); |
4175 |
++ if (mdio_ctrl < 0) |
4176 |
++ return mdio_ctrl; |
4177 |
++ |
4178 |
++ if (mdio_ctrl & AN_CL37_EN) { |
4179 |
++ ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, |
4180 |
++ mdio_ctrl & ~AN_CL37_EN); |
4181 |
++ if (ret < 0) |
4182 |
++ return ret; |
4183 |
++ } |
4184 |
++ |
4185 |
+ ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL); |
4186 |
+ if (ret < 0) |
4187 |
+ return ret; |
4188 |
+@@ -732,7 +751,15 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) |
4189 |
+ else |
4190 |
+ ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; |
4191 |
+ |
4192 |
+- return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); |
4193 |
++ ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); |
4194 |
++ if (ret < 0) |
4195 |
++ return ret; |
4196 |
++ |
4197 |
++ if (phylink_autoneg_inband(mode)) |
4198 |
++ ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, |
4199 |
++ mdio_ctrl | AN_CL37_EN); |
4200 |
++ |
4201 |
++ return ret; |
4202 |
+ } |
4203 |
+ |
4204 |
+ static int xpcs_config_2500basex(struct dw_xpcs *xpcs) |
4205 |
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c |
4206 |
+index ee8313a4ac713..6865d9319197f 100644 |
4207 |
+--- a/drivers/net/phy/mdio_bus.c |
4208 |
++++ b/drivers/net/phy/mdio_bus.c |
4209 |
+@@ -538,6 +538,13 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner) |
4210 |
+ bus->dev.groups = NULL; |
4211 |
+ dev_set_name(&bus->dev, "%s", bus->id); |
4212 |
+ |
4213 |
++ /* We need to set state to MDIOBUS_UNREGISTERED to correctly release |
4214 |
++ * the device in mdiobus_free() |
4215 |
++ * |
4216 |
++ * State will be updated later in this function in case of success |
4217 |
++ */ |
4218 |
++ bus->state = MDIOBUS_UNREGISTERED; |
4219 |
++ |
4220 |
+ err = device_register(&bus->dev); |
4221 |
+ if (err) { |
4222 |
+ pr_err("mii_bus %s failed to register\n", bus->id); |
4223 |
+diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c |
4224 |
+index 34e90216bd2cb..ab77a9f439ef9 100644 |
4225 |
+--- a/drivers/net/phy/sfp.c |
4226 |
++++ b/drivers/net/phy/sfp.c |
4227 |
+@@ -134,7 +134,7 @@ static const char * const sm_state_strings[] = { |
4228 |
+ [SFP_S_LINK_UP] = "link_up", |
4229 |
+ [SFP_S_TX_FAULT] = "tx_fault", |
4230 |
+ [SFP_S_REINIT] = "reinit", |
4231 |
+- [SFP_S_TX_DISABLE] = "rx_disable", |
4232 |
++ [SFP_S_TX_DISABLE] = "tx_disable", |
4233 |
+ }; |
4234 |
+ |
4235 |
+ static const char *sm_state_to_str(unsigned short sm_state) |
4236 |
+diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig |
4237 |
+index f35cd8de228e4..6914b37bb0fbc 100644 |
4238 |
+--- a/drivers/net/wireless/ath/ath5k/Kconfig |
4239 |
++++ b/drivers/net/wireless/ath/ath5k/Kconfig |
4240 |
+@@ -3,9 +3,7 @@ config ATH5K |
4241 |
+ tristate "Atheros 5xxx wireless cards support" |
4242 |
+ depends on (PCI || ATH25) && MAC80211 |
4243 |
+ select ATH_COMMON |
4244 |
+- select MAC80211_LEDS |
4245 |
+- select LEDS_CLASS |
4246 |
+- select NEW_LEDS |
4247 |
++ select MAC80211_LEDS if LEDS_CLASS=y || LEDS_CLASS=MAC80211 |
4248 |
+ select ATH5K_AHB if ATH25 |
4249 |
+ select ATH5K_PCI if !ATH25 |
4250 |
+ help |
4251 |
+diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c |
4252 |
+index 6a2a168567630..33e9928af3635 100644 |
4253 |
+--- a/drivers/net/wireless/ath/ath5k/led.c |
4254 |
++++ b/drivers/net/wireless/ath/ath5k/led.c |
4255 |
+@@ -89,7 +89,8 @@ static const struct pci_device_id ath5k_led_devices[] = { |
4256 |
+ |
4257 |
+ void ath5k_led_enable(struct ath5k_hw *ah) |
4258 |
+ { |
4259 |
+- if (test_bit(ATH_STAT_LEDSOFT, ah->status)) { |
4260 |
++ if (IS_ENABLED(CONFIG_MAC80211_LEDS) && |
4261 |
++ test_bit(ATH_STAT_LEDSOFT, ah->status)) { |
4262 |
+ ath5k_hw_set_gpio_output(ah, ah->led_pin); |
4263 |
+ ath5k_led_off(ah); |
4264 |
+ } |
4265 |
+@@ -104,7 +105,8 @@ static void ath5k_led_on(struct ath5k_hw *ah) |
4266 |
+ |
4267 |
+ void ath5k_led_off(struct ath5k_hw *ah) |
4268 |
+ { |
4269 |
+- if (!test_bit(ATH_STAT_LEDSOFT, ah->status)) |
4270 |
++ if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || |
4271 |
++ !test_bit(ATH_STAT_LEDSOFT, ah->status)) |
4272 |
+ return; |
4273 |
+ ath5k_hw_set_gpio(ah, ah->led_pin, !ah->led_on); |
4274 |
+ } |
4275 |
+@@ -146,7 +148,7 @@ ath5k_register_led(struct ath5k_hw *ah, struct ath5k_led *led, |
4276 |
+ static void |
4277 |
+ ath5k_unregister_led(struct ath5k_led *led) |
4278 |
+ { |
4279 |
+- if (!led->ah) |
4280 |
++ if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !led->ah) |
4281 |
+ return; |
4282 |
+ led_classdev_unregister(&led->led_dev); |
4283 |
+ ath5k_led_off(led->ah); |
4284 |
+@@ -169,7 +171,7 @@ int ath5k_init_leds(struct ath5k_hw *ah) |
4285 |
+ char name[ATH5K_LED_MAX_NAME_LEN + 1]; |
4286 |
+ const struct pci_device_id *match; |
4287 |
+ |
4288 |
+- if (!ah->pdev) |
4289 |
++ if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !ah->pdev) |
4290 |
+ return 0; |
4291 |
+ |
4292 |
+ #ifdef CONFIG_ATH5K_AHB |
4293 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c |
4294 |
+index 24b658a3098aa..3ae727bc4e944 100644 |
4295 |
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c |
4296 |
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c |
4297 |
+@@ -652,12 +652,13 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm, |
4298 |
+ u32 *uid) |
4299 |
+ { |
4300 |
+ u32 id; |
4301 |
+- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); |
4302 |
++ struct iwl_mvm_vif *mvmvif; |
4303 |
+ enum nl80211_iftype iftype; |
4304 |
+ |
4305 |
+ if (!te_data->vif) |
4306 |
+ return false; |
4307 |
+ |
4308 |
++ mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); |
4309 |
+ iftype = te_data->vif->type; |
4310 |
+ |
4311 |
+ /* |
4312 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c |
4313 |
+index 6f49950a5f6d1..be3ad42813532 100644 |
4314 |
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c |
4315 |
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c |
4316 |
+@@ -547,6 +547,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { |
4317 |
+ IWL_DEV_INFO(0x43F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), |
4318 |
+ IWL_DEV_INFO(0x43F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), |
4319 |
+ IWL_DEV_INFO(0x43F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), |
4320 |
++ IWL_DEV_INFO(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650s_name), |
4321 |
++ IWL_DEV_INFO(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650i_name), |
4322 |
+ IWL_DEV_INFO(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), |
4323 |
+ IWL_DEV_INFO(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), |
4324 |
+ IWL_DEV_INFO(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), |
4325 |
+diff --git a/drivers/of/base.c b/drivers/of/base.c |
4326 |
+index 48e941f99558e..073ea7cd007bb 100644 |
4327 |
+--- a/drivers/of/base.c |
4328 |
++++ b/drivers/of/base.c |
4329 |
+@@ -36,6 +36,7 @@ LIST_HEAD(aliases_lookup); |
4330 |
+ struct device_node *of_root; |
4331 |
+ EXPORT_SYMBOL(of_root); |
4332 |
+ struct device_node *of_chosen; |
4333 |
++EXPORT_SYMBOL(of_chosen); |
4334 |
+ struct device_node *of_aliases; |
4335 |
+ struct device_node *of_stdout; |
4336 |
+ static const char *of_stdout_options; |
4337 |
+diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c |
4338 |
+index a53bd8728d0d3..fc1a29acadbbf 100644 |
4339 |
+--- a/drivers/pci/controller/pci-hyperv.c |
4340 |
++++ b/drivers/pci/controller/pci-hyperv.c |
4341 |
+@@ -3229,9 +3229,17 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs) |
4342 |
+ return 0; |
4343 |
+ |
4344 |
+ if (!keep_devs) { |
4345 |
+- /* Delete any children which might still exist. */ |
4346 |
++ struct list_head removed; |
4347 |
++ |
4348 |
++ /* Move all present children to the list on stack */ |
4349 |
++ INIT_LIST_HEAD(&removed); |
4350 |
+ spin_lock_irqsave(&hbus->device_list_lock, flags); |
4351 |
+- list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry) { |
4352 |
++ list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry) |
4353 |
++ list_move_tail(&hpdev->list_entry, &removed); |
4354 |
++ spin_unlock_irqrestore(&hbus->device_list_lock, flags); |
4355 |
++ |
4356 |
++ /* Remove all children in the list */ |
4357 |
++ list_for_each_entry_safe(hpdev, tmp, &removed, list_entry) { |
4358 |
+ list_del(&hpdev->list_entry); |
4359 |
+ if (hpdev->pci_slot) |
4360 |
+ pci_destroy_slot(hpdev->pci_slot); |
4361 |
+@@ -3239,7 +3247,6 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs) |
4362 |
+ put_pcichild(hpdev); |
4363 |
+ put_pcichild(hpdev); |
4364 |
+ } |
4365 |
+- spin_unlock_irqrestore(&hbus->device_list_lock, flags); |
4366 |
+ } |
4367 |
+ |
4368 |
+ ret = hv_send_resources_released(hdev); |
4369 |
+diff --git a/drivers/ptp/ptp_pch.c b/drivers/ptp/ptp_pch.c |
4370 |
+index a17e8cc642c5f..8070f3fd98f01 100644 |
4371 |
+--- a/drivers/ptp/ptp_pch.c |
4372 |
++++ b/drivers/ptp/ptp_pch.c |
4373 |
+@@ -644,6 +644,7 @@ static const struct pci_device_id pch_ieee1588_pcidev_id[] = { |
4374 |
+ }, |
4375 |
+ {0} |
4376 |
+ }; |
4377 |
++MODULE_DEVICE_TABLE(pci, pch_ieee1588_pcidev_id); |
4378 |
+ |
4379 |
+ static SIMPLE_DEV_PM_OPS(pch_pm_ops, pch_suspend, pch_resume); |
4380 |
+ |
4381 |
+diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c |
4382 |
+index 4683c183e9d41..5bc91d34df634 100644 |
4383 |
+--- a/drivers/scsi/libiscsi.c |
4384 |
++++ b/drivers/scsi/libiscsi.c |
4385 |
+@@ -2281,11 +2281,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) |
4386 |
+ return FAILED; |
4387 |
+ } |
4388 |
+ |
4389 |
+- conn = session->leadconn; |
4390 |
+- iscsi_get_conn(conn->cls_conn); |
4391 |
+- conn->eh_abort_cnt++; |
4392 |
+- age = session->age; |
4393 |
+- |
4394 |
+ spin_lock(&session->back_lock); |
4395 |
+ task = (struct iscsi_task *)sc->SCp.ptr; |
4396 |
+ if (!task || !task->sc) { |
4397 |
+@@ -2293,8 +2288,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) |
4398 |
+ ISCSI_DBG_EH(session, "sc completed while abort in progress\n"); |
4399 |
+ |
4400 |
+ spin_unlock(&session->back_lock); |
4401 |
+- goto success; |
4402 |
++ spin_unlock_bh(&session->frwd_lock); |
4403 |
++ mutex_unlock(&session->eh_mutex); |
4404 |
++ return SUCCESS; |
4405 |
+ } |
4406 |
++ |
4407 |
++ conn = session->leadconn; |
4408 |
++ iscsi_get_conn(conn->cls_conn); |
4409 |
++ conn->eh_abort_cnt++; |
4410 |
++ age = session->age; |
4411 |
++ |
4412 |
+ ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt); |
4413 |
+ __iscsi_get_task(task); |
4414 |
+ spin_unlock(&session->back_lock); |
4415 |
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c |
4416 |
+index a3f5af088122e..b073b514dcc48 100644 |
4417 |
+--- a/drivers/scsi/ufs/ufshcd.c |
4418 |
++++ b/drivers/scsi/ufs/ufshcd.c |
4419 |
+@@ -6365,27 +6365,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) |
4420 |
+ return retval; |
4421 |
+ } |
4422 |
+ |
4423 |
+-struct ctm_info { |
4424 |
+- struct ufs_hba *hba; |
4425 |
+- unsigned long pending; |
4426 |
+- unsigned int ncpl; |
4427 |
+-}; |
4428 |
+- |
4429 |
+-static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved) |
4430 |
+-{ |
4431 |
+- struct ctm_info *const ci = priv; |
4432 |
+- struct completion *c; |
4433 |
+- |
4434 |
+- WARN_ON_ONCE(reserved); |
4435 |
+- if (test_bit(req->tag, &ci->pending)) |
4436 |
+- return true; |
4437 |
+- ci->ncpl++; |
4438 |
+- c = req->end_io_data; |
4439 |
+- if (c) |
4440 |
+- complete(c); |
4441 |
+- return true; |
4442 |
+-} |
4443 |
+- |
4444 |
+ /** |
4445 |
+ * ufshcd_tmc_handler - handle task management function completion |
4446 |
+ * @hba: per adapter instance |
4447 |
+@@ -6396,18 +6375,24 @@ static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved) |
4448 |
+ */ |
4449 |
+ static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) |
4450 |
+ { |
4451 |
+- unsigned long flags; |
4452 |
+- struct request_queue *q = hba->tmf_queue; |
4453 |
+- struct ctm_info ci = { |
4454 |
+- .hba = hba, |
4455 |
+- }; |
4456 |
++ unsigned long flags, pending, issued; |
4457 |
++ irqreturn_t ret = IRQ_NONE; |
4458 |
++ int tag; |
4459 |
++ |
4460 |
++ pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); |
4461 |
+ |
4462 |
+ spin_lock_irqsave(hba->host->host_lock, flags); |
4463 |
+- ci.pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); |
4464 |
+- blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci); |
4465 |
++ issued = hba->outstanding_tasks & ~pending; |
4466 |
++ for_each_set_bit(tag, &issued, hba->nutmrs) { |
4467 |
++ struct request *req = hba->tmf_rqs[tag]; |
4468 |
++ struct completion *c = req->end_io_data; |
4469 |
++ |
4470 |
++ complete(c); |
4471 |
++ ret = IRQ_HANDLED; |
4472 |
++ } |
4473 |
+ spin_unlock_irqrestore(hba->host->host_lock, flags); |
4474 |
+ |
4475 |
+- return ci.ncpl ? IRQ_HANDLED : IRQ_NONE; |
4476 |
++ return ret; |
4477 |
+ } |
4478 |
+ |
4479 |
+ /** |
4480 |
+@@ -6530,9 +6515,9 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, |
4481 |
+ ufshcd_hold(hba, false); |
4482 |
+ |
4483 |
+ spin_lock_irqsave(host->host_lock, flags); |
4484 |
+- blk_mq_start_request(req); |
4485 |
+ |
4486 |
+ task_tag = req->tag; |
4487 |
++ hba->tmf_rqs[req->tag] = req; |
4488 |
+ treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag); |
4489 |
+ |
4490 |
+ memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq)); |
4491 |
+@@ -6576,6 +6561,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, |
4492 |
+ } |
4493 |
+ |
4494 |
+ spin_lock_irqsave(hba->host->host_lock, flags); |
4495 |
++ hba->tmf_rqs[req->tag] = NULL; |
4496 |
+ __clear_bit(task_tag, &hba->outstanding_tasks); |
4497 |
+ spin_unlock_irqrestore(hba->host->host_lock, flags); |
4498 |
+ |
4499 |
+@@ -9568,6 +9554,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) |
4500 |
+ err = PTR_ERR(hba->tmf_queue); |
4501 |
+ goto free_tmf_tag_set; |
4502 |
+ } |
4503 |
++ hba->tmf_rqs = devm_kcalloc(hba->dev, hba->nutmrs, |
4504 |
++ sizeof(*hba->tmf_rqs), GFP_KERNEL); |
4505 |
++ if (!hba->tmf_rqs) { |
4506 |
++ err = -ENOMEM; |
4507 |
++ goto free_tmf_queue; |
4508 |
++ } |
4509 |
+ |
4510 |
+ /* Reset the attached device */ |
4511 |
+ ufshcd_device_reset(hba); |
4512 |
+diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h |
4513 |
+index aa95deffb873a..6069e37ec983c 100644 |
4514 |
+--- a/drivers/scsi/ufs/ufshcd.h |
4515 |
++++ b/drivers/scsi/ufs/ufshcd.h |
4516 |
+@@ -780,6 +780,7 @@ struct ufs_hba { |
4517 |
+ |
4518 |
+ struct blk_mq_tag_set tmf_tag_set; |
4519 |
+ struct request_queue *tmf_queue; |
4520 |
++ struct request **tmf_rqs; |
4521 |
+ |
4522 |
+ struct uic_command *active_uic_cmd; |
4523 |
+ struct mutex uic_cmd_mutex; |
4524 |
+diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c |
4525 |
+index eba7f76f9d61a..6034cd8992b0e 100644 |
4526 |
+--- a/drivers/soc/qcom/mdt_loader.c |
4527 |
++++ b/drivers/soc/qcom/mdt_loader.c |
4528 |
+@@ -98,7 +98,7 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len) |
4529 |
+ if (ehdr->e_phnum < 2) |
4530 |
+ return ERR_PTR(-EINVAL); |
4531 |
+ |
4532 |
+- if (phdrs[0].p_type == PT_LOAD || phdrs[1].p_type == PT_LOAD) |
4533 |
++ if (phdrs[0].p_type == PT_LOAD) |
4534 |
+ return ERR_PTR(-EINVAL); |
4535 |
+ |
4536 |
+ if ((phdrs[1].p_flags & QCOM_MDT_TYPE_MASK) != QCOM_MDT_TYPE_HASH) |
4537 |
+diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c |
4538 |
+index b2f049faa3dfa..a6cffd57d3c7b 100644 |
4539 |
+--- a/drivers/soc/qcom/socinfo.c |
4540 |
++++ b/drivers/soc/qcom/socinfo.c |
4541 |
+@@ -628,7 +628,7 @@ static int qcom_socinfo_probe(struct platform_device *pdev) |
4542 |
+ /* Feed the soc specific unique data into entropy pool */ |
4543 |
+ add_device_randomness(info, item_size); |
4544 |
+ |
4545 |
+- platform_set_drvdata(pdev, qs->soc_dev); |
4546 |
++ platform_set_drvdata(pdev, qs); |
4547 |
+ |
4548 |
+ return 0; |
4549 |
+ } |
4550 |
+diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c |
4551 |
+index ea64e187854eb..f32e1cbbe8c52 100644 |
4552 |
+--- a/drivers/soc/ti/omap_prm.c |
4553 |
++++ b/drivers/soc/ti/omap_prm.c |
4554 |
+@@ -825,25 +825,28 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev, |
4555 |
+ writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl); |
4556 |
+ spin_unlock_irqrestore(&reset->lock, flags); |
4557 |
+ |
4558 |
+- if (!has_rstst) |
4559 |
+- goto exit; |
4560 |
++ /* wait for the reset bit to clear */ |
4561 |
++ ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + |
4562 |
++ reset->prm->data->rstctrl, |
4563 |
++ v, !(v & BIT(id)), 1, |
4564 |
++ OMAP_RESET_MAX_WAIT); |
4565 |
++ if (ret) |
4566 |
++ pr_err("%s: timedout waiting for %s:%lu\n", __func__, |
4567 |
++ reset->prm->data->name, id); |
4568 |
+ |
4569 |
+ /* wait for the status to be set */ |
4570 |
+- ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + |
4571 |
++ if (has_rstst) { |
4572 |
++ ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + |
4573 |
+ reset->prm->data->rstst, |
4574 |
+ v, v & BIT(st_bit), 1, |
4575 |
+ OMAP_RESET_MAX_WAIT); |
4576 |
+- if (ret) |
4577 |
+- pr_err("%s: timedout waiting for %s:%lu\n", __func__, |
4578 |
+- reset->prm->data->name, id); |
4579 |
++ if (ret) |
4580 |
++ pr_err("%s: timedout waiting for %s:%lu\n", __func__, |
4581 |
++ reset->prm->data->name, id); |
4582 |
++ } |
4583 |
+ |
4584 |
+-exit: |
4585 |
+- if (reset->clkdm) { |
4586 |
+- /* At least dra7 iva needs a delay before clkdm idle */ |
4587 |
+- if (has_rstst) |
4588 |
+- udelay(1); |
4589 |
++ if (reset->clkdm) |
4590 |
+ pdata->clkdm_allow_idle(reset->clkdm); |
4591 |
+- } |
4592 |
+ |
4593 |
+ return ret; |
4594 |
+ } |
4595 |
+diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c |
4596 |
+index 8b7bc10b6e8b4..f1d100671ee6a 100644 |
4597 |
+--- a/drivers/usb/chipidea/ci_hdrc_imx.c |
4598 |
++++ b/drivers/usb/chipidea/ci_hdrc_imx.c |
4599 |
+@@ -420,11 +420,16 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) |
4600 |
+ data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0); |
4601 |
+ if (IS_ERR(data->phy)) { |
4602 |
+ ret = PTR_ERR(data->phy); |
4603 |
+- /* Return -EINVAL if no usbphy is available */ |
4604 |
+- if (ret == -ENODEV) |
4605 |
+- data->phy = NULL; |
4606 |
+- else |
4607 |
+- goto err_clk; |
4608 |
++ if (ret == -ENODEV) { |
4609 |
++ data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0); |
4610 |
++ if (IS_ERR(data->phy)) { |
4611 |
++ ret = PTR_ERR(data->phy); |
4612 |
++ if (ret == -ENODEV) |
4613 |
++ data->phy = NULL; |
4614 |
++ else |
4615 |
++ goto err_clk; |
4616 |
++ } |
4617 |
++ } |
4618 |
+ } |
4619 |
+ |
4620 |
+ pdata.usb_phy = data->phy; |
4621 |
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c |
4622 |
+index 5b90d0979c607..8913c58c306ef 100644 |
4623 |
+--- a/drivers/usb/class/cdc-acm.c |
4624 |
++++ b/drivers/usb/class/cdc-acm.c |
4625 |
+@@ -340,6 +340,9 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf) |
4626 |
+ acm->iocount.overrun++; |
4627 |
+ spin_unlock_irqrestore(&acm->read_lock, flags); |
4628 |
+ |
4629 |
++ if (newctrl & ACM_CTRL_BRK) |
4630 |
++ tty_flip_buffer_push(&acm->port); |
4631 |
++ |
4632 |
+ if (difference) |
4633 |
+ wake_up_all(&acm->wioctl); |
4634 |
+ |
4635 |
+@@ -475,11 +478,16 @@ static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags) |
4636 |
+ |
4637 |
+ static void acm_process_read_urb(struct acm *acm, struct urb *urb) |
4638 |
+ { |
4639 |
++ unsigned long flags; |
4640 |
++ |
4641 |
+ if (!urb->actual_length) |
4642 |
+ return; |
4643 |
+ |
4644 |
++ spin_lock_irqsave(&acm->read_lock, flags); |
4645 |
+ tty_insert_flip_string(&acm->port, urb->transfer_buffer, |
4646 |
+ urb->actual_length); |
4647 |
++ spin_unlock_irqrestore(&acm->read_lock, flags); |
4648 |
++ |
4649 |
+ tty_flip_buffer_push(&acm->port); |
4650 |
+ } |
4651 |
+ |
4652 |
+diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c |
4653 |
+index 35d5908b5478a..fdf79bcf7eb09 100644 |
4654 |
+--- a/drivers/usb/class/cdc-wdm.c |
4655 |
++++ b/drivers/usb/class/cdc-wdm.c |
4656 |
+@@ -824,7 +824,7 @@ static struct usb_class_driver wdm_class = { |
4657 |
+ }; |
4658 |
+ |
4659 |
+ /* --- WWAN framework integration --- */ |
4660 |
+-#ifdef CONFIG_WWAN_CORE |
4661 |
++#ifdef CONFIG_WWAN |
4662 |
+ static int wdm_wwan_port_start(struct wwan_port *port) |
4663 |
+ { |
4664 |
+ struct wdm_device *desc = wwan_port_get_drvdata(port); |
4665 |
+@@ -963,11 +963,11 @@ static void wdm_wwan_rx(struct wdm_device *desc, int length) |
4666 |
+ /* inbuf has been copied, it is safe to check for outstanding data */ |
4667 |
+ schedule_work(&desc->service_outs_intr); |
4668 |
+ } |
4669 |
+-#else /* CONFIG_WWAN_CORE */ |
4670 |
++#else /* CONFIG_WWAN */ |
4671 |
+ static void wdm_wwan_init(struct wdm_device *desc) {} |
4672 |
+ static void wdm_wwan_deinit(struct wdm_device *desc) {} |
4673 |
+ static void wdm_wwan_rx(struct wdm_device *desc, int length) {} |
4674 |
+-#endif /* CONFIG_WWAN_CORE */ |
4675 |
++#endif /* CONFIG_WWAN */ |
4676 |
+ |
4677 |
+ /* --- error handling --- */ |
4678 |
+ static void wdm_rxwork(struct work_struct *work) |
4679 |
+diff --git a/drivers/usb/common/Kconfig b/drivers/usb/common/Kconfig |
4680 |
+index 5e8a04e3dd3c8..b856622431a73 100644 |
4681 |
+--- a/drivers/usb/common/Kconfig |
4682 |
++++ b/drivers/usb/common/Kconfig |
4683 |
+@@ -6,8 +6,7 @@ config USB_COMMON |
4684 |
+ |
4685 |
+ config USB_LED_TRIG |
4686 |
+ bool "USB LED Triggers" |
4687 |
+- depends on LEDS_CLASS && LEDS_TRIGGERS |
4688 |
+- select USB_COMMON |
4689 |
++ depends on LEDS_CLASS && USB_COMMON && LEDS_TRIGGERS |
4690 |
+ help |
4691 |
+ This option adds LED triggers for USB host and/or gadget activity. |
4692 |
+ |
4693 |
+diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c |
4694 |
+index 37c94031af1ed..53cb6b2637a09 100644 |
4695 |
+--- a/drivers/usb/gadget/function/f_uac2.c |
4696 |
++++ b/drivers/usb/gadget/function/f_uac2.c |
4697 |
+@@ -593,11 +593,17 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, |
4698 |
+ ssize = uac2_opts->c_ssize; |
4699 |
+ } |
4700 |
+ |
4701 |
+- if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC)) |
4702 |
++ if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC)) { |
4703 |
++ // Win10 requires max packet size + 1 frame |
4704 |
+ srate = srate * (1000 + uac2_opts->fb_max) / 1000; |
4705 |
+- |
4706 |
+- max_size_bw = num_channels(chmask) * ssize * |
4707 |
+- DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); |
4708 |
++ // updated srate is always bigger, therefore DIV_ROUND_UP always yields +1 |
4709 |
++ max_size_bw = num_channels(chmask) * ssize * |
4710 |
++ (DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)))); |
4711 |
++ } else { |
4712 |
++ // adding 1 frame provision for Win10 |
4713 |
++ max_size_bw = num_channels(chmask) * ssize * |
4714 |
++ (DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))) + 1); |
4715 |
++ } |
4716 |
+ ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, |
4717 |
+ max_size_ep)); |
4718 |
+ |
4719 |
+diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c |
4720 |
+index 9858716698dfe..c15eec9cc460a 100644 |
4721 |
+--- a/drivers/usb/typec/tcpm/tcpci.c |
4722 |
++++ b/drivers/usb/typec/tcpm/tcpci.c |
4723 |
+@@ -696,7 +696,7 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci) |
4724 |
+ tcpm_pd_receive(tcpci->port, &msg); |
4725 |
+ } |
4726 |
+ |
4727 |
+- if (status & TCPC_ALERT_EXTENDED_STATUS) { |
4728 |
++ if (tcpci->data->vbus_vsafe0v && (status & TCPC_ALERT_EXTENDED_STATUS)) { |
4729 |
+ ret = regmap_read(tcpci->regmap, TCPC_EXTENDED_STATUS, &raw); |
4730 |
+ if (!ret && (raw & TCPC_EXTENDED_STATUS_VSAFE0V)) |
4731 |
+ tcpm_vbus_change(tcpci->port); |
4732 |
+diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c |
4733 |
+index 5d05de6665974..686b9245d6d67 100644 |
4734 |
+--- a/drivers/usb/typec/tcpm/tcpm.c |
4735 |
++++ b/drivers/usb/typec/tcpm/tcpm.c |
4736 |
+@@ -4846,6 +4846,7 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, |
4737 |
+ tcpm_set_state(port, SRC_ATTACH_WAIT, 0); |
4738 |
+ break; |
4739 |
+ case SRC_ATTACHED: |
4740 |
++ case SRC_STARTUP: |
4741 |
+ case SRC_SEND_CAPABILITIES: |
4742 |
+ case SRC_READY: |
4743 |
+ if (tcpm_port_is_disconnected(port) || |
4744 |
+diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c |
4745 |
+index 21b3ae25c76d2..ea4cc0a6e40cc 100644 |
4746 |
+--- a/drivers/usb/typec/tipd/core.c |
4747 |
++++ b/drivers/usb/typec/tipd/core.c |
4748 |
+@@ -625,10 +625,6 @@ static int tps6598x_probe(struct i2c_client *client) |
4749 |
+ if (ret < 0) |
4750 |
+ return ret; |
4751 |
+ |
4752 |
+- fwnode = device_get_named_child_node(&client->dev, "connector"); |
4753 |
+- if (!fwnode) |
4754 |
+- return -ENODEV; |
4755 |
+- |
4756 |
+ /* |
4757 |
+ * This fwnode has a "compatible" property, but is never populated as a |
4758 |
+ * struct device. Instead we simply parse it to read the properties. |
4759 |
+@@ -636,7 +632,9 @@ static int tps6598x_probe(struct i2c_client *client) |
4760 |
+ * with existing DT files, we work around this by deleting any |
4761 |
+ * fwnode_links to/from this fwnode. |
4762 |
+ */ |
4763 |
+- fw_devlink_purge_absent_suppliers(fwnode); |
4764 |
++ fwnode = device_get_named_child_node(&client->dev, "connector"); |
4765 |
++ if (fwnode) |
4766 |
++ fw_devlink_purge_absent_suppliers(fwnode); |
4767 |
+ |
4768 |
+ tps->role_sw = fwnode_usb_role_switch_get(fwnode); |
4769 |
+ if (IS_ERR(tps->role_sw)) { |
4770 |
+diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig |
4771 |
+index d33c5cd684c0b..f71668367caf1 100644 |
4772 |
+--- a/drivers/video/fbdev/Kconfig |
4773 |
++++ b/drivers/video/fbdev/Kconfig |
4774 |
+@@ -2191,8 +2191,9 @@ config FB_HYPERV |
4775 |
+ This framebuffer driver supports Microsoft Hyper-V Synthetic Video. |
4776 |
+ |
4777 |
+ config FB_SIMPLE |
4778 |
+- bool "Simple framebuffer support" |
4779 |
+- depends on (FB = y) && !DRM_SIMPLEDRM |
4780 |
++ tristate "Simple framebuffer support" |
4781 |
++ depends on FB |
4782 |
++ depends on !DRM_SIMPLEDRM |
4783 |
+ select FB_CFB_FILLRECT |
4784 |
+ select FB_CFB_COPYAREA |
4785 |
+ select FB_CFB_IMAGEBLIT |
4786 |
+diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c |
4787 |
+index c5b99a4861e87..6b4d5a7f3e152 100644 |
4788 |
+--- a/drivers/video/fbdev/gbefb.c |
4789 |
++++ b/drivers/video/fbdev/gbefb.c |
4790 |
+@@ -1267,7 +1267,7 @@ static struct platform_device *gbefb_device; |
4791 |
+ static int __init gbefb_init(void) |
4792 |
+ { |
4793 |
+ int ret = platform_driver_register(&gbefb_driver); |
4794 |
+- if (!ret) { |
4795 |
++ if (IS_ENABLED(CONFIG_SGI_IP32) && !ret) { |
4796 |
+ gbefb_device = platform_device_alloc("gbefb", 0); |
4797 |
+ if (gbefb_device) { |
4798 |
+ ret = platform_device_add(gbefb_device); |
4799 |
+diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c |
4800 |
+index 43ebfe36ac276..3a50f097ed3ed 100644 |
4801 |
+--- a/drivers/xen/balloon.c |
4802 |
++++ b/drivers/xen/balloon.c |
4803 |
+@@ -491,12 +491,12 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) |
4804 |
+ } |
4805 |
+ |
4806 |
+ /* |
4807 |
+- * Stop waiting if either state is not BP_EAGAIN and ballooning action is |
4808 |
+- * needed, or if the credit has changed while state is BP_EAGAIN. |
4809 |
++ * Stop waiting if either state is BP_DONE and ballooning action is |
4810 |
++ * needed, or if the credit has changed while state is not BP_DONE. |
4811 |
+ */ |
4812 |
+ static bool balloon_thread_cond(enum bp_state state, long credit) |
4813 |
+ { |
4814 |
+- if (state != BP_EAGAIN) |
4815 |
++ if (state == BP_DONE) |
4816 |
+ credit = 0; |
4817 |
+ |
4818 |
+ return current_credit() != credit || kthread_should_stop(); |
4819 |
+@@ -516,10 +516,19 @@ static int balloon_thread(void *unused) |
4820 |
+ |
4821 |
+ set_freezable(); |
4822 |
+ for (;;) { |
4823 |
+- if (state == BP_EAGAIN) |
4824 |
+- timeout = balloon_stats.schedule_delay * HZ; |
4825 |
+- else |
4826 |
++ switch (state) { |
4827 |
++ case BP_DONE: |
4828 |
++ case BP_ECANCELED: |
4829 |
+ timeout = 3600 * HZ; |
4830 |
++ break; |
4831 |
++ case BP_EAGAIN: |
4832 |
++ timeout = balloon_stats.schedule_delay * HZ; |
4833 |
++ break; |
4834 |
++ case BP_WAIT: |
4835 |
++ timeout = HZ; |
4836 |
++ break; |
4837 |
++ } |
4838 |
++ |
4839 |
+ credit = current_credit(); |
4840 |
+ |
4841 |
+ wait_event_freezable_timeout(balloon_thread_wq, |
4842 |
+diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c |
4843 |
+index 720a7b7abd46d..fe8df32bb612b 100644 |
4844 |
+--- a/drivers/xen/privcmd.c |
4845 |
++++ b/drivers/xen/privcmd.c |
4846 |
+@@ -803,11 +803,12 @@ static long privcmd_ioctl_mmap_resource(struct file *file, |
4847 |
+ unsigned int domid = |
4848 |
+ (xdata.flags & XENMEM_rsrc_acq_caller_owned) ? |
4849 |
+ DOMID_SELF : kdata.dom; |
4850 |
+- int num; |
4851 |
++ int num, *errs = (int *)pfns; |
4852 |
+ |
4853 |
++ BUILD_BUG_ON(sizeof(*errs) > sizeof(*pfns)); |
4854 |
+ num = xen_remap_domain_mfn_array(vma, |
4855 |
+ kdata.addr & PAGE_MASK, |
4856 |
+- pfns, kdata.num, (int *)pfns, |
4857 |
++ pfns, kdata.num, errs, |
4858 |
+ vma->vm_page_prot, |
4859 |
+ domid, |
4860 |
+ vma->vm_private_data); |
4861 |
+@@ -817,7 +818,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file, |
4862 |
+ unsigned int i; |
4863 |
+ |
4864 |
+ for (i = 0; i < num; i++) { |
4865 |
+- rc = pfns[i]; |
4866 |
++ rc = errs[i]; |
4867 |
+ if (rc < 0) |
4868 |
+ break; |
4869 |
+ } |
4870 |
+diff --git a/fs/afs/write.c b/fs/afs/write.c |
4871 |
+index 2dfe3b3a53d69..f24370f5c7744 100644 |
4872 |
+--- a/fs/afs/write.c |
4873 |
++++ b/fs/afs/write.c |
4874 |
+@@ -974,8 +974,7 @@ int afs_launder_page(struct page *page) |
4875 |
+ iov_iter_bvec(&iter, WRITE, bv, 1, bv[0].bv_len); |
4876 |
+ |
4877 |
+ trace_afs_page_dirty(vnode, tracepoint_string("launder"), page); |
4878 |
+- ret = afs_store_data(vnode, &iter, (loff_t)page->index * PAGE_SIZE, |
4879 |
+- true); |
4880 |
++ ret = afs_store_data(vnode, &iter, page_offset(page) + f, true); |
4881 |
+ } |
4882 |
+ |
4883 |
+ trace_afs_page_dirty(vnode, tracepoint_string("laundered"), page); |
4884 |
+diff --git a/fs/netfs/read_helper.c b/fs/netfs/read_helper.c |
4885 |
+index 0b6cd3b8734c6..994ec22d40402 100644 |
4886 |
+--- a/fs/netfs/read_helper.c |
4887 |
++++ b/fs/netfs/read_helper.c |
4888 |
+@@ -150,7 +150,7 @@ static void netfs_clear_unread(struct netfs_read_subrequest *subreq) |
4889 |
+ { |
4890 |
+ struct iov_iter iter; |
4891 |
+ |
4892 |
+- iov_iter_xarray(&iter, WRITE, &subreq->rreq->mapping->i_pages, |
4893 |
++ iov_iter_xarray(&iter, READ, &subreq->rreq->mapping->i_pages, |
4894 |
+ subreq->start + subreq->transferred, |
4895 |
+ subreq->len - subreq->transferred); |
4896 |
+ iov_iter_zero(iov_iter_count(&iter), &iter); |
4897 |
+diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c |
4898 |
+index 7abeccb975b22..cf030ebe28275 100644 |
4899 |
+--- a/fs/nfsd/nfs4xdr.c |
4900 |
++++ b/fs/nfsd/nfs4xdr.c |
4901 |
+@@ -3544,15 +3544,18 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, |
4902 |
+ goto fail; |
4903 |
+ cd->rd_maxcount -= entry_bytes; |
4904 |
+ /* |
4905 |
+- * RFC 3530 14.2.24 describes rd_dircount as only a "hint", so |
4906 |
+- * let's always let through the first entry, at least: |
4907 |
++ * RFC 3530 14.2.24 describes rd_dircount as only a "hint", and |
4908 |
++ * notes that it could be zero. If it is zero, then the server |
4909 |
++ * should enforce only the rd_maxcount value. |
4910 |
+ */ |
4911 |
+- if (!cd->rd_dircount) |
4912 |
+- goto fail; |
4913 |
+- name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8; |
4914 |
+- if (name_and_cookie > cd->rd_dircount && cd->cookie_offset) |
4915 |
+- goto fail; |
4916 |
+- cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie); |
4917 |
++ if (cd->rd_dircount) { |
4918 |
++ name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8; |
4919 |
++ if (name_and_cookie > cd->rd_dircount && cd->cookie_offset) |
4920 |
++ goto fail; |
4921 |
++ cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie); |
4922 |
++ if (!cd->rd_dircount) |
4923 |
++ cd->rd_maxcount = 0; |
4924 |
++ } |
4925 |
+ |
4926 |
+ cd->cookie_offset = cookie_offset; |
4927 |
+ skip_entry: |
4928 |
+diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c |
4929 |
+index c2c3d9077dc58..09ae1a0873d05 100644 |
4930 |
+--- a/fs/nfsd/nfsctl.c |
4931 |
++++ b/fs/nfsd/nfsctl.c |
4932 |
+@@ -1545,7 +1545,7 @@ static int __init init_nfsd(void) |
4933 |
+ goto out_free_all; |
4934 |
+ return 0; |
4935 |
+ out_free_all: |
4936 |
+- unregister_pernet_subsys(&nfsd_net_ops); |
4937 |
++ unregister_filesystem(&nfsd_fs_type); |
4938 |
+ out_free_exports: |
4939 |
+ remove_proc_entry("fs/nfs/exports", NULL); |
4940 |
+ remove_proc_entry("fs/nfs", NULL); |
4941 |
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c |
4942 |
+index 7c1850adec288..a4ad25f1f797f 100644 |
4943 |
+--- a/fs/overlayfs/dir.c |
4944 |
++++ b/fs/overlayfs/dir.c |
4945 |
+@@ -1215,9 +1215,13 @@ static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir, |
4946 |
+ goto out_dput; |
4947 |
+ } |
4948 |
+ } else { |
4949 |
+- if (!d_is_negative(newdentry) && |
4950 |
+- (!new_opaque || !ovl_is_whiteout(newdentry))) |
4951 |
+- goto out_dput; |
4952 |
++ if (!d_is_negative(newdentry)) { |
4953 |
++ if (!new_opaque || !ovl_is_whiteout(newdentry)) |
4954 |
++ goto out_dput; |
4955 |
++ } else { |
4956 |
++ if (flags & RENAME_EXCHANGE) |
4957 |
++ goto out_dput; |
4958 |
++ } |
4959 |
+ } |
4960 |
+ |
4961 |
+ if (olddentry == trap) |
4962 |
+diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c |
4963 |
+index d081faa55e830..c88ac571593dc 100644 |
4964 |
+--- a/fs/overlayfs/file.c |
4965 |
++++ b/fs/overlayfs/file.c |
4966 |
+@@ -296,6 +296,12 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter) |
4967 |
+ if (ret) |
4968 |
+ return ret; |
4969 |
+ |
4970 |
++ ret = -EINVAL; |
4971 |
++ if (iocb->ki_flags & IOCB_DIRECT && |
4972 |
++ (!real.file->f_mapping->a_ops || |
4973 |
++ !real.file->f_mapping->a_ops->direct_IO)) |
4974 |
++ goto out_fdput; |
4975 |
++ |
4976 |
+ old_cred = ovl_override_creds(file_inode(file)->i_sb); |
4977 |
+ if (is_sync_kiocb(iocb)) { |
4978 |
+ ret = vfs_iter_read(real.file, iter, &iocb->ki_pos, |
4979 |
+@@ -320,7 +326,7 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter) |
4980 |
+ out: |
4981 |
+ revert_creds(old_cred); |
4982 |
+ ovl_file_accessed(file); |
4983 |
+- |
4984 |
++out_fdput: |
4985 |
+ fdput(real); |
4986 |
+ |
4987 |
+ return ret; |
4988 |
+@@ -349,6 +355,12 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) |
4989 |
+ if (ret) |
4990 |
+ goto out_unlock; |
4991 |
+ |
4992 |
++ ret = -EINVAL; |
4993 |
++ if (iocb->ki_flags & IOCB_DIRECT && |
4994 |
++ (!real.file->f_mapping->a_ops || |
4995 |
++ !real.file->f_mapping->a_ops->direct_IO)) |
4996 |
++ goto out_fdput; |
4997 |
++ |
4998 |
+ if (!ovl_should_sync(OVL_FS(inode->i_sb))) |
4999 |
+ ifl &= ~(IOCB_DSYNC | IOCB_SYNC); |
5000 |
+ |
5001 |
+@@ -384,6 +396,7 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) |
5002 |
+ } |
5003 |
+ out: |
5004 |
+ revert_creds(old_cred); |
5005 |
++out_fdput: |
5006 |
+ fdput(real); |
5007 |
+ |
5008 |
+ out_unlock: |
5009 |
+diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h |
5010 |
+index 0fd8a4159662d..ceadf8ba25a44 100644 |
5011 |
+--- a/include/net/netfilter/ipv6/nf_defrag_ipv6.h |
5012 |
++++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h |
5013 |
+@@ -17,7 +17,6 @@ struct inet_frags_ctl; |
5014 |
+ struct nft_ct_frag6_pernet { |
5015 |
+ struct ctl_table_header *nf_frag_frags_hdr; |
5016 |
+ struct fqdir *fqdir; |
5017 |
+- unsigned int users; |
5018 |
+ }; |
5019 |
+ |
5020 |
+ #endif /* _NF_DEFRAG_IPV6_H */ |
5021 |
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h |
5022 |
+index 148f5d8ee5ab3..a16171c5fd9eb 100644 |
5023 |
+--- a/include/net/netfilter/nf_tables.h |
5024 |
++++ b/include/net/netfilter/nf_tables.h |
5025 |
+@@ -1202,7 +1202,7 @@ struct nft_object *nft_obj_lookup(const struct net *net, |
5026 |
+ |
5027 |
+ void nft_obj_notify(struct net *net, const struct nft_table *table, |
5028 |
+ struct nft_object *obj, u32 portid, u32 seq, |
5029 |
+- int event, int family, int report, gfp_t gfp); |
5030 |
++ int event, u16 flags, int family, int report, gfp_t gfp); |
5031 |
+ |
5032 |
+ /** |
5033 |
+ * struct nft_object_type - stateful object type |
5034 |
+diff --git a/include/net/netns/netfilter.h b/include/net/netns/netfilter.h |
5035 |
+index 15e2b13fb0c0f..71343b969cd31 100644 |
5036 |
+--- a/include/net/netns/netfilter.h |
5037 |
++++ b/include/net/netns/netfilter.h |
5038 |
+@@ -28,5 +28,11 @@ struct netns_nf { |
5039 |
+ #if IS_ENABLED(CONFIG_DECNET) |
5040 |
+ struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS]; |
5041 |
+ #endif |
5042 |
++#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) |
5043 |
++ unsigned int defrag_ipv4_users; |
5044 |
++#endif |
5045 |
++#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) |
5046 |
++ unsigned int defrag_ipv6_users; |
5047 |
++#endif |
5048 |
+ }; |
5049 |
+ #endif |
5050 |
+diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h |
5051 |
+index 25fd525aaf928..4869ebbd438d9 100644 |
5052 |
+--- a/include/soc/mscc/ocelot_vcap.h |
5053 |
++++ b/include/soc/mscc/ocelot_vcap.h |
5054 |
+@@ -694,7 +694,7 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot, |
5055 |
+ int ocelot_vcap_filter_del(struct ocelot *ocelot, |
5056 |
+ struct ocelot_vcap_filter *rule); |
5057 |
+ struct ocelot_vcap_filter * |
5058 |
+-ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int id, |
5059 |
+- bool tc_offload); |
5060 |
++ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, |
5061 |
++ unsigned long cookie, bool tc_offload); |
5062 |
+ |
5063 |
+ #endif /* _OCELOT_VCAP_H_ */ |
5064 |
+diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c |
5065 |
+index 6fbc2abe9c916..2553caf4f74a3 100644 |
5066 |
+--- a/kernel/bpf/stackmap.c |
5067 |
++++ b/kernel/bpf/stackmap.c |
5068 |
+@@ -63,7 +63,8 @@ static inline int stack_map_data_size(struct bpf_map *map) |
5069 |
+ |
5070 |
+ static int prealloc_elems_and_freelist(struct bpf_stack_map *smap) |
5071 |
+ { |
5072 |
+- u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size; |
5073 |
++ u64 elem_size = sizeof(struct stack_map_bucket) + |
5074 |
++ (u64)smap->map.value_size; |
5075 |
+ int err; |
5076 |
+ |
5077 |
+ smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries, |
5078 |
+diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c |
5079 |
+index 8642e56059fb2..2abfbd4b8a15e 100644 |
5080 |
+--- a/net/bridge/br_netlink.c |
5081 |
++++ b/net/bridge/br_netlink.c |
5082 |
+@@ -1657,7 +1657,8 @@ static size_t br_get_linkxstats_size(const struct net_device *dev, int attr) |
5083 |
+ } |
5084 |
+ |
5085 |
+ return numvls * nla_total_size(sizeof(struct bridge_vlan_xstats)) + |
5086 |
+- nla_total_size(sizeof(struct br_mcast_stats)) + |
5087 |
++ nla_total_size_64bit(sizeof(struct br_mcast_stats)) + |
5088 |
++ (p ? nla_total_size_64bit(sizeof(p->stp_xstats)) : 0) + |
5089 |
+ nla_total_size(0); |
5090 |
+ } |
5091 |
+ |
5092 |
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c |
5093 |
+index 662eb1c37f47b..10e2a0e4804b4 100644 |
5094 |
+--- a/net/core/rtnetlink.c |
5095 |
++++ b/net/core/rtnetlink.c |
5096 |
+@@ -5265,7 +5265,7 @@ nla_put_failure: |
5097 |
+ static size_t if_nlmsg_stats_size(const struct net_device *dev, |
5098 |
+ u32 filter_mask) |
5099 |
+ { |
5100 |
+- size_t size = 0; |
5101 |
++ size_t size = NLMSG_ALIGN(sizeof(struct if_stats_msg)); |
5102 |
+ |
5103 |
+ if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0)) |
5104 |
+ size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64)); |
5105 |
+diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c |
5106 |
+index a822355afc903..26c6768b6b0c5 100644 |
5107 |
+--- a/net/dsa/tag_dsa.c |
5108 |
++++ b/net/dsa/tag_dsa.c |
5109 |
+@@ -176,7 +176,7 @@ static struct sk_buff *dsa_rcv_ll(struct sk_buff *skb, struct net_device *dev, |
5110 |
+ case DSA_CMD_FORWARD: |
5111 |
+ skb->offload_fwd_mark = 1; |
5112 |
+ |
5113 |
+- trunk = !!(dsa_header[1] & 7); |
5114 |
++ trunk = !!(dsa_header[1] & 4); |
5115 |
+ break; |
5116 |
+ |
5117 |
+ case DSA_CMD_TO_CPU: |
5118 |
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c |
5119 |
+index 80aeaf9e6e16e..bfb522e513461 100644 |
5120 |
+--- a/net/ipv4/inet_hashtables.c |
5121 |
++++ b/net/ipv4/inet_hashtables.c |
5122 |
+@@ -242,8 +242,10 @@ static inline int compute_score(struct sock *sk, struct net *net, |
5123 |
+ |
5124 |
+ if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) |
5125 |
+ return -1; |
5126 |
++ score = sk->sk_bound_dev_if ? 2 : 1; |
5127 |
+ |
5128 |
+- score = sk->sk_family == PF_INET ? 2 : 1; |
5129 |
++ if (sk->sk_family == PF_INET) |
5130 |
++ score++; |
5131 |
+ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
5132 |
+ score++; |
5133 |
+ } |
5134 |
+diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c |
5135 |
+index 613432a36f0a7..e61ea428ea187 100644 |
5136 |
+--- a/net/ipv4/netfilter/nf_defrag_ipv4.c |
5137 |
++++ b/net/ipv4/netfilter/nf_defrag_ipv4.c |
5138 |
+@@ -20,13 +20,8 @@ |
5139 |
+ #endif |
5140 |
+ #include <net/netfilter/nf_conntrack_zones.h> |
5141 |
+ |
5142 |
+-static unsigned int defrag4_pernet_id __read_mostly; |
5143 |
+ static DEFINE_MUTEX(defrag4_mutex); |
5144 |
+ |
5145 |
+-struct defrag4_pernet { |
5146 |
+- unsigned int users; |
5147 |
+-}; |
5148 |
+- |
5149 |
+ static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb, |
5150 |
+ u_int32_t user) |
5151 |
+ { |
5152 |
+@@ -111,19 +106,15 @@ static const struct nf_hook_ops ipv4_defrag_ops[] = { |
5153 |
+ |
5154 |
+ static void __net_exit defrag4_net_exit(struct net *net) |
5155 |
+ { |
5156 |
+- struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); |
5157 |
+- |
5158 |
+- if (nf_defrag->users) { |
5159 |
++ if (net->nf.defrag_ipv4_users) { |
5160 |
+ nf_unregister_net_hooks(net, ipv4_defrag_ops, |
5161 |
+ ARRAY_SIZE(ipv4_defrag_ops)); |
5162 |
+- nf_defrag->users = 0; |
5163 |
++ net->nf.defrag_ipv4_users = 0; |
5164 |
+ } |
5165 |
+ } |
5166 |
+ |
5167 |
+ static struct pernet_operations defrag4_net_ops = { |
5168 |
+ .exit = defrag4_net_exit, |
5169 |
+- .id = &defrag4_pernet_id, |
5170 |
+- .size = sizeof(struct defrag4_pernet), |
5171 |
+ }; |
5172 |
+ |
5173 |
+ static int __init nf_defrag_init(void) |
5174 |
+@@ -138,24 +129,23 @@ static void __exit nf_defrag_fini(void) |
5175 |
+ |
5176 |
+ int nf_defrag_ipv4_enable(struct net *net) |
5177 |
+ { |
5178 |
+- struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); |
5179 |
+ int err = 0; |
5180 |
+ |
5181 |
+ mutex_lock(&defrag4_mutex); |
5182 |
+- if (nf_defrag->users == UINT_MAX) { |
5183 |
++ if (net->nf.defrag_ipv4_users == UINT_MAX) { |
5184 |
+ err = -EOVERFLOW; |
5185 |
+ goto out_unlock; |
5186 |
+ } |
5187 |
+ |
5188 |
+- if (nf_defrag->users) { |
5189 |
+- nf_defrag->users++; |
5190 |
++ if (net->nf.defrag_ipv4_users) { |
5191 |
++ net->nf.defrag_ipv4_users++; |
5192 |
+ goto out_unlock; |
5193 |
+ } |
5194 |
+ |
5195 |
+ err = nf_register_net_hooks(net, ipv4_defrag_ops, |
5196 |
+ ARRAY_SIZE(ipv4_defrag_ops)); |
5197 |
+ if (err == 0) |
5198 |
+- nf_defrag->users = 1; |
5199 |
++ net->nf.defrag_ipv4_users = 1; |
5200 |
+ |
5201 |
+ out_unlock: |
5202 |
+ mutex_unlock(&defrag4_mutex); |
5203 |
+@@ -165,12 +155,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable); |
5204 |
+ |
5205 |
+ void nf_defrag_ipv4_disable(struct net *net) |
5206 |
+ { |
5207 |
+- struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); |
5208 |
+- |
5209 |
+ mutex_lock(&defrag4_mutex); |
5210 |
+- if (nf_defrag->users) { |
5211 |
+- nf_defrag->users--; |
5212 |
+- if (nf_defrag->users == 0) |
5213 |
++ if (net->nf.defrag_ipv4_users) { |
5214 |
++ net->nf.defrag_ipv4_users--; |
5215 |
++ if (net->nf.defrag_ipv4_users == 0) |
5216 |
+ nf_unregister_net_hooks(net, ipv4_defrag_ops, |
5217 |
+ ARRAY_SIZE(ipv4_defrag_ops)); |
5218 |
+ } |
5219 |
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c |
5220 |
+index 915ea635b2d5a..cbc7907f79b84 100644 |
5221 |
+--- a/net/ipv4/udp.c |
5222 |
++++ b/net/ipv4/udp.c |
5223 |
+@@ -390,7 +390,8 @@ static int compute_score(struct sock *sk, struct net *net, |
5224 |
+ dif, sdif); |
5225 |
+ if (!dev_match) |
5226 |
+ return -1; |
5227 |
+- score += 4; |
5228 |
++ if (sk->sk_bound_dev_if) |
5229 |
++ score += 4; |
5230 |
+ |
5231 |
+ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
5232 |
+ score++; |
5233 |
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c |
5234 |
+index 55c290d556059..67c9114835c84 100644 |
5235 |
+--- a/net/ipv6/inet6_hashtables.c |
5236 |
++++ b/net/ipv6/inet6_hashtables.c |
5237 |
+@@ -106,7 +106,7 @@ static inline int compute_score(struct sock *sk, struct net *net, |
5238 |
+ if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) |
5239 |
+ return -1; |
5240 |
+ |
5241 |
+- score = 1; |
5242 |
++ score = sk->sk_bound_dev_if ? 2 : 1; |
5243 |
+ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
5244 |
+ score++; |
5245 |
+ } |
5246 |
+diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c |
5247 |
+index a0108415275fe..5c47be29b9ee9 100644 |
5248 |
+--- a/net/ipv6/netfilter/nf_conntrack_reasm.c |
5249 |
++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c |
5250 |
+@@ -33,7 +33,7 @@ |
5251 |
+ |
5252 |
+ static const char nf_frags_cache_name[] = "nf-frags"; |
5253 |
+ |
5254 |
+-unsigned int nf_frag_pernet_id __read_mostly; |
5255 |
++static unsigned int nf_frag_pernet_id __read_mostly; |
5256 |
+ static struct inet_frags nf_frags; |
5257 |
+ |
5258 |
+ static struct nft_ct_frag6_pernet *nf_frag_pernet(struct net *net) |
5259 |
+diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c |
5260 |
+index e8a59d8bf2adf..cb4eb1d2c620b 100644 |
5261 |
+--- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c |
5262 |
++++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c |
5263 |
+@@ -25,8 +25,6 @@ |
5264 |
+ #include <net/netfilter/nf_conntrack_zones.h> |
5265 |
+ #include <net/netfilter/ipv6/nf_defrag_ipv6.h> |
5266 |
+ |
5267 |
+-extern unsigned int nf_frag_pernet_id; |
5268 |
+- |
5269 |
+ static DEFINE_MUTEX(defrag6_mutex); |
5270 |
+ |
5271 |
+ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, |
5272 |
+@@ -91,12 +89,10 @@ static const struct nf_hook_ops ipv6_defrag_ops[] = { |
5273 |
+ |
5274 |
+ static void __net_exit defrag6_net_exit(struct net *net) |
5275 |
+ { |
5276 |
+- struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); |
5277 |
+- |
5278 |
+- if (nf_frag->users) { |
5279 |
++ if (net->nf.defrag_ipv6_users) { |
5280 |
+ nf_unregister_net_hooks(net, ipv6_defrag_ops, |
5281 |
+ ARRAY_SIZE(ipv6_defrag_ops)); |
5282 |
+- nf_frag->users = 0; |
5283 |
++ net->nf.defrag_ipv6_users = 0; |
5284 |
+ } |
5285 |
+ } |
5286 |
+ |
5287 |
+@@ -134,24 +130,23 @@ static void __exit nf_defrag_fini(void) |
5288 |
+ |
5289 |
+ int nf_defrag_ipv6_enable(struct net *net) |
5290 |
+ { |
5291 |
+- struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); |
5292 |
+ int err = 0; |
5293 |
+ |
5294 |
+ mutex_lock(&defrag6_mutex); |
5295 |
+- if (nf_frag->users == UINT_MAX) { |
5296 |
++ if (net->nf.defrag_ipv6_users == UINT_MAX) { |
5297 |
+ err = -EOVERFLOW; |
5298 |
+ goto out_unlock; |
5299 |
+ } |
5300 |
+ |
5301 |
+- if (nf_frag->users) { |
5302 |
+- nf_frag->users++; |
5303 |
++ if (net->nf.defrag_ipv6_users) { |
5304 |
++ net->nf.defrag_ipv6_users++; |
5305 |
+ goto out_unlock; |
5306 |
+ } |
5307 |
+ |
5308 |
+ err = nf_register_net_hooks(net, ipv6_defrag_ops, |
5309 |
+ ARRAY_SIZE(ipv6_defrag_ops)); |
5310 |
+ if (err == 0) |
5311 |
+- nf_frag->users = 1; |
5312 |
++ net->nf.defrag_ipv6_users = 1; |
5313 |
+ |
5314 |
+ out_unlock: |
5315 |
+ mutex_unlock(&defrag6_mutex); |
5316 |
+@@ -161,12 +156,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable); |
5317 |
+ |
5318 |
+ void nf_defrag_ipv6_disable(struct net *net) |
5319 |
+ { |
5320 |
+- struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); |
5321 |
+- |
5322 |
+ mutex_lock(&defrag6_mutex); |
5323 |
+- if (nf_frag->users) { |
5324 |
+- nf_frag->users--; |
5325 |
+- if (nf_frag->users == 0) |
5326 |
++ if (net->nf.defrag_ipv6_users) { |
5327 |
++ net->nf.defrag_ipv6_users--; |
5328 |
++ if (net->nf.defrag_ipv6_users == 0) |
5329 |
+ nf_unregister_net_hooks(net, ipv6_defrag_ops, |
5330 |
+ ARRAY_SIZE(ipv6_defrag_ops)); |
5331 |
+ } |
5332 |
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c |
5333 |
+index 80ae024d13c8c..ba77955d75fbd 100644 |
5334 |
+--- a/net/ipv6/udp.c |
5335 |
++++ b/net/ipv6/udp.c |
5336 |
+@@ -133,7 +133,8 @@ static int compute_score(struct sock *sk, struct net *net, |
5337 |
+ dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif); |
5338 |
+ if (!dev_match) |
5339 |
+ return -1; |
5340 |
+- score++; |
5341 |
++ if (sk->sk_bound_dev_if) |
5342 |
++ score++; |
5343 |
+ |
5344 |
+ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
5345 |
+ score++; |
5346 |
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c |
5347 |
+index b9546defdc280..c0851fec11d46 100644 |
5348 |
+--- a/net/netfilter/nf_tables_api.c |
5349 |
++++ b/net/netfilter/nf_tables_api.c |
5350 |
+@@ -780,6 +780,7 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event) |
5351 |
+ { |
5352 |
+ struct nftables_pernet *nft_net; |
5353 |
+ struct sk_buff *skb; |
5354 |
++ u16 flags = 0; |
5355 |
+ int err; |
5356 |
+ |
5357 |
+ if (!ctx->report && |
5358 |
+@@ -790,8 +791,11 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event) |
5359 |
+ if (skb == NULL) |
5360 |
+ goto err; |
5361 |
+ |
5362 |
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) |
5363 |
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); |
5364 |
++ |
5365 |
+ err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq, |
5366 |
+- event, 0, ctx->family, ctx->table); |
5367 |
++ event, flags, ctx->family, ctx->table); |
5368 |
+ if (err < 0) { |
5369 |
+ kfree_skb(skb); |
5370 |
+ goto err; |
5371 |
+@@ -1563,6 +1567,7 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event) |
5372 |
+ { |
5373 |
+ struct nftables_pernet *nft_net; |
5374 |
+ struct sk_buff *skb; |
5375 |
++ u16 flags = 0; |
5376 |
+ int err; |
5377 |
+ |
5378 |
+ if (!ctx->report && |
5379 |
+@@ -1573,8 +1578,11 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event) |
5380 |
+ if (skb == NULL) |
5381 |
+ goto err; |
5382 |
+ |
5383 |
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) |
5384 |
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); |
5385 |
++ |
5386 |
+ err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq, |
5387 |
+- event, 0, ctx->family, ctx->table, |
5388 |
++ event, flags, ctx->family, ctx->table, |
5389 |
+ ctx->chain); |
5390 |
+ if (err < 0) { |
5391 |
+ kfree_skb(skb); |
5392 |
+@@ -2866,8 +2874,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, |
5393 |
+ u32 flags, int family, |
5394 |
+ const struct nft_table *table, |
5395 |
+ const struct nft_chain *chain, |
5396 |
+- const struct nft_rule *rule, |
5397 |
+- const struct nft_rule *prule) |
5398 |
++ const struct nft_rule *rule, u64 handle) |
5399 |
+ { |
5400 |
+ struct nlmsghdr *nlh; |
5401 |
+ const struct nft_expr *expr, *next; |
5402 |
+@@ -2887,9 +2894,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, |
5403 |
+ NFTA_RULE_PAD)) |
5404 |
+ goto nla_put_failure; |
5405 |
+ |
5406 |
+- if (event != NFT_MSG_DELRULE && prule) { |
5407 |
+- if (nla_put_be64(skb, NFTA_RULE_POSITION, |
5408 |
+- cpu_to_be64(prule->handle), |
5409 |
++ if (event != NFT_MSG_DELRULE && handle) { |
5410 |
++ if (nla_put_be64(skb, NFTA_RULE_POSITION, cpu_to_be64(handle), |
5411 |
+ NFTA_RULE_PAD)) |
5412 |
+ goto nla_put_failure; |
5413 |
+ } |
5414 |
+@@ -2925,7 +2931,10 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx, |
5415 |
+ const struct nft_rule *rule, int event) |
5416 |
+ { |
5417 |
+ struct nftables_pernet *nft_net = nft_pernet(ctx->net); |
5418 |
++ const struct nft_rule *prule; |
5419 |
+ struct sk_buff *skb; |
5420 |
++ u64 handle = 0; |
5421 |
++ u16 flags = 0; |
5422 |
+ int err; |
5423 |
+ |
5424 |
+ if (!ctx->report && |
5425 |
+@@ -2936,9 +2945,20 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx, |
5426 |
+ if (skb == NULL) |
5427 |
+ goto err; |
5428 |
+ |
5429 |
++ if (event == NFT_MSG_NEWRULE && |
5430 |
++ !list_is_first(&rule->list, &ctx->chain->rules) && |
5431 |
++ !list_is_last(&rule->list, &ctx->chain->rules)) { |
5432 |
++ prule = list_prev_entry(rule, list); |
5433 |
++ handle = prule->handle; |
5434 |
++ } |
5435 |
++ if (ctx->flags & (NLM_F_APPEND | NLM_F_REPLACE)) |
5436 |
++ flags |= NLM_F_APPEND; |
5437 |
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) |
5438 |
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); |
5439 |
++ |
5440 |
+ err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq, |
5441 |
+- event, 0, ctx->family, ctx->table, |
5442 |
+- ctx->chain, rule, NULL); |
5443 |
++ event, flags, ctx->family, ctx->table, |
5444 |
++ ctx->chain, rule, handle); |
5445 |
+ if (err < 0) { |
5446 |
+ kfree_skb(skb); |
5447 |
+ goto err; |
5448 |
+@@ -2964,6 +2984,7 @@ static int __nf_tables_dump_rules(struct sk_buff *skb, |
5449 |
+ struct net *net = sock_net(skb->sk); |
5450 |
+ const struct nft_rule *rule, *prule; |
5451 |
+ unsigned int s_idx = cb->args[0]; |
5452 |
++ u64 handle; |
5453 |
+ |
5454 |
+ prule = NULL; |
5455 |
+ list_for_each_entry_rcu(rule, &chain->rules, list) { |
5456 |
+@@ -2975,12 +2996,17 @@ static int __nf_tables_dump_rules(struct sk_buff *skb, |
5457 |
+ memset(&cb->args[1], 0, |
5458 |
+ sizeof(cb->args) - sizeof(cb->args[0])); |
5459 |
+ } |
5460 |
++ if (prule) |
5461 |
++ handle = prule->handle; |
5462 |
++ else |
5463 |
++ handle = 0; |
5464 |
++ |
5465 |
+ if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid, |
5466 |
+ cb->nlh->nlmsg_seq, |
5467 |
+ NFT_MSG_NEWRULE, |
5468 |
+ NLM_F_MULTI | NLM_F_APPEND, |
5469 |
+ table->family, |
5470 |
+- table, chain, rule, prule) < 0) |
5471 |
++ table, chain, rule, handle) < 0) |
5472 |
+ return 1; |
5473 |
+ |
5474 |
+ nl_dump_check_consistent(cb, nlmsg_hdr(skb)); |
5475 |
+@@ -3143,7 +3169,7 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info, |
5476 |
+ |
5477 |
+ err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid, |
5478 |
+ info->nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0, |
5479 |
+- family, table, chain, rule, NULL); |
5480 |
++ family, table, chain, rule, 0); |
5481 |
+ if (err < 0) |
5482 |
+ goto err_fill_rule_info; |
5483 |
+ |
5484 |
+@@ -3403,17 +3429,15 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, |
5485 |
+ } |
5486 |
+ |
5487 |
+ if (info->nlh->nlmsg_flags & NLM_F_REPLACE) { |
5488 |
++ err = nft_delrule(&ctx, old_rule); |
5489 |
++ if (err < 0) |
5490 |
++ goto err_destroy_flow_rule; |
5491 |
++ |
5492 |
+ trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule); |
5493 |
+ if (trans == NULL) { |
5494 |
+ err = -ENOMEM; |
5495 |
+ goto err_destroy_flow_rule; |
5496 |
+ } |
5497 |
+- err = nft_delrule(&ctx, old_rule); |
5498 |
+- if (err < 0) { |
5499 |
+- nft_trans_destroy(trans); |
5500 |
+- goto err_destroy_flow_rule; |
5501 |
+- } |
5502 |
+- |
5503 |
+ list_add_tail_rcu(&rule->list, &old_rule->list); |
5504 |
+ } else { |
5505 |
+ trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule); |
5506 |
+@@ -3943,8 +3967,9 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx, |
5507 |
+ gfp_t gfp_flags) |
5508 |
+ { |
5509 |
+ struct nftables_pernet *nft_net = nft_pernet(ctx->net); |
5510 |
+- struct sk_buff *skb; |
5511 |
+ u32 portid = ctx->portid; |
5512 |
++ struct sk_buff *skb; |
5513 |
++ u16 flags = 0; |
5514 |
+ int err; |
5515 |
+ |
5516 |
+ if (!ctx->report && |
5517 |
+@@ -3955,7 +3980,10 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx, |
5518 |
+ if (skb == NULL) |
5519 |
+ goto err; |
5520 |
+ |
5521 |
+- err = nf_tables_fill_set(skb, ctx, set, event, 0); |
5522 |
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) |
5523 |
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); |
5524 |
++ |
5525 |
++ err = nf_tables_fill_set(skb, ctx, set, event, flags); |
5526 |
+ if (err < 0) { |
5527 |
+ kfree_skb(skb); |
5528 |
+ goto err; |
5529 |
+@@ -5231,12 +5259,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb, |
5530 |
+ static void nf_tables_setelem_notify(const struct nft_ctx *ctx, |
5531 |
+ const struct nft_set *set, |
5532 |
+ const struct nft_set_elem *elem, |
5533 |
+- int event, u16 flags) |
5534 |
++ int event) |
5535 |
+ { |
5536 |
+ struct nftables_pernet *nft_net; |
5537 |
+ struct net *net = ctx->net; |
5538 |
+ u32 portid = ctx->portid; |
5539 |
+ struct sk_buff *skb; |
5540 |
++ u16 flags = 0; |
5541 |
+ int err; |
5542 |
+ |
5543 |
+ if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES)) |
5544 |
+@@ -5246,6 +5275,9 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx, |
5545 |
+ if (skb == NULL) |
5546 |
+ goto err; |
5547 |
+ |
5548 |
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) |
5549 |
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); |
5550 |
++ |
5551 |
+ err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags, |
5552 |
+ set, elem); |
5553 |
+ if (err < 0) { |
5554 |
+@@ -6921,7 +6953,7 @@ static int nf_tables_delobj(struct sk_buff *skb, const struct nfnl_info *info, |
5555 |
+ |
5556 |
+ void nft_obj_notify(struct net *net, const struct nft_table *table, |
5557 |
+ struct nft_object *obj, u32 portid, u32 seq, int event, |
5558 |
+- int family, int report, gfp_t gfp) |
5559 |
++ u16 flags, int family, int report, gfp_t gfp) |
5560 |
+ { |
5561 |
+ struct nftables_pernet *nft_net = nft_pernet(net); |
5562 |
+ struct sk_buff *skb; |
5563 |
+@@ -6946,8 +6978,9 @@ void nft_obj_notify(struct net *net, const struct nft_table *table, |
5564 |
+ if (skb == NULL) |
5565 |
+ goto err; |
5566 |
+ |
5567 |
+- err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family, |
5568 |
+- table, obj, false); |
5569 |
++ err = nf_tables_fill_obj_info(skb, net, portid, seq, event, |
5570 |
++ flags & (NLM_F_CREATE | NLM_F_EXCL), |
5571 |
++ family, table, obj, false); |
5572 |
+ if (err < 0) { |
5573 |
+ kfree_skb(skb); |
5574 |
+ goto err; |
5575 |
+@@ -6964,7 +6997,7 @@ static void nf_tables_obj_notify(const struct nft_ctx *ctx, |
5576 |
+ struct nft_object *obj, int event) |
5577 |
+ { |
5578 |
+ nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event, |
5579 |
+- ctx->family, ctx->report, GFP_KERNEL); |
5580 |
++ ctx->flags, ctx->family, ctx->report, GFP_KERNEL); |
5581 |
+ } |
5582 |
+ |
5583 |
+ /* |
5584 |
+@@ -7745,6 +7778,7 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx, |
5585 |
+ { |
5586 |
+ struct nftables_pernet *nft_net = nft_pernet(ctx->net); |
5587 |
+ struct sk_buff *skb; |
5588 |
++ u16 flags = 0; |
5589 |
+ int err; |
5590 |
+ |
5591 |
+ if (!ctx->report && |
5592 |
+@@ -7755,8 +7789,11 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx, |
5593 |
+ if (skb == NULL) |
5594 |
+ goto err; |
5595 |
+ |
5596 |
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) |
5597 |
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); |
5598 |
++ |
5599 |
+ err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid, |
5600 |
+- ctx->seq, event, 0, |
5601 |
++ ctx->seq, event, flags, |
5602 |
+ ctx->family, flowtable, hook_list); |
5603 |
+ if (err < 0) { |
5604 |
+ kfree_skb(skb); |
5605 |
+@@ -8634,7 +8671,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) |
5606 |
+ nft_setelem_activate(net, te->set, &te->elem); |
5607 |
+ nf_tables_setelem_notify(&trans->ctx, te->set, |
5608 |
+ &te->elem, |
5609 |
+- NFT_MSG_NEWSETELEM, 0); |
5610 |
++ NFT_MSG_NEWSETELEM); |
5611 |
+ nft_trans_destroy(trans); |
5612 |
+ break; |
5613 |
+ case NFT_MSG_DELSETELEM: |
5614 |
+@@ -8642,7 +8679,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) |
5615 |
+ |
5616 |
+ nf_tables_setelem_notify(&trans->ctx, te->set, |
5617 |
+ &te->elem, |
5618 |
+- NFT_MSG_DELSETELEM, 0); |
5619 |
++ NFT_MSG_DELSETELEM); |
5620 |
+ nft_setelem_remove(net, te->set, &te->elem); |
5621 |
+ if (!nft_setelem_is_catchall(te->set, &te->elem)) { |
5622 |
+ atomic_dec(&te->set->nelems); |
5623 |
+diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c |
5624 |
+index 0363f533a42b8..c4d1389f7185a 100644 |
5625 |
+--- a/net/netfilter/nft_quota.c |
5626 |
++++ b/net/netfilter/nft_quota.c |
5627 |
+@@ -60,7 +60,7 @@ static void nft_quota_obj_eval(struct nft_object *obj, |
5628 |
+ if (overquota && |
5629 |
+ !test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags)) |
5630 |
+ nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0, |
5631 |
+- NFT_MSG_NEWOBJ, nft_pf(pkt), 0, GFP_ATOMIC); |
5632 |
++ NFT_MSG_NEWOBJ, 0, nft_pf(pkt), 0, GFP_ATOMIC); |
5633 |
+ } |
5634 |
+ |
5635 |
+ static int nft_quota_do_init(const struct nlattr * const tb[], |
5636 |
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c |
5637 |
+index 24b7cf447bc55..ada47e59647a0 100644 |
5638 |
+--- a/net/netlink/af_netlink.c |
5639 |
++++ b/net/netlink/af_netlink.c |
5640 |
+@@ -594,7 +594,10 @@ static int netlink_insert(struct sock *sk, u32 portid) |
5641 |
+ |
5642 |
+ /* We need to ensure that the socket is hashed and visible. */ |
5643 |
+ smp_wmb(); |
5644 |
+- nlk_sk(sk)->bound = portid; |
5645 |
++ /* Paired with lockless reads from netlink_bind(), |
5646 |
++ * netlink_connect() and netlink_sendmsg(). |
5647 |
++ */ |
5648 |
++ WRITE_ONCE(nlk_sk(sk)->bound, portid); |
5649 |
+ |
5650 |
+ err: |
5651 |
+ release_sock(sk); |
5652 |
+@@ -1012,7 +1015,8 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, |
5653 |
+ if (nlk->ngroups < BITS_PER_LONG) |
5654 |
+ groups &= (1UL << nlk->ngroups) - 1; |
5655 |
+ |
5656 |
+- bound = nlk->bound; |
5657 |
++ /* Paired with WRITE_ONCE() in netlink_insert() */ |
5658 |
++ bound = READ_ONCE(nlk->bound); |
5659 |
+ if (bound) { |
5660 |
+ /* Ensure nlk->portid is up-to-date. */ |
5661 |
+ smp_rmb(); |
5662 |
+@@ -1098,8 +1102,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, |
5663 |
+ |
5664 |
+ /* No need for barriers here as we return to user-space without |
5665 |
+ * using any of the bound attributes. |
5666 |
++ * Paired with WRITE_ONCE() in netlink_insert(). |
5667 |
+ */ |
5668 |
+- if (!nlk->bound) |
5669 |
++ if (!READ_ONCE(nlk->bound)) |
5670 |
+ err = netlink_autobind(sock); |
5671 |
+ |
5672 |
+ if (err == 0) { |
5673 |
+@@ -1888,7 +1893,8 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) |
5674 |
+ dst_group = nlk->dst_group; |
5675 |
+ } |
5676 |
+ |
5677 |
+- if (!nlk->bound) { |
5678 |
++ /* Paired with WRITE_ONCE() in netlink_insert() */ |
5679 |
++ if (!READ_ONCE(nlk->bound)) { |
5680 |
+ err = netlink_autobind(sock); |
5681 |
+ if (err) |
5682 |
+ goto out; |
5683 |
+diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c |
5684 |
+index a579a4131d22d..e1040421b7979 100644 |
5685 |
+--- a/net/sched/sch_fifo.c |
5686 |
++++ b/net/sched/sch_fifo.c |
5687 |
+@@ -233,6 +233,9 @@ int fifo_set_limit(struct Qdisc *q, unsigned int limit) |
5688 |
+ if (strncmp(q->ops->id + 1, "fifo", 4) != 0) |
5689 |
+ return 0; |
5690 |
+ |
5691 |
++ if (!q->ops->change) |
5692 |
++ return 0; |
5693 |
++ |
5694 |
+ nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), GFP_KERNEL); |
5695 |
+ if (nla) { |
5696 |
+ nla->nla_type = RTM_NEWQDISC; |
5697 |
+diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c |
5698 |
+index 1ab2fc933a214..b9fd18d986464 100644 |
5699 |
+--- a/net/sched/sch_taprio.c |
5700 |
++++ b/net/sched/sch_taprio.c |
5701 |
+@@ -1641,6 +1641,10 @@ static void taprio_destroy(struct Qdisc *sch) |
5702 |
+ list_del(&q->taprio_list); |
5703 |
+ spin_unlock(&taprio_list_lock); |
5704 |
+ |
5705 |
++ /* Note that taprio_reset() might not be called if an error |
5706 |
++ * happens in qdisc_create(), after taprio_init() has been called. |
5707 |
++ */ |
5708 |
++ hrtimer_cancel(&q->advance_timer); |
5709 |
+ |
5710 |
+ taprio_disable_offload(dev, q, NULL); |
5711 |
+ |
5712 |
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c |
5713 |
+index 3d685fe328fad..9fd35a60de6ce 100644 |
5714 |
+--- a/net/sunrpc/auth_gss/svcauth_gss.c |
5715 |
++++ b/net/sunrpc/auth_gss/svcauth_gss.c |
5716 |
+@@ -643,7 +643,7 @@ static bool gss_check_seq_num(const struct svc_rqst *rqstp, struct rsc *rsci, |
5717 |
+ } |
5718 |
+ __set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win); |
5719 |
+ goto ok; |
5720 |
+- } else if (seq_num <= sd->sd_max - GSS_SEQ_WIN) { |
5721 |
++ } else if (seq_num + GSS_SEQ_WIN <= sd->sd_max) { |
5722 |
+ goto toolow; |
5723 |
+ } |
5724 |
+ if (__test_and_set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win)) |
5725 |
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c |
5726 |
+index d27e017ebfbea..f1bc09e606cd1 100644 |
5727 |
+--- a/tools/lib/bpf/libbpf.c |
5728 |
++++ b/tools/lib/bpf/libbpf.c |
5729 |
+@@ -8115,7 +8115,8 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr) |
5730 |
+ |
5731 |
+ if (obj->gen_loader) { |
5732 |
+ /* reset FDs */ |
5733 |
+- btf__set_fd(obj->btf, -1); |
5734 |
++ if (obj->btf) |
5735 |
++ btf__set_fd(obj->btf, -1); |
5736 |
+ for (i = 0; i < obj->nr_maps; i++) |
5737 |
+ obj->maps[i].fd = -1; |
5738 |
+ if (!err) |
5739 |
+diff --git a/tools/lib/bpf/strset.c b/tools/lib/bpf/strset.c |
5740 |
+index 1fb8b49de1d62..ea655318153f2 100644 |
5741 |
+--- a/tools/lib/bpf/strset.c |
5742 |
++++ b/tools/lib/bpf/strset.c |
5743 |
+@@ -88,6 +88,7 @@ void strset__free(struct strset *set) |
5744 |
+ |
5745 |
+ hashmap__free(set->strs_hash); |
5746 |
+ free(set->strs_data); |
5747 |
++ free(set); |
5748 |
+ } |
5749 |
+ |
5750 |
+ size_t strset__data_size(const struct strset *set) |
5751 |
+diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c |
5752 |
+index bc821056aba90..0893436cc09f8 100644 |
5753 |
+--- a/tools/objtool/arch/x86/decode.c |
5754 |
++++ b/tools/objtool/arch/x86/decode.c |
5755 |
+@@ -684,7 +684,7 @@ static int elf_add_alternative(struct elf *elf, |
5756 |
+ sec = find_section_by_name(elf, ".altinstructions"); |
5757 |
+ if (!sec) { |
5758 |
+ sec = elf_create_section(elf, ".altinstructions", |
5759 |
+- SHF_ALLOC, size, 0); |
5760 |
++ SHF_ALLOC, 0, 0); |
5761 |
+ |
5762 |
+ if (!sec) { |
5763 |
+ WARN_ELF("elf_create_section"); |
5764 |
+diff --git a/tools/objtool/special.c b/tools/objtool/special.c |
5765 |
+index f1428e32a5052..83d5f969bcb00 100644 |
5766 |
+--- a/tools/objtool/special.c |
5767 |
++++ b/tools/objtool/special.c |
5768 |
+@@ -58,22 +58,11 @@ void __weak arch_handle_alternative(unsigned short feature, struct special_alt * |
5769 |
+ { |
5770 |
+ } |
5771 |
+ |
5772 |
+-static bool reloc2sec_off(struct reloc *reloc, struct section **sec, unsigned long *off) |
5773 |
++static void reloc_to_sec_off(struct reloc *reloc, struct section **sec, |
5774 |
++ unsigned long *off) |
5775 |
+ { |
5776 |
+- switch (reloc->sym->type) { |
5777 |
+- case STT_FUNC: |
5778 |
+- *sec = reloc->sym->sec; |
5779 |
+- *off = reloc->sym->offset + reloc->addend; |
5780 |
+- return true; |
5781 |
+- |
5782 |
+- case STT_SECTION: |
5783 |
+- *sec = reloc->sym->sec; |
5784 |
+- *off = reloc->addend; |
5785 |
+- return true; |
5786 |
+- |
5787 |
+- default: |
5788 |
+- return false; |
5789 |
+- } |
5790 |
++ *sec = reloc->sym->sec; |
5791 |
++ *off = reloc->sym->offset + reloc->addend; |
5792 |
+ } |
5793 |
+ |
5794 |
+ static int get_alt_entry(struct elf *elf, struct special_entry *entry, |
5795 |
+@@ -109,13 +98,8 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry, |
5796 |
+ WARN_FUNC("can't find orig reloc", sec, offset + entry->orig); |
5797 |
+ return -1; |
5798 |
+ } |
5799 |
+- if (!reloc2sec_off(orig_reloc, &alt->orig_sec, &alt->orig_off)) { |
5800 |
+- WARN_FUNC("don't know how to handle reloc symbol type %d: %s", |
5801 |
+- sec, offset + entry->orig, |
5802 |
+- orig_reloc->sym->type, |
5803 |
+- orig_reloc->sym->name); |
5804 |
+- return -1; |
5805 |
+- } |
5806 |
++ |
5807 |
++ reloc_to_sec_off(orig_reloc, &alt->orig_sec, &alt->orig_off); |
5808 |
+ |
5809 |
+ if (!entry->group || alt->new_len) { |
5810 |
+ new_reloc = find_reloc_by_dest(elf, sec, offset + entry->new); |
5811 |
+@@ -133,13 +117,7 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry, |
5812 |
+ if (arch_is_retpoline(new_reloc->sym)) |
5813 |
+ return 1; |
5814 |
+ |
5815 |
+- if (!reloc2sec_off(new_reloc, &alt->new_sec, &alt->new_off)) { |
5816 |
+- WARN_FUNC("don't know how to handle reloc symbol type %d: %s", |
5817 |
+- sec, offset + entry->new, |
5818 |
+- new_reloc->sym->type, |
5819 |
+- new_reloc->sym->name); |
5820 |
+- return -1; |
5821 |
+- } |
5822 |
++ reloc_to_sec_off(new_reloc, &alt->new_sec, &alt->new_off); |
5823 |
+ |
5824 |
+ /* _ASM_EXTABLE_EX hack */ |
5825 |
+ if (alt->new_off >= 0x7ffffff0) |
5826 |
+diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c |
5827 |
+index 9604446f8360b..8b536117e154f 100644 |
5828 |
+--- a/tools/perf/pmu-events/jevents.c |
5829 |
++++ b/tools/perf/pmu-events/jevents.c |
5830 |
+@@ -1284,6 +1284,7 @@ int main(int argc, char *argv[]) |
5831 |
+ } |
5832 |
+ |
5833 |
+ free_arch_std_events(); |
5834 |
++ free_sys_event_tables(); |
5835 |
+ free(mapfile); |
5836 |
+ return 0; |
5837 |
+ |
5838 |
+@@ -1305,6 +1306,7 @@ err_close_eventsfp: |
5839 |
+ create_empty_mapping(output_file); |
5840 |
+ err_out: |
5841 |
+ free_arch_std_events(); |
5842 |
++ free_sys_event_tables(); |
5843 |
+ free(mapfile); |
5844 |
+ return ret; |
5845 |
+ } |