Annotation of /trunk/kernel-alx/patches-4.19/0128-4.19.29-all-fixes.patch
Parent Directory | Revision Log
Revision 3407 -
(hide annotations)
(download)
Fri Aug 2 11:47:39 2019 UTC (4 years, 10 months ago) by niro
File size: 198034 byte(s)
Fri Aug 2 11:47:39 2019 UTC (4 years, 10 months ago) by niro
File size: 198034 byte(s)
-linux-4.19.29
1 | niro | 3407 | diff --git a/Makefile b/Makefile |
2 | index c6ac023ba33a..6e526583291c 100644 | ||
3 | --- a/Makefile | ||
4 | +++ b/Makefile | ||
5 | @@ -1,7 +1,7 @@ | ||
6 | # SPDX-License-Identifier: GPL-2.0 | ||
7 | VERSION = 4 | ||
8 | PATCHLEVEL = 19 | ||
9 | -SUBLEVEL = 28 | ||
10 | +SUBLEVEL = 29 | ||
11 | EXTRAVERSION = | ||
12 | NAME = "People's Front" | ||
13 | |||
14 | diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi | ||
15 | index 27a1ee28c3bb..94efca78c42f 100644 | ||
16 | --- a/arch/arm/boot/dts/exynos3250.dtsi | ||
17 | +++ b/arch/arm/boot/dts/exynos3250.dtsi | ||
18 | @@ -168,6 +168,9 @@ | ||
19 | interrupt-controller; | ||
20 | #interrupt-cells = <3>; | ||
21 | interrupt-parent = <&gic>; | ||
22 | + clock-names = "clkout8"; | ||
23 | + clocks = <&cmu CLK_FIN_PLL>; | ||
24 | + #clock-cells = <1>; | ||
25 | }; | ||
26 | |||
27 | mipi_phy: video-phy { | ||
28 | diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi | ||
29 | index a09e46c9dbc0..00820d239753 100644 | ||
30 | --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi | ||
31 | +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi | ||
32 | @@ -49,7 +49,7 @@ | ||
33 | }; | ||
34 | |||
35 | emmc_pwrseq: pwrseq { | ||
36 | - pinctrl-0 = <&sd1_cd>; | ||
37 | + pinctrl-0 = <&emmc_rstn>; | ||
38 | pinctrl-names = "default"; | ||
39 | compatible = "mmc-pwrseq-emmc"; | ||
40 | reset-gpios = <&gpk1 2 GPIO_ACTIVE_LOW>; | ||
41 | @@ -161,12 +161,6 @@ | ||
42 | cpu0-supply = <&buck2_reg>; | ||
43 | }; | ||
44 | |||
45 | -/* RSTN signal for eMMC */ | ||
46 | -&sd1_cd { | ||
47 | - samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; | ||
48 | - samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; | ||
49 | -}; | ||
50 | - | ||
51 | &pinctrl_1 { | ||
52 | gpio_power_key: power_key { | ||
53 | samsung,pins = "gpx1-3"; | ||
54 | @@ -184,6 +178,11 @@ | ||
55 | samsung,pins = "gpx3-7"; | ||
56 | samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>; | ||
57 | }; | ||
58 | + | ||
59 | + emmc_rstn: emmc-rstn { | ||
60 | + samsung,pins = "gpk1-2"; | ||
61 | + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; | ||
62 | + }; | ||
63 | }; | ||
64 | |||
65 | &ehci { | ||
66 | diff --git a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi | ||
67 | index 2f4f40882dab..27214e6ebe4f 100644 | ||
68 | --- a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi | ||
69 | +++ b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi | ||
70 | @@ -334,7 +334,7 @@ | ||
71 | buck8_reg: BUCK8 { | ||
72 | regulator-name = "vdd_1.8v_ldo"; | ||
73 | regulator-min-microvolt = <800000>; | ||
74 | - regulator-max-microvolt = <1500000>; | ||
75 | + regulator-max-microvolt = <2000000>; | ||
76 | regulator-always-on; | ||
77 | regulator-boot-on; | ||
78 | }; | ||
79 | diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi | ||
80 | index 844caa39364f..50083cecc6c9 100644 | ||
81 | --- a/arch/arm/boot/dts/imx6sx.dtsi | ||
82 | +++ b/arch/arm/boot/dts/imx6sx.dtsi | ||
83 | @@ -462,7 +462,7 @@ | ||
84 | }; | ||
85 | |||
86 | gpt: gpt@2098000 { | ||
87 | - compatible = "fsl,imx6sx-gpt", "fsl,imx31-gpt"; | ||
88 | + compatible = "fsl,imx6sx-gpt", "fsl,imx6dl-gpt"; | ||
89 | reg = <0x02098000 0x4000>; | ||
90 | interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; | ||
91 | clocks = <&clks IMX6SX_CLK_GPT_BUS>, | ||
92 | diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi | ||
93 | index 0d9faf1a51ea..a86b89086334 100644 | ||
94 | --- a/arch/arm/boot/dts/meson.dtsi | ||
95 | +++ b/arch/arm/boot/dts/meson.dtsi | ||
96 | @@ -263,7 +263,7 @@ | ||
97 | compatible = "amlogic,meson6-dwmac", "snps,dwmac"; | ||
98 | reg = <0xc9410000 0x10000 | ||
99 | 0xc1108108 0x4>; | ||
100 | - interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE_RISING>; | ||
101 | + interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; | ||
102 | interrupt-names = "macirq"; | ||
103 | status = "disabled"; | ||
104 | }; | ||
105 | diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts | ||
106 | index ef3177d3da3d..8fdeeffecbdb 100644 | ||
107 | --- a/arch/arm/boot/dts/meson8b-odroidc1.dts | ||
108 | +++ b/arch/arm/boot/dts/meson8b-odroidc1.dts | ||
109 | @@ -125,7 +125,6 @@ | ||
110 | /* Realtek RTL8211F (0x001cc916) */ | ||
111 | eth_phy: ethernet-phy@0 { | ||
112 | reg = <0>; | ||
113 | - eee-broken-1000t; | ||
114 | interrupt-parent = <&gpio_intc>; | ||
115 | /* GPIOH_3 */ | ||
116 | interrupts = <17 IRQ_TYPE_LEVEL_LOW>; | ||
117 | @@ -172,8 +171,7 @@ | ||
118 | cap-sd-highspeed; | ||
119 | disable-wp; | ||
120 | |||
121 | - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; | ||
122 | - cd-inverted; | ||
123 | + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; | ||
124 | |||
125 | vmmc-supply = <&tflash_vdd>; | ||
126 | vqmmc-supply = <&tf_io>; | ||
127 | diff --git a/arch/arm/boot/dts/meson8m2-mxiii-plus.dts b/arch/arm/boot/dts/meson8m2-mxiii-plus.dts | ||
128 | index f5853610b20b..6ac02beb5fa7 100644 | ||
129 | --- a/arch/arm/boot/dts/meson8m2-mxiii-plus.dts | ||
130 | +++ b/arch/arm/boot/dts/meson8m2-mxiii-plus.dts | ||
131 | @@ -206,8 +206,7 @@ | ||
132 | cap-sd-highspeed; | ||
133 | disable-wp; | ||
134 | |||
135 | - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; | ||
136 | - cd-inverted; | ||
137 | + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; | ||
138 | |||
139 | vmmc-supply = <&vcc_3v3>; | ||
140 | }; | ||
141 | diff --git a/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi b/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi | ||
142 | index ddc7a7bb33c0..f57acf8f66b9 100644 | ||
143 | --- a/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi | ||
144 | +++ b/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi | ||
145 | @@ -105,7 +105,7 @@ | ||
146 | interrupts-extended = < | ||
147 | &cpcap 15 0 &cpcap 14 0 &cpcap 28 0 &cpcap 19 0 | ||
148 | &cpcap 18 0 &cpcap 17 0 &cpcap 16 0 &cpcap 49 0 | ||
149 | - &cpcap 48 1 | ||
150 | + &cpcap 48 0 | ||
151 | >; | ||
152 | interrupt-names = | ||
153 | "id_ground", "id_float", "se0conn", "vbusvld", | ||
154 | diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi | ||
155 | index 0d9b85317529..e142e6c70a59 100644 | ||
156 | --- a/arch/arm/boot/dts/omap3-n950-n9.dtsi | ||
157 | +++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi | ||
158 | @@ -370,6 +370,19 @@ | ||
159 | compatible = "ti,omap2-onenand"; | ||
160 | reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */ | ||
161 | |||
162 | + /* | ||
163 | + * These timings are based on CONFIG_OMAP_GPMC_DEBUG=y reported | ||
164 | + * bootloader set values when booted with v4.19 using both N950 | ||
165 | + * and N9 devices (OneNAND Manufacturer: Samsung): | ||
166 | + * | ||
167 | + * gpmc cs0 before gpmc_cs_program_settings: | ||
168 | + * cs0 GPMC_CS_CONFIG1: 0xfd001202 | ||
169 | + * cs0 GPMC_CS_CONFIG2: 0x00181800 | ||
170 | + * cs0 GPMC_CS_CONFIG3: 0x00030300 | ||
171 | + * cs0 GPMC_CS_CONFIG4: 0x18001804 | ||
172 | + * cs0 GPMC_CS_CONFIG5: 0x03171d1d | ||
173 | + * cs0 GPMC_CS_CONFIG6: 0x97080000 | ||
174 | + */ | ||
175 | gpmc,sync-read; | ||
176 | gpmc,sync-write; | ||
177 | gpmc,burst-length = <16>; | ||
178 | @@ -379,26 +392,27 @@ | ||
179 | gpmc,device-width = <2>; | ||
180 | gpmc,mux-add-data = <2>; | ||
181 | gpmc,cs-on-ns = <0>; | ||
182 | - gpmc,cs-rd-off-ns = <87>; | ||
183 | - gpmc,cs-wr-off-ns = <87>; | ||
184 | + gpmc,cs-rd-off-ns = <122>; | ||
185 | + gpmc,cs-wr-off-ns = <122>; | ||
186 | gpmc,adv-on-ns = <0>; | ||
187 | - gpmc,adv-rd-off-ns = <10>; | ||
188 | - gpmc,adv-wr-off-ns = <10>; | ||
189 | - gpmc,oe-on-ns = <15>; | ||
190 | - gpmc,oe-off-ns = <87>; | ||
191 | + gpmc,adv-rd-off-ns = <15>; | ||
192 | + gpmc,adv-wr-off-ns = <15>; | ||
193 | + gpmc,oe-on-ns = <20>; | ||
194 | + gpmc,oe-off-ns = <122>; | ||
195 | gpmc,we-on-ns = <0>; | ||
196 | - gpmc,we-off-ns = <87>; | ||
197 | - gpmc,rd-cycle-ns = <112>; | ||
198 | - gpmc,wr-cycle-ns = <112>; | ||
199 | - gpmc,access-ns = <81>; | ||
200 | + gpmc,we-off-ns = <122>; | ||
201 | + gpmc,rd-cycle-ns = <148>; | ||
202 | + gpmc,wr-cycle-ns = <148>; | ||
203 | + gpmc,access-ns = <117>; | ||
204 | gpmc,page-burst-access-ns = <15>; | ||
205 | gpmc,bus-turnaround-ns = <0>; | ||
206 | gpmc,cycle2cycle-delay-ns = <0>; | ||
207 | gpmc,wait-monitoring-ns = <0>; | ||
208 | - gpmc,clk-activation-ns = <5>; | ||
209 | - gpmc,wr-data-mux-bus-ns = <30>; | ||
210 | - gpmc,wr-access-ns = <81>; | ||
211 | - gpmc,sync-clk-ps = <15000>; | ||
212 | + gpmc,clk-activation-ns = <10>; | ||
213 | + gpmc,wr-data-mux-bus-ns = <40>; | ||
214 | + gpmc,wr-access-ns = <117>; | ||
215 | + | ||
216 | + gpmc,sync-clk-ps = <15000>; /* TBC; Where this value came? */ | ||
217 | |||
218 | /* | ||
219 | * MTD partition table corresponding to Nokia's MeeGo 1.2 | ||
220 | diff --git a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts | ||
221 | index 5d23667dc2d2..25540b7694d5 100644 | ||
222 | --- a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts | ||
223 | +++ b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts | ||
224 | @@ -53,7 +53,7 @@ | ||
225 | |||
226 | aliases { | ||
227 | serial0 = &uart0; | ||
228 | - /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */ | ||
229 | + ethernet0 = &emac; | ||
230 | ethernet1 = &sdiowifi; | ||
231 | }; | ||
232 | |||
233 | diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c | ||
234 | index ed36dcab80f1..f51919974183 100644 | ||
235 | --- a/arch/arm/plat-pxa/ssp.c | ||
236 | +++ b/arch/arm/plat-pxa/ssp.c | ||
237 | @@ -190,8 +190,6 @@ static int pxa_ssp_remove(struct platform_device *pdev) | ||
238 | if (ssp == NULL) | ||
239 | return -ENODEV; | ||
240 | |||
241 | - iounmap(ssp->mmio_base); | ||
242 | - | ||
243 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
244 | release_mem_region(res->start, resource_size(res)); | ||
245 | |||
246 | @@ -201,7 +199,6 @@ static int pxa_ssp_remove(struct platform_device *pdev) | ||
247 | list_del(&ssp->node); | ||
248 | mutex_unlock(&ssp_lock); | ||
249 | |||
250 | - kfree(ssp); | ||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | ||
255 | index f4964bee6a1a..e80a792827ed 100644 | ||
256 | --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | ||
257 | +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | ||
258 | @@ -118,6 +118,7 @@ | ||
259 | reset-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; | ||
260 | clocks = <&pmic>; | ||
261 | clock-names = "ext_clock"; | ||
262 | + post-power-on-delay-ms = <10>; | ||
263 | power-off-delay-us = <10>; | ||
264 | }; | ||
265 | |||
266 | @@ -300,7 +301,6 @@ | ||
267 | |||
268 | dwmmc_0: dwmmc0@f723d000 { | ||
269 | cap-mmc-highspeed; | ||
270 | - mmc-hs200-1_8v; | ||
271 | non-removable; | ||
272 | bus-width = <0x8>; | ||
273 | vmmc-supply = <&ldo19>; | ||
274 | diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi | ||
275 | index cd3865e7a270..8c86c41a0d25 100644 | ||
276 | --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi | ||
277 | +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi | ||
278 | @@ -399,7 +399,7 @@ | ||
279 | }; | ||
280 | |||
281 | intc: interrupt-controller@9bc0000 { | ||
282 | - compatible = "arm,gic-v3"; | ||
283 | + compatible = "qcom,msm8996-gic-v3", "arm,gic-v3"; | ||
284 | #interrupt-cells = <3>; | ||
285 | interrupt-controller; | ||
286 | #redistributor-regions = <1>; | ||
287 | diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi | ||
288 | index cbd35c00b4af..33cb0281c39c 100644 | ||
289 | --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi | ||
290 | +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi | ||
291 | @@ -1161,6 +1161,9 @@ | ||
292 | <&cpg CPG_CORE R8A7796_CLK_S3D1>, | ||
293 | <&scif_clk>; | ||
294 | clock-names = "fck", "brg_int", "scif_clk"; | ||
295 | + dmas = <&dmac1 0x13>, <&dmac1 0x12>, | ||
296 | + <&dmac2 0x13>, <&dmac2 0x12>; | ||
297 | + dma-names = "tx", "rx", "tx", "rx"; | ||
298 | power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; | ||
299 | resets = <&cpg 310>; | ||
300 | status = "disabled"; | ||
301 | diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi | ||
302 | index 0cd44461a0bd..f60f08ba1a6f 100644 | ||
303 | --- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi | ||
304 | +++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi | ||
305 | @@ -951,6 +951,9 @@ | ||
306 | <&cpg CPG_CORE R8A77965_CLK_S3D1>, | ||
307 | <&scif_clk>; | ||
308 | clock-names = "fck", "brg_int", "scif_clk"; | ||
309 | + dmas = <&dmac1 0x13>, <&dmac1 0x12>, | ||
310 | + <&dmac2 0x13>, <&dmac2 0x12>; | ||
311 | + dma-names = "tx", "rx", "tx", "rx"; | ||
312 | power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; | ||
313 | resets = <&cpg 310>; | ||
314 | status = "disabled"; | ||
315 | diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts | ||
316 | index eb5e8bddb610..8954c8c6f547 100644 | ||
317 | --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts | ||
318 | +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts | ||
319 | @@ -101,6 +101,7 @@ | ||
320 | sdio_pwrseq: sdio_pwrseq { | ||
321 | compatible = "mmc-pwrseq-simple"; | ||
322 | reset-gpios = <&gpio 7 GPIO_ACTIVE_LOW>; /* WIFI_EN */ | ||
323 | + post-power-on-delay-ms = <10>; | ||
324 | }; | ||
325 | }; | ||
326 | |||
327 | diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c | ||
328 | index b5a367d4bba6..30bb13797034 100644 | ||
329 | --- a/arch/arm64/kernel/probes/kprobes.c | ||
330 | +++ b/arch/arm64/kernel/probes/kprobes.c | ||
331 | @@ -478,13 +478,13 @@ bool arch_within_kprobe_blacklist(unsigned long addr) | ||
332 | addr < (unsigned long)__entry_text_end) || | ||
333 | (addr >= (unsigned long)__idmap_text_start && | ||
334 | addr < (unsigned long)__idmap_text_end) || | ||
335 | + (addr >= (unsigned long)__hyp_text_start && | ||
336 | + addr < (unsigned long)__hyp_text_end) || | ||
337 | !!search_exception_tables(addr)) | ||
338 | return true; | ||
339 | |||
340 | if (!is_kernel_in_hyp_mode()) { | ||
341 | - if ((addr >= (unsigned long)__hyp_text_start && | ||
342 | - addr < (unsigned long)__hyp_text_end) || | ||
343 | - (addr >= (unsigned long)__hyp_idmap_text_start && | ||
344 | + if ((addr >= (unsigned long)__hyp_idmap_text_start && | ||
345 | addr < (unsigned long)__hyp_idmap_text_end)) | ||
346 | return true; | ||
347 | } | ||
348 | diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts | ||
349 | index 50cff3cbcc6d..4f7b1fa31cf5 100644 | ||
350 | --- a/arch/mips/boot/dts/ingenic/ci20.dts | ||
351 | +++ b/arch/mips/boot/dts/ingenic/ci20.dts | ||
352 | @@ -76,7 +76,7 @@ | ||
353 | status = "okay"; | ||
354 | |||
355 | pinctrl-names = "default"; | ||
356 | - pinctrl-0 = <&pins_uart2>; | ||
357 | + pinctrl-0 = <&pins_uart3>; | ||
358 | }; | ||
359 | |||
360 | &uart4 { | ||
361 | @@ -196,9 +196,9 @@ | ||
362 | bias-disable; | ||
363 | }; | ||
364 | |||
365 | - pins_uart2: uart2 { | ||
366 | - function = "uart2"; | ||
367 | - groups = "uart2-data", "uart2-hwflow"; | ||
368 | + pins_uart3: uart3 { | ||
369 | + function = "uart3"; | ||
370 | + groups = "uart3-data", "uart3-hwflow"; | ||
371 | bias-disable; | ||
372 | }; | ||
373 | |||
374 | diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c | ||
375 | index d4f7fd4550e1..85522c137f19 100644 | ||
376 | --- a/arch/mips/kernel/process.c | ||
377 | +++ b/arch/mips/kernel/process.c | ||
378 | @@ -371,7 +371,7 @@ static inline int is_sp_move_ins(union mips_instruction *ip, int *frame_size) | ||
379 | static int get_frame_info(struct mips_frame_info *info) | ||
380 | { | ||
381 | bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS); | ||
382 | - union mips_instruction insn, *ip, *ip_end; | ||
383 | + union mips_instruction insn, *ip; | ||
384 | const unsigned int max_insns = 128; | ||
385 | unsigned int last_insn_size = 0; | ||
386 | unsigned int i; | ||
387 | @@ -384,10 +384,9 @@ static int get_frame_info(struct mips_frame_info *info) | ||
388 | if (!ip) | ||
389 | goto err; | ||
390 | |||
391 | - ip_end = (void *)ip + info->func_size; | ||
392 | - | ||
393 | - for (i = 0; i < max_insns && ip < ip_end; i++) { | ||
394 | + for (i = 0; i < max_insns; i++) { | ||
395 | ip = (void *)ip + last_insn_size; | ||
396 | + | ||
397 | if (is_mmips && mm_insn_16bit(ip->halfword[0])) { | ||
398 | insn.word = ip->halfword[0] << 16; | ||
399 | last_insn_size = 2; | ||
400 | diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h | ||
401 | index 3fe4af8147d2..c23578a37b44 100644 | ||
402 | --- a/arch/riscv/include/asm/processor.h | ||
403 | +++ b/arch/riscv/include/asm/processor.h | ||
404 | @@ -22,7 +22,7 @@ | ||
405 | * This decides where the kernel will search for a free chunk of vm | ||
406 | * space during mmap's. | ||
407 | */ | ||
408 | -#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE >> 1) | ||
409 | +#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3) | ||
410 | |||
411 | #define STACK_TOP TASK_SIZE | ||
412 | #define STACK_TOP_MAX STACK_TOP | ||
413 | diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c | ||
414 | index b2d26d9d8489..9713d4e8c22b 100644 | ||
415 | --- a/arch/riscv/kernel/setup.c | ||
416 | +++ b/arch/riscv/kernel/setup.c | ||
417 | @@ -186,7 +186,7 @@ static void __init setup_bootmem(void) | ||
418 | BUG_ON(mem_size == 0); | ||
419 | |||
420 | set_max_mapnr(PFN_DOWN(mem_size)); | ||
421 | - max_low_pfn = memblock_end_of_DRAM(); | ||
422 | + max_low_pfn = PFN_DOWN(memblock_end_of_DRAM()); | ||
423 | |||
424 | #ifdef CONFIG_BLK_DEV_INITRD | ||
425 | setup_initrd(); | ||
426 | diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c | ||
427 | index 58a522f9bcc3..200a4b315e15 100644 | ||
428 | --- a/arch/riscv/mm/init.c | ||
429 | +++ b/arch/riscv/mm/init.c | ||
430 | @@ -29,7 +29,8 @@ static void __init zone_sizes_init(void) | ||
431 | unsigned long max_zone_pfns[MAX_NR_ZONES] = { 0, }; | ||
432 | |||
433 | #ifdef CONFIG_ZONE_DMA32 | ||
434 | - max_zone_pfns[ZONE_DMA32] = PFN_DOWN(min(4UL * SZ_1G, max_low_pfn)); | ||
435 | + max_zone_pfns[ZONE_DMA32] = PFN_DOWN(min(4UL * SZ_1G, | ||
436 | + (unsigned long) PFN_PHYS(max_low_pfn))); | ||
437 | #endif | ||
438 | max_zone_pfns[ZONE_NORMAL] = max_low_pfn; | ||
439 | |||
440 | diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S | ||
441 | index 64037895b085..f105ae8651c9 100644 | ||
442 | --- a/arch/x86/boot/compressed/head_64.S | ||
443 | +++ b/arch/x86/boot/compressed/head_64.S | ||
444 | @@ -600,6 +600,14 @@ ENTRY(trampoline_32bit_src) | ||
445 | leal TRAMPOLINE_32BIT_PGTABLE_OFFSET(%ecx), %eax | ||
446 | movl %eax, %cr3 | ||
447 | 3: | ||
448 | + /* Set EFER.LME=1 as a precaution in case hypervsior pulls the rug */ | ||
449 | + pushl %ecx | ||
450 | + movl $MSR_EFER, %ecx | ||
451 | + rdmsr | ||
452 | + btsl $_EFER_LME, %eax | ||
453 | + wrmsr | ||
454 | + popl %ecx | ||
455 | + | ||
456 | /* Enable PAE and LA57 (if required) paging modes */ | ||
457 | movl $X86_CR4_PAE, %eax | ||
458 | cmpl $0, %edx | ||
459 | diff --git a/arch/x86/boot/compressed/pgtable.h b/arch/x86/boot/compressed/pgtable.h | ||
460 | index 91f75638f6e6..6ff7e81b5628 100644 | ||
461 | --- a/arch/x86/boot/compressed/pgtable.h | ||
462 | +++ b/arch/x86/boot/compressed/pgtable.h | ||
463 | @@ -6,7 +6,7 @@ | ||
464 | #define TRAMPOLINE_32BIT_PGTABLE_OFFSET 0 | ||
465 | |||
466 | #define TRAMPOLINE_32BIT_CODE_OFFSET PAGE_SIZE | ||
467 | -#define TRAMPOLINE_32BIT_CODE_SIZE 0x60 | ||
468 | +#define TRAMPOLINE_32BIT_CODE_SIZE 0x70 | ||
469 | |||
470 | #define TRAMPOLINE_32BIT_STACK_END TRAMPOLINE_32BIT_SIZE | ||
471 | |||
472 | diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c | ||
473 | index c04a8813cff9..a41554350893 100644 | ||
474 | --- a/arch/x86/events/core.c | ||
475 | +++ b/arch/x86/events/core.c | ||
476 | @@ -1970,7 +1970,7 @@ static int x86_pmu_commit_txn(struct pmu *pmu) | ||
477 | */ | ||
478 | static void free_fake_cpuc(struct cpu_hw_events *cpuc) | ||
479 | { | ||
480 | - kfree(cpuc->shared_regs); | ||
481 | + intel_cpuc_finish(cpuc); | ||
482 | kfree(cpuc); | ||
483 | } | ||
484 | |||
485 | @@ -1982,14 +1982,11 @@ static struct cpu_hw_events *allocate_fake_cpuc(void) | ||
486 | cpuc = kzalloc(sizeof(*cpuc), GFP_KERNEL); | ||
487 | if (!cpuc) | ||
488 | return ERR_PTR(-ENOMEM); | ||
489 | - | ||
490 | - /* only needed, if we have extra_regs */ | ||
491 | - if (x86_pmu.extra_regs) { | ||
492 | - cpuc->shared_regs = allocate_shared_regs(cpu); | ||
493 | - if (!cpuc->shared_regs) | ||
494 | - goto error; | ||
495 | - } | ||
496 | cpuc->is_fake = 1; | ||
497 | + | ||
498 | + if (intel_cpuc_prepare(cpuc, cpu)) | ||
499 | + goto error; | ||
500 | + | ||
501 | return cpuc; | ||
502 | error: | ||
503 | free_fake_cpuc(cpuc); | ||
504 | diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c | ||
505 | index fbd7551a8d44..220b40b75e6f 100644 | ||
506 | --- a/arch/x86/events/intel/core.c | ||
507 | +++ b/arch/x86/events/intel/core.c | ||
508 | @@ -1995,6 +1995,39 @@ static void intel_pmu_nhm_enable_all(int added) | ||
509 | intel_pmu_enable_all(added); | ||
510 | } | ||
511 | |||
512 | +static void intel_set_tfa(struct cpu_hw_events *cpuc, bool on) | ||
513 | +{ | ||
514 | + u64 val = on ? MSR_TFA_RTM_FORCE_ABORT : 0; | ||
515 | + | ||
516 | + if (cpuc->tfa_shadow != val) { | ||
517 | + cpuc->tfa_shadow = val; | ||
518 | + wrmsrl(MSR_TSX_FORCE_ABORT, val); | ||
519 | + } | ||
520 | +} | ||
521 | + | ||
522 | +static void intel_tfa_commit_scheduling(struct cpu_hw_events *cpuc, int idx, int cntr) | ||
523 | +{ | ||
524 | + /* | ||
525 | + * We're going to use PMC3, make sure TFA is set before we touch it. | ||
526 | + */ | ||
527 | + if (cntr == 3 && !cpuc->is_fake) | ||
528 | + intel_set_tfa(cpuc, true); | ||
529 | +} | ||
530 | + | ||
531 | +static void intel_tfa_pmu_enable_all(int added) | ||
532 | +{ | ||
533 | + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | ||
534 | + | ||
535 | + /* | ||
536 | + * If we find PMC3 is no longer used when we enable the PMU, we can | ||
537 | + * clear TFA. | ||
538 | + */ | ||
539 | + if (!test_bit(3, cpuc->active_mask)) | ||
540 | + intel_set_tfa(cpuc, false); | ||
541 | + | ||
542 | + intel_pmu_enable_all(added); | ||
543 | +} | ||
544 | + | ||
545 | static inline u64 intel_pmu_get_status(void) | ||
546 | { | ||
547 | u64 status; | ||
548 | @@ -2652,6 +2685,35 @@ intel_stop_scheduling(struct cpu_hw_events *cpuc) | ||
549 | raw_spin_unlock(&excl_cntrs->lock); | ||
550 | } | ||
551 | |||
552 | +static struct event_constraint * | ||
553 | +dyn_constraint(struct cpu_hw_events *cpuc, struct event_constraint *c, int idx) | ||
554 | +{ | ||
555 | + WARN_ON_ONCE(!cpuc->constraint_list); | ||
556 | + | ||
557 | + if (!(c->flags & PERF_X86_EVENT_DYNAMIC)) { | ||
558 | + struct event_constraint *cx; | ||
559 | + | ||
560 | + /* | ||
561 | + * grab pre-allocated constraint entry | ||
562 | + */ | ||
563 | + cx = &cpuc->constraint_list[idx]; | ||
564 | + | ||
565 | + /* | ||
566 | + * initialize dynamic constraint | ||
567 | + * with static constraint | ||
568 | + */ | ||
569 | + *cx = *c; | ||
570 | + | ||
571 | + /* | ||
572 | + * mark constraint as dynamic | ||
573 | + */ | ||
574 | + cx->flags |= PERF_X86_EVENT_DYNAMIC; | ||
575 | + c = cx; | ||
576 | + } | ||
577 | + | ||
578 | + return c; | ||
579 | +} | ||
580 | + | ||
581 | static struct event_constraint * | ||
582 | intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event, | ||
583 | int idx, struct event_constraint *c) | ||
584 | @@ -2682,27 +2744,7 @@ intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event, | ||
585 | * only needed when constraint has not yet | ||
586 | * been cloned (marked dynamic) | ||
587 | */ | ||
588 | - if (!(c->flags & PERF_X86_EVENT_DYNAMIC)) { | ||
589 | - struct event_constraint *cx; | ||
590 | - | ||
591 | - /* | ||
592 | - * grab pre-allocated constraint entry | ||
593 | - */ | ||
594 | - cx = &cpuc->constraint_list[idx]; | ||
595 | - | ||
596 | - /* | ||
597 | - * initialize dynamic constraint | ||
598 | - * with static constraint | ||
599 | - */ | ||
600 | - *cx = *c; | ||
601 | - | ||
602 | - /* | ||
603 | - * mark constraint as dynamic, so we | ||
604 | - * can free it later on | ||
605 | - */ | ||
606 | - cx->flags |= PERF_X86_EVENT_DYNAMIC; | ||
607 | - c = cx; | ||
608 | - } | ||
609 | + c = dyn_constraint(cpuc, c, idx); | ||
610 | |||
611 | /* | ||
612 | * From here on, the constraint is dynamic. | ||
613 | @@ -3229,6 +3271,26 @@ glp_get_event_constraints(struct cpu_hw_events *cpuc, int idx, | ||
614 | return c; | ||
615 | } | ||
616 | |||
617 | +static bool allow_tsx_force_abort = true; | ||
618 | + | ||
619 | +static struct event_constraint * | ||
620 | +tfa_get_event_constraints(struct cpu_hw_events *cpuc, int idx, | ||
621 | + struct perf_event *event) | ||
622 | +{ | ||
623 | + struct event_constraint *c = hsw_get_event_constraints(cpuc, idx, event); | ||
624 | + | ||
625 | + /* | ||
626 | + * Without TFA we must not use PMC3. | ||
627 | + */ | ||
628 | + if (!allow_tsx_force_abort && test_bit(3, c->idxmsk)) { | ||
629 | + c = dyn_constraint(cpuc, c, idx); | ||
630 | + c->idxmsk64 &= ~(1ULL << 3); | ||
631 | + c->weight--; | ||
632 | + } | ||
633 | + | ||
634 | + return c; | ||
635 | +} | ||
636 | + | ||
637 | /* | ||
638 | * Broadwell: | ||
639 | * | ||
640 | @@ -3282,7 +3344,7 @@ ssize_t intel_event_sysfs_show(char *page, u64 config) | ||
641 | return x86_event_sysfs_show(page, config, event); | ||
642 | } | ||
643 | |||
644 | -struct intel_shared_regs *allocate_shared_regs(int cpu) | ||
645 | +static struct intel_shared_regs *allocate_shared_regs(int cpu) | ||
646 | { | ||
647 | struct intel_shared_regs *regs; | ||
648 | int i; | ||
649 | @@ -3314,23 +3376,24 @@ static struct intel_excl_cntrs *allocate_excl_cntrs(int cpu) | ||
650 | return c; | ||
651 | } | ||
652 | |||
653 | -static int intel_pmu_cpu_prepare(int cpu) | ||
654 | -{ | ||
655 | - struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); | ||
656 | |||
657 | +int intel_cpuc_prepare(struct cpu_hw_events *cpuc, int cpu) | ||
658 | +{ | ||
659 | if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) { | ||
660 | cpuc->shared_regs = allocate_shared_regs(cpu); | ||
661 | if (!cpuc->shared_regs) | ||
662 | goto err; | ||
663 | } | ||
664 | |||
665 | - if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) { | ||
666 | + if (x86_pmu.flags & (PMU_FL_EXCL_CNTRS | PMU_FL_TFA)) { | ||
667 | size_t sz = X86_PMC_IDX_MAX * sizeof(struct event_constraint); | ||
668 | |||
669 | - cpuc->constraint_list = kzalloc(sz, GFP_KERNEL); | ||
670 | + cpuc->constraint_list = kzalloc_node(sz, GFP_KERNEL, cpu_to_node(cpu)); | ||
671 | if (!cpuc->constraint_list) | ||
672 | goto err_shared_regs; | ||
673 | + } | ||
674 | |||
675 | + if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) { | ||
676 | cpuc->excl_cntrs = allocate_excl_cntrs(cpu); | ||
677 | if (!cpuc->excl_cntrs) | ||
678 | goto err_constraint_list; | ||
679 | @@ -3352,6 +3415,11 @@ err: | ||
680 | return -ENOMEM; | ||
681 | } | ||
682 | |||
683 | +static int intel_pmu_cpu_prepare(int cpu) | ||
684 | +{ | ||
685 | + return intel_cpuc_prepare(&per_cpu(cpu_hw_events, cpu), cpu); | ||
686 | +} | ||
687 | + | ||
688 | static void flip_smm_bit(void *data) | ||
689 | { | ||
690 | unsigned long set = *(unsigned long *)data; | ||
691 | @@ -3423,9 +3491,8 @@ static void intel_pmu_cpu_starting(int cpu) | ||
692 | } | ||
693 | } | ||
694 | |||
695 | -static void free_excl_cntrs(int cpu) | ||
696 | +static void free_excl_cntrs(struct cpu_hw_events *cpuc) | ||
697 | { | ||
698 | - struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); | ||
699 | struct intel_excl_cntrs *c; | ||
700 | |||
701 | c = cpuc->excl_cntrs; | ||
702 | @@ -3433,9 +3500,10 @@ static void free_excl_cntrs(int cpu) | ||
703 | if (c->core_id == -1 || --c->refcnt == 0) | ||
704 | kfree(c); | ||
705 | cpuc->excl_cntrs = NULL; | ||
706 | - kfree(cpuc->constraint_list); | ||
707 | - cpuc->constraint_list = NULL; | ||
708 | } | ||
709 | + | ||
710 | + kfree(cpuc->constraint_list); | ||
711 | + cpuc->constraint_list = NULL; | ||
712 | } | ||
713 | |||
714 | static void intel_pmu_cpu_dying(int cpu) | ||
715 | @@ -3443,9 +3511,8 @@ static void intel_pmu_cpu_dying(int cpu) | ||
716 | fini_debug_store_on_cpu(cpu); | ||
717 | } | ||
718 | |||
719 | -static void intel_pmu_cpu_dead(int cpu) | ||
720 | +void intel_cpuc_finish(struct cpu_hw_events *cpuc) | ||
721 | { | ||
722 | - struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); | ||
723 | struct intel_shared_regs *pc; | ||
724 | |||
725 | pc = cpuc->shared_regs; | ||
726 | @@ -3455,7 +3522,12 @@ static void intel_pmu_cpu_dead(int cpu) | ||
727 | cpuc->shared_regs = NULL; | ||
728 | } | ||
729 | |||
730 | - free_excl_cntrs(cpu); | ||
731 | + free_excl_cntrs(cpuc); | ||
732 | +} | ||
733 | + | ||
734 | +static void intel_pmu_cpu_dead(int cpu) | ||
735 | +{ | ||
736 | + intel_cpuc_finish(&per_cpu(cpu_hw_events, cpu)); | ||
737 | } | ||
738 | |||
739 | static void intel_pmu_sched_task(struct perf_event_context *ctx, | ||
740 | @@ -3917,8 +3989,11 @@ static struct attribute *intel_pmu_caps_attrs[] = { | ||
741 | NULL | ||
742 | }; | ||
743 | |||
744 | +DEVICE_BOOL_ATTR(allow_tsx_force_abort, 0644, allow_tsx_force_abort); | ||
745 | + | ||
746 | static struct attribute *intel_pmu_attrs[] = { | ||
747 | &dev_attr_freeze_on_smi.attr, | ||
748 | + NULL, /* &dev_attr_allow_tsx_force_abort.attr.attr */ | ||
749 | NULL, | ||
750 | }; | ||
751 | |||
752 | @@ -4374,6 +4449,15 @@ __init int intel_pmu_init(void) | ||
753 | x86_pmu.cpu_events = get_hsw_events_attrs(); | ||
754 | intel_pmu_pebs_data_source_skl( | ||
755 | boot_cpu_data.x86_model == INTEL_FAM6_SKYLAKE_X); | ||
756 | + | ||
757 | + if (boot_cpu_has(X86_FEATURE_TSX_FORCE_ABORT)) { | ||
758 | + x86_pmu.flags |= PMU_FL_TFA; | ||
759 | + x86_pmu.get_event_constraints = tfa_get_event_constraints; | ||
760 | + x86_pmu.enable_all = intel_tfa_pmu_enable_all; | ||
761 | + x86_pmu.commit_scheduling = intel_tfa_commit_scheduling; | ||
762 | + intel_pmu_attrs[1] = &dev_attr_allow_tsx_force_abort.attr.attr; | ||
763 | + } | ||
764 | + | ||
765 | pr_cont("Skylake events, "); | ||
766 | name = "skylake"; | ||
767 | break; | ||
768 | @@ -4515,7 +4599,7 @@ static __init int fixup_ht_bug(void) | ||
769 | hardlockup_detector_perf_restart(); | ||
770 | |||
771 | for_each_online_cpu(c) | ||
772 | - free_excl_cntrs(c); | ||
773 | + free_excl_cntrs(&per_cpu(cpu_hw_events, c)); | ||
774 | |||
775 | cpus_read_unlock(); | ||
776 | pr_info("PMU erratum BJ122, BV98, HSD29 workaround disabled, HT off\n"); | ||
777 | diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h | ||
778 | index 0ee3a441ad79..5c424009b71f 100644 | ||
779 | --- a/arch/x86/events/perf_event.h | ||
780 | +++ b/arch/x86/events/perf_event.h | ||
781 | @@ -242,6 +242,11 @@ struct cpu_hw_events { | ||
782 | struct intel_excl_cntrs *excl_cntrs; | ||
783 | int excl_thread_id; /* 0 or 1 */ | ||
784 | |||
785 | + /* | ||
786 | + * SKL TSX_FORCE_ABORT shadow | ||
787 | + */ | ||
788 | + u64 tfa_shadow; | ||
789 | + | ||
790 | /* | ||
791 | * AMD specific bits | ||
792 | */ | ||
793 | @@ -679,6 +684,7 @@ do { \ | ||
794 | #define PMU_FL_EXCL_CNTRS 0x4 /* has exclusive counter requirements */ | ||
795 | #define PMU_FL_EXCL_ENABLED 0x8 /* exclusive counter active */ | ||
796 | #define PMU_FL_PEBS_ALL 0x10 /* all events are valid PEBS events */ | ||
797 | +#define PMU_FL_TFA 0x20 /* deal with TSX force abort */ | ||
798 | |||
799 | #define EVENT_VAR(_id) event_attr_##_id | ||
800 | #define EVENT_PTR(_id) &event_attr_##_id.attr.attr | ||
801 | @@ -887,7 +893,8 @@ struct event_constraint * | ||
802 | x86_get_event_constraints(struct cpu_hw_events *cpuc, int idx, | ||
803 | struct perf_event *event); | ||
804 | |||
805 | -struct intel_shared_regs *allocate_shared_regs(int cpu); | ||
806 | +extern int intel_cpuc_prepare(struct cpu_hw_events *cpuc, int cpu); | ||
807 | +extern void intel_cpuc_finish(struct cpu_hw_events *cpuc); | ||
808 | |||
809 | int intel_pmu_init(void); | ||
810 | |||
811 | @@ -1023,9 +1030,13 @@ static inline int intel_pmu_init(void) | ||
812 | return 0; | ||
813 | } | ||
814 | |||
815 | -static inline struct intel_shared_regs *allocate_shared_regs(int cpu) | ||
816 | +static inline int intel_cpuc_prepare(struct cpu_hw_event *cpuc, int cpu) | ||
817 | +{ | ||
818 | + return 0; | ||
819 | +} | ||
820 | + | ||
821 | +static inline void intel_cpuc_finish(struct cpu_hw_event *cpuc) | ||
822 | { | ||
823 | - return NULL; | ||
824 | } | ||
825 | |||
826 | static inline int is_ht_workaround_enabled(void) | ||
827 | diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h | ||
828 | index 89a048c2faec..7b31ee5223fc 100644 | ||
829 | --- a/arch/x86/include/asm/cpufeatures.h | ||
830 | +++ b/arch/x86/include/asm/cpufeatures.h | ||
831 | @@ -340,6 +340,7 @@ | ||
832 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */ | ||
833 | #define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */ | ||
834 | #define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */ | ||
835 | +#define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */ | ||
836 | #define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */ | ||
837 | #define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ | ||
838 | #define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */ | ||
839 | diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h | ||
840 | index 1f9de7635bcb..f14ca0be1e3f 100644 | ||
841 | --- a/arch/x86/include/asm/msr-index.h | ||
842 | +++ b/arch/x86/include/asm/msr-index.h | ||
843 | @@ -629,6 +629,12 @@ | ||
844 | |||
845 | #define MSR_IA32_TSC_DEADLINE 0x000006E0 | ||
846 | |||
847 | + | ||
848 | +#define MSR_TSX_FORCE_ABORT 0x0000010F | ||
849 | + | ||
850 | +#define MSR_TFA_RTM_FORCE_ABORT_BIT 0 | ||
851 | +#define MSR_TFA_RTM_FORCE_ABORT BIT_ULL(MSR_TFA_RTM_FORCE_ABORT_BIT) | ||
852 | + | ||
853 | /* P4/Xeon+ specific */ | ||
854 | #define MSR_IA32_MCG_EAX 0x00000180 | ||
855 | #define MSR_IA32_MCG_EBX 0x00000181 | ||
856 | diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h | ||
857 | index b99d497e342d..0b6352aabbd3 100644 | ||
858 | --- a/arch/x86/include/asm/page_64_types.h | ||
859 | +++ b/arch/x86/include/asm/page_64_types.h | ||
860 | @@ -7,7 +7,11 @@ | ||
861 | #endif | ||
862 | |||
863 | #ifdef CONFIG_KASAN | ||
864 | +#ifdef CONFIG_KASAN_EXTRA | ||
865 | +#define KASAN_STACK_ORDER 2 | ||
866 | +#else | ||
867 | #define KASAN_STACK_ORDER 1 | ||
868 | +#endif | ||
869 | #else | ||
870 | #define KASAN_STACK_ORDER 0 | ||
871 | #endif | ||
872 | diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c | ||
873 | index 07b5fc00b188..a4e7e100ed26 100644 | ||
874 | --- a/arch/x86/kernel/cpu/microcode/amd.c | ||
875 | +++ b/arch/x86/kernel/cpu/microcode/amd.c | ||
876 | @@ -707,7 +707,7 @@ load_microcode_amd(bool save, u8 family, const u8 *data, size_t size) | ||
877 | if (!p) { | ||
878 | return ret; | ||
879 | } else { | ||
880 | - if (boot_cpu_data.microcode == p->patch_id) | ||
881 | + if (boot_cpu_data.microcode >= p->patch_id) | ||
882 | return ret; | ||
883 | |||
884 | ret = UCODE_NEW; | ||
885 | diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c | ||
886 | index 278cd07228dd..9490a2845f14 100644 | ||
887 | --- a/arch/x86/kernel/kexec-bzimage64.c | ||
888 | +++ b/arch/x86/kernel/kexec-bzimage64.c | ||
889 | @@ -167,6 +167,9 @@ setup_efi_state(struct boot_params *params, unsigned long params_load_addr, | ||
890 | struct efi_info *current_ei = &boot_params.efi_info; | ||
891 | struct efi_info *ei = ¶ms->efi_info; | ||
892 | |||
893 | + if (!efi_enabled(EFI_RUNTIME_SERVICES)) | ||
894 | + return 0; | ||
895 | + | ||
896 | if (!current_ei->efi_memmap_size) | ||
897 | return 0; | ||
898 | |||
899 | diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c | ||
900 | index 13f4485ca388..bd372e896557 100644 | ||
901 | --- a/arch/x86/pci/fixup.c | ||
902 | +++ b/arch/x86/pci/fixup.c | ||
903 | @@ -641,6 +641,22 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x334b, quirk_no_aersid); | ||
904 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x334c, quirk_no_aersid); | ||
905 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x334d, quirk_no_aersid); | ||
906 | |||
907 | +static void quirk_intel_th_dnv(struct pci_dev *dev) | ||
908 | +{ | ||
909 | + struct resource *r = &dev->resource[4]; | ||
910 | + | ||
911 | + /* | ||
912 | + * Denverton reports 2k of RTIT_BAR (intel_th resource 4), which | ||
913 | + * appears to be 4 MB in reality. | ||
914 | + */ | ||
915 | + if (r->end == r->start + 0x7ff) { | ||
916 | + r->start = 0; | ||
917 | + r->end = 0x3fffff; | ||
918 | + r->flags |= IORESOURCE_UNSET; | ||
919 | + } | ||
920 | +} | ||
921 | +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x19e1, quirk_intel_th_dnv); | ||
922 | + | ||
923 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | ||
924 | |||
925 | #define AMD_141b_MMIO_BASE(x) (0x80 + (x) * 0x8) | ||
926 | diff --git a/arch/xtensa/configs/smp_lx200_defconfig b/arch/xtensa/configs/smp_lx200_defconfig | ||
927 | index 11fed6c06a7c..b5938160fb3d 100644 | ||
928 | --- a/arch/xtensa/configs/smp_lx200_defconfig | ||
929 | +++ b/arch/xtensa/configs/smp_lx200_defconfig | ||
930 | @@ -33,6 +33,7 @@ CONFIG_SMP=y | ||
931 | CONFIG_HOTPLUG_CPU=y | ||
932 | # CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX is not set | ||
933 | # CONFIG_PCI is not set | ||
934 | +CONFIG_VECTORS_OFFSET=0x00002000 | ||
935 | CONFIG_XTENSA_PLATFORM_XTFPGA=y | ||
936 | CONFIG_CMDLINE_BOOL=y | ||
937 | CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=96M@0" | ||
938 | diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S | ||
939 | index 9053a5622d2c..5bd38ea2da38 100644 | ||
940 | --- a/arch/xtensa/kernel/head.S | ||
941 | +++ b/arch/xtensa/kernel/head.S | ||
942 | @@ -280,12 +280,13 @@ should_never_return: | ||
943 | |||
944 | movi a2, cpu_start_ccount | ||
945 | 1: | ||
946 | + memw | ||
947 | l32i a3, a2, 0 | ||
948 | beqi a3, 0, 1b | ||
949 | movi a3, 0 | ||
950 | s32i a3, a2, 0 | ||
951 | - memw | ||
952 | 1: | ||
953 | + memw | ||
954 | l32i a3, a2, 0 | ||
955 | beqi a3, 0, 1b | ||
956 | wsr a3, ccount | ||
957 | @@ -321,11 +322,13 @@ ENTRY(cpu_restart) | ||
958 | rsr a0, prid | ||
959 | neg a2, a0 | ||
960 | movi a3, cpu_start_id | ||
961 | + memw | ||
962 | s32i a2, a3, 0 | ||
963 | #if XCHAL_DCACHE_IS_WRITEBACK | ||
964 | dhwbi a3, 0 | ||
965 | #endif | ||
966 | 1: | ||
967 | + memw | ||
968 | l32i a2, a3, 0 | ||
969 | dhi a3, 0 | ||
970 | bne a2, a0, 1b | ||
971 | diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c | ||
972 | index 932d64689bac..be1f280c322c 100644 | ||
973 | --- a/arch/xtensa/kernel/smp.c | ||
974 | +++ b/arch/xtensa/kernel/smp.c | ||
975 | @@ -83,7 +83,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | ||
976 | { | ||
977 | unsigned i; | ||
978 | |||
979 | - for (i = 0; i < max_cpus; ++i) | ||
980 | + for_each_possible_cpu(i) | ||
981 | set_cpu_present(i, true); | ||
982 | } | ||
983 | |||
984 | @@ -96,6 +96,11 @@ void __init smp_init_cpus(void) | ||
985 | pr_info("%s: Core Count = %d\n", __func__, ncpus); | ||
986 | pr_info("%s: Core Id = %d\n", __func__, core_id); | ||
987 | |||
988 | + if (ncpus > NR_CPUS) { | ||
989 | + ncpus = NR_CPUS; | ||
990 | + pr_info("%s: limiting core count by %d\n", __func__, ncpus); | ||
991 | + } | ||
992 | + | ||
993 | for (i = 0; i < ncpus; ++i) | ||
994 | set_cpu_possible(i, true); | ||
995 | } | ||
996 | @@ -195,9 +200,11 @@ static int boot_secondary(unsigned int cpu, struct task_struct *ts) | ||
997 | int i; | ||
998 | |||
999 | #ifdef CONFIG_HOTPLUG_CPU | ||
1000 | - cpu_start_id = cpu; | ||
1001 | - system_flush_invalidate_dcache_range( | ||
1002 | - (unsigned long)&cpu_start_id, sizeof(cpu_start_id)); | ||
1003 | + WRITE_ONCE(cpu_start_id, cpu); | ||
1004 | + /* Pairs with the third memw in the cpu_restart */ | ||
1005 | + mb(); | ||
1006 | + system_flush_invalidate_dcache_range((unsigned long)&cpu_start_id, | ||
1007 | + sizeof(cpu_start_id)); | ||
1008 | #endif | ||
1009 | smp_call_function_single(0, mx_cpu_start, (void *)cpu, 1); | ||
1010 | |||
1011 | @@ -206,18 +213,21 @@ static int boot_secondary(unsigned int cpu, struct task_struct *ts) | ||
1012 | ccount = get_ccount(); | ||
1013 | while (!ccount); | ||
1014 | |||
1015 | - cpu_start_ccount = ccount; | ||
1016 | + WRITE_ONCE(cpu_start_ccount, ccount); | ||
1017 | |||
1018 | - while (time_before(jiffies, timeout)) { | ||
1019 | + do { | ||
1020 | + /* | ||
1021 | + * Pairs with the first two memws in the | ||
1022 | + * .Lboot_secondary. | ||
1023 | + */ | ||
1024 | mb(); | ||
1025 | - if (!cpu_start_ccount) | ||
1026 | - break; | ||
1027 | - } | ||
1028 | + ccount = READ_ONCE(cpu_start_ccount); | ||
1029 | + } while (ccount && time_before(jiffies, timeout)); | ||
1030 | |||
1031 | - if (cpu_start_ccount) { | ||
1032 | + if (ccount) { | ||
1033 | smp_call_function_single(0, mx_cpu_stop, | ||
1034 | - (void *)cpu, 1); | ||
1035 | - cpu_start_ccount = 0; | ||
1036 | + (void *)cpu, 1); | ||
1037 | + WRITE_ONCE(cpu_start_ccount, 0); | ||
1038 | return -EIO; | ||
1039 | } | ||
1040 | } | ||
1041 | @@ -237,6 +247,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) | ||
1042 | pr_debug("%s: Calling wakeup_secondary(cpu:%d, idle:%p, sp: %08lx)\n", | ||
1043 | __func__, cpu, idle, start_info.stack); | ||
1044 | |||
1045 | + init_completion(&cpu_running); | ||
1046 | ret = boot_secondary(cpu, idle); | ||
1047 | if (ret == 0) { | ||
1048 | wait_for_completion_timeout(&cpu_running, | ||
1049 | @@ -298,8 +309,10 @@ void __cpu_die(unsigned int cpu) | ||
1050 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | ||
1051 | while (time_before(jiffies, timeout)) { | ||
1052 | system_invalidate_dcache_range((unsigned long)&cpu_start_id, | ||
1053 | - sizeof(cpu_start_id)); | ||
1054 | - if (cpu_start_id == -cpu) { | ||
1055 | + sizeof(cpu_start_id)); | ||
1056 | + /* Pairs with the second memw in the cpu_restart */ | ||
1057 | + mb(); | ||
1058 | + if (READ_ONCE(cpu_start_id) == -cpu) { | ||
1059 | platform_cpu_kill(cpu); | ||
1060 | return; | ||
1061 | } | ||
1062 | diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c | ||
1063 | index fd524a54d2ab..378186b5eb40 100644 | ||
1064 | --- a/arch/xtensa/kernel/time.c | ||
1065 | +++ b/arch/xtensa/kernel/time.c | ||
1066 | @@ -89,7 +89,7 @@ static int ccount_timer_shutdown(struct clock_event_device *evt) | ||
1067 | container_of(evt, struct ccount_timer, evt); | ||
1068 | |||
1069 | if (timer->irq_enabled) { | ||
1070 | - disable_irq(evt->irq); | ||
1071 | + disable_irq_nosync(evt->irq); | ||
1072 | timer->irq_enabled = 0; | ||
1073 | } | ||
1074 | return 0; | ||
1075 | diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c | ||
1076 | index 19923f8a029d..b154e057ca67 100644 | ||
1077 | --- a/block/blk-iolatency.c | ||
1078 | +++ b/block/blk-iolatency.c | ||
1079 | @@ -72,6 +72,7 @@ | ||
1080 | #include <linux/sched/loadavg.h> | ||
1081 | #include <linux/sched/signal.h> | ||
1082 | #include <trace/events/block.h> | ||
1083 | +#include <linux/blk-mq.h> | ||
1084 | #include "blk-rq-qos.h" | ||
1085 | #include "blk-stat.h" | ||
1086 | |||
1087 | @@ -568,6 +569,9 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio) | ||
1088 | return; | ||
1089 | |||
1090 | enabled = blk_iolatency_enabled(iolat->blkiolat); | ||
1091 | + if (!enabled) | ||
1092 | + return; | ||
1093 | + | ||
1094 | while (blkg && blkg->parent) { | ||
1095 | iolat = blkg_to_lat(blkg); | ||
1096 | if (!iolat) { | ||
1097 | @@ -577,7 +581,7 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio) | ||
1098 | rqw = &iolat->rq_wait; | ||
1099 | |||
1100 | atomic_dec(&rqw->inflight); | ||
1101 | - if (!enabled || iolat->min_lat_nsec == 0) | ||
1102 | + if (iolat->min_lat_nsec == 0) | ||
1103 | goto next; | ||
1104 | iolatency_record_time(iolat, &bio->bi_issue, now, | ||
1105 | issue_as_root); | ||
1106 | @@ -721,10 +725,13 @@ int blk_iolatency_init(struct request_queue *q) | ||
1107 | return 0; | ||
1108 | } | ||
1109 | |||
1110 | -static void iolatency_set_min_lat_nsec(struct blkcg_gq *blkg, u64 val) | ||
1111 | +/* | ||
1112 | + * return 1 for enabling iolatency, return -1 for disabling iolatency, otherwise | ||
1113 | + * return 0. | ||
1114 | + */ | ||
1115 | +static int iolatency_set_min_lat_nsec(struct blkcg_gq *blkg, u64 val) | ||
1116 | { | ||
1117 | struct iolatency_grp *iolat = blkg_to_lat(blkg); | ||
1118 | - struct blk_iolatency *blkiolat = iolat->blkiolat; | ||
1119 | u64 oldval = iolat->min_lat_nsec; | ||
1120 | |||
1121 | iolat->min_lat_nsec = val; | ||
1122 | @@ -733,9 +740,10 @@ static void iolatency_set_min_lat_nsec(struct blkcg_gq *blkg, u64 val) | ||
1123 | BLKIOLATENCY_MAX_WIN_SIZE); | ||
1124 | |||
1125 | if (!oldval && val) | ||
1126 | - atomic_inc(&blkiolat->enabled); | ||
1127 | + return 1; | ||
1128 | if (oldval && !val) | ||
1129 | - atomic_dec(&blkiolat->enabled); | ||
1130 | + return -1; | ||
1131 | + return 0; | ||
1132 | } | ||
1133 | |||
1134 | static void iolatency_clear_scaling(struct blkcg_gq *blkg) | ||
1135 | @@ -768,6 +776,7 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf, | ||
1136 | u64 lat_val = 0; | ||
1137 | u64 oldval; | ||
1138 | int ret; | ||
1139 | + int enable = 0; | ||
1140 | |||
1141 | ret = blkg_conf_prep(blkcg, &blkcg_policy_iolatency, buf, &ctx); | ||
1142 | if (ret) | ||
1143 | @@ -803,7 +812,12 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf, | ||
1144 | blkg = ctx.blkg; | ||
1145 | oldval = iolat->min_lat_nsec; | ||
1146 | |||
1147 | - iolatency_set_min_lat_nsec(blkg, lat_val); | ||
1148 | + enable = iolatency_set_min_lat_nsec(blkg, lat_val); | ||
1149 | + if (enable) { | ||
1150 | + WARN_ON_ONCE(!blk_get_queue(blkg->q)); | ||
1151 | + blkg_get(blkg); | ||
1152 | + } | ||
1153 | + | ||
1154 | if (oldval != iolat->min_lat_nsec) { | ||
1155 | iolatency_clear_scaling(blkg); | ||
1156 | } | ||
1157 | @@ -811,6 +825,24 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf, | ||
1158 | ret = 0; | ||
1159 | out: | ||
1160 | blkg_conf_finish(&ctx); | ||
1161 | + if (ret == 0 && enable) { | ||
1162 | + struct iolatency_grp *tmp = blkg_to_lat(blkg); | ||
1163 | + struct blk_iolatency *blkiolat = tmp->blkiolat; | ||
1164 | + | ||
1165 | + blk_mq_freeze_queue(blkg->q); | ||
1166 | + | ||
1167 | + if (enable == 1) | ||
1168 | + atomic_inc(&blkiolat->enabled); | ||
1169 | + else if (enable == -1) | ||
1170 | + atomic_dec(&blkiolat->enabled); | ||
1171 | + else | ||
1172 | + WARN_ON_ONCE(1); | ||
1173 | + | ||
1174 | + blk_mq_unfreeze_queue(blkg->q); | ||
1175 | + | ||
1176 | + blkg_put(blkg); | ||
1177 | + blk_put_queue(blkg->q); | ||
1178 | + } | ||
1179 | return ret ?: nbytes; | ||
1180 | } | ||
1181 | |||
1182 | @@ -910,8 +942,14 @@ static void iolatency_pd_offline(struct blkg_policy_data *pd) | ||
1183 | { | ||
1184 | struct iolatency_grp *iolat = pd_to_lat(pd); | ||
1185 | struct blkcg_gq *blkg = lat_to_blkg(iolat); | ||
1186 | + struct blk_iolatency *blkiolat = iolat->blkiolat; | ||
1187 | + int ret; | ||
1188 | |||
1189 | - iolatency_set_min_lat_nsec(blkg, 0); | ||
1190 | + ret = iolatency_set_min_lat_nsec(blkg, 0); | ||
1191 | + if (ret == 1) | ||
1192 | + atomic_inc(&blkiolat->enabled); | ||
1193 | + if (ret == -1) | ||
1194 | + atomic_dec(&blkiolat->enabled); | ||
1195 | iolatency_clear_scaling(blkg); | ||
1196 | } | ||
1197 | |||
1198 | diff --git a/drivers/base/dd.c b/drivers/base/dd.c | ||
1199 | index 7caa1adaf62a..f5b74856784a 100644 | ||
1200 | --- a/drivers/base/dd.c | ||
1201 | +++ b/drivers/base/dd.c | ||
1202 | @@ -963,9 +963,9 @@ static void __device_release_driver(struct device *dev, struct device *parent) | ||
1203 | drv->remove(dev); | ||
1204 | |||
1205 | device_links_driver_cleanup(dev); | ||
1206 | - dma_deconfigure(dev); | ||
1207 | |||
1208 | devres_release_all(dev); | ||
1209 | + dma_deconfigure(dev); | ||
1210 | dev->driver = NULL; | ||
1211 | dev_set_drvdata(dev, NULL); | ||
1212 | if (dev->pm_domain && dev->pm_domain->dismiss) | ||
1213 | diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c | ||
1214 | index fa1a196350f1..3bf11a620094 100644 | ||
1215 | --- a/drivers/clk/qcom/gcc-sdm845.c | ||
1216 | +++ b/drivers/clk/qcom/gcc-sdm845.c | ||
1217 | @@ -131,8 +131,8 @@ static const char * const gcc_parent_names_6[] = { | ||
1218 | "core_bi_pll_test_se", | ||
1219 | }; | ||
1220 | |||
1221 | -static const char * const gcc_parent_names_7[] = { | ||
1222 | - "bi_tcxo", | ||
1223 | +static const char * const gcc_parent_names_7_ao[] = { | ||
1224 | + "bi_tcxo_ao", | ||
1225 | "gpll0", | ||
1226 | "gpll0_out_even", | ||
1227 | "core_bi_pll_test_se", | ||
1228 | @@ -144,6 +144,12 @@ static const char * const gcc_parent_names_8[] = { | ||
1229 | "core_bi_pll_test_se", | ||
1230 | }; | ||
1231 | |||
1232 | +static const char * const gcc_parent_names_8_ao[] = { | ||
1233 | + "bi_tcxo_ao", | ||
1234 | + "gpll0", | ||
1235 | + "core_bi_pll_test_se", | ||
1236 | +}; | ||
1237 | + | ||
1238 | static const struct parent_map gcc_parent_map_10[] = { | ||
1239 | { P_BI_TCXO, 0 }, | ||
1240 | { P_GPLL0_OUT_MAIN, 1 }, | ||
1241 | @@ -226,7 +232,7 @@ static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { | ||
1242 | .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, | ||
1243 | .clkr.hw.init = &(struct clk_init_data){ | ||
1244 | .name = "gcc_cpuss_ahb_clk_src", | ||
1245 | - .parent_names = gcc_parent_names_7, | ||
1246 | + .parent_names = gcc_parent_names_7_ao, | ||
1247 | .num_parents = 4, | ||
1248 | .ops = &clk_rcg2_ops, | ||
1249 | }, | ||
1250 | @@ -245,7 +251,7 @@ static struct clk_rcg2 gcc_cpuss_rbcpr_clk_src = { | ||
1251 | .freq_tbl = ftbl_gcc_cpuss_rbcpr_clk_src, | ||
1252 | .clkr.hw.init = &(struct clk_init_data){ | ||
1253 | .name = "gcc_cpuss_rbcpr_clk_src", | ||
1254 | - .parent_names = gcc_parent_names_8, | ||
1255 | + .parent_names = gcc_parent_names_8_ao, | ||
1256 | .num_parents = 3, | ||
1257 | .ops = &clk_rcg2_ops, | ||
1258 | }, | ||
1259 | diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c | ||
1260 | index ccfb4d9a152a..079f0beda8b6 100644 | ||
1261 | --- a/drivers/clk/ti/divider.c | ||
1262 | +++ b/drivers/clk/ti/divider.c | ||
1263 | @@ -367,8 +367,10 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, | ||
1264 | num_dividers = i; | ||
1265 | |||
1266 | tmp = kcalloc(valid_div + 1, sizeof(*tmp), GFP_KERNEL); | ||
1267 | - if (!tmp) | ||
1268 | + if (!tmp) { | ||
1269 | + *table = ERR_PTR(-ENOMEM); | ||
1270 | return -ENOMEM; | ||
1271 | + } | ||
1272 | |||
1273 | valid_div = 0; | ||
1274 | *width = 0; | ||
1275 | @@ -403,6 +405,7 @@ struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup) | ||
1276 | { | ||
1277 | struct clk_omap_divider *div; | ||
1278 | struct clk_omap_reg *reg; | ||
1279 | + int ret; | ||
1280 | |||
1281 | if (!setup) | ||
1282 | return NULL; | ||
1283 | @@ -422,6 +425,12 @@ struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup) | ||
1284 | div->flags |= CLK_DIVIDER_POWER_OF_TWO; | ||
1285 | |||
1286 | div->table = _get_div_table_from_setup(setup, &div->width); | ||
1287 | + if (IS_ERR(div->table)) { | ||
1288 | + ret = PTR_ERR(div->table); | ||
1289 | + kfree(div); | ||
1290 | + return ERR_PTR(ret); | ||
1291 | + } | ||
1292 | + | ||
1293 | |||
1294 | div->shift = setup->bit_shift; | ||
1295 | div->latch = -EINVAL; | ||
1296 | diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c | ||
1297 | index 4bf72561667c..a75b95fac3bd 100644 | ||
1298 | --- a/drivers/dma/at_xdmac.c | ||
1299 | +++ b/drivers/dma/at_xdmac.c | ||
1300 | @@ -203,6 +203,7 @@ struct at_xdmac_chan { | ||
1301 | u32 save_cim; | ||
1302 | u32 save_cnda; | ||
1303 | u32 save_cndc; | ||
1304 | + u32 irq_status; | ||
1305 | unsigned long status; | ||
1306 | struct tasklet_struct tasklet; | ||
1307 | struct dma_slave_config sconfig; | ||
1308 | @@ -1580,8 +1581,8 @@ static void at_xdmac_tasklet(unsigned long data) | ||
1309 | struct at_xdmac_desc *desc; | ||
1310 | u32 error_mask; | ||
1311 | |||
1312 | - dev_dbg(chan2dev(&atchan->chan), "%s: status=0x%08lx\n", | ||
1313 | - __func__, atchan->status); | ||
1314 | + dev_dbg(chan2dev(&atchan->chan), "%s: status=0x%08x\n", | ||
1315 | + __func__, atchan->irq_status); | ||
1316 | |||
1317 | error_mask = AT_XDMAC_CIS_RBEIS | ||
1318 | | AT_XDMAC_CIS_WBEIS | ||
1319 | @@ -1589,15 +1590,15 @@ static void at_xdmac_tasklet(unsigned long data) | ||
1320 | |||
1321 | if (at_xdmac_chan_is_cyclic(atchan)) { | ||
1322 | at_xdmac_handle_cyclic(atchan); | ||
1323 | - } else if ((atchan->status & AT_XDMAC_CIS_LIS) | ||
1324 | - || (atchan->status & error_mask)) { | ||
1325 | + } else if ((atchan->irq_status & AT_XDMAC_CIS_LIS) | ||
1326 | + || (atchan->irq_status & error_mask)) { | ||
1327 | struct dma_async_tx_descriptor *txd; | ||
1328 | |||
1329 | - if (atchan->status & AT_XDMAC_CIS_RBEIS) | ||
1330 | + if (atchan->irq_status & AT_XDMAC_CIS_RBEIS) | ||
1331 | dev_err(chan2dev(&atchan->chan), "read bus error!!!"); | ||
1332 | - if (atchan->status & AT_XDMAC_CIS_WBEIS) | ||
1333 | + if (atchan->irq_status & AT_XDMAC_CIS_WBEIS) | ||
1334 | dev_err(chan2dev(&atchan->chan), "write bus error!!!"); | ||
1335 | - if (atchan->status & AT_XDMAC_CIS_ROIS) | ||
1336 | + if (atchan->irq_status & AT_XDMAC_CIS_ROIS) | ||
1337 | dev_err(chan2dev(&atchan->chan), "request overflow error!!!"); | ||
1338 | |||
1339 | spin_lock_bh(&atchan->lock); | ||
1340 | @@ -1652,7 +1653,7 @@ static irqreturn_t at_xdmac_interrupt(int irq, void *dev_id) | ||
1341 | atchan = &atxdmac->chan[i]; | ||
1342 | chan_imr = at_xdmac_chan_read(atchan, AT_XDMAC_CIM); | ||
1343 | chan_status = at_xdmac_chan_read(atchan, AT_XDMAC_CIS); | ||
1344 | - atchan->status = chan_status & chan_imr; | ||
1345 | + atchan->irq_status = chan_status & chan_imr; | ||
1346 | dev_vdbg(atxdmac->dma.dev, | ||
1347 | "%s: chan%d: imr=0x%x, status=0x%x\n", | ||
1348 | __func__, i, chan_imr, chan_status); | ||
1349 | @@ -1666,7 +1667,7 @@ static irqreturn_t at_xdmac_interrupt(int irq, void *dev_id) | ||
1350 | at_xdmac_chan_read(atchan, AT_XDMAC_CDA), | ||
1351 | at_xdmac_chan_read(atchan, AT_XDMAC_CUBC)); | ||
1352 | |||
1353 | - if (atchan->status & (AT_XDMAC_CIS_RBEIS | AT_XDMAC_CIS_WBEIS)) | ||
1354 | + if (atchan->irq_status & (AT_XDMAC_CIS_RBEIS | AT_XDMAC_CIS_WBEIS)) | ||
1355 | at_xdmac_write(atxdmac, AT_XDMAC_GD, atchan->mask); | ||
1356 | |||
1357 | tasklet_schedule(&atchan->tasklet); | ||
1358 | diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c | ||
1359 | index aa1712beb0cc..7b7fba0c9253 100644 | ||
1360 | --- a/drivers/dma/dmatest.c | ||
1361 | +++ b/drivers/dma/dmatest.c | ||
1362 | @@ -642,11 +642,9 @@ static int dmatest_func(void *data) | ||
1363 | srcs[i] = um->addr[i] + src_off; | ||
1364 | ret = dma_mapping_error(dev->dev, um->addr[i]); | ||
1365 | if (ret) { | ||
1366 | - dmaengine_unmap_put(um); | ||
1367 | result("src mapping error", total_tests, | ||
1368 | src_off, dst_off, len, ret); | ||
1369 | - failed_tests++; | ||
1370 | - continue; | ||
1371 | + goto error_unmap_continue; | ||
1372 | } | ||
1373 | um->to_cnt++; | ||
1374 | } | ||
1375 | @@ -661,11 +659,9 @@ static int dmatest_func(void *data) | ||
1376 | DMA_BIDIRECTIONAL); | ||
1377 | ret = dma_mapping_error(dev->dev, dsts[i]); | ||
1378 | if (ret) { | ||
1379 | - dmaengine_unmap_put(um); | ||
1380 | result("dst mapping error", total_tests, | ||
1381 | src_off, dst_off, len, ret); | ||
1382 | - failed_tests++; | ||
1383 | - continue; | ||
1384 | + goto error_unmap_continue; | ||
1385 | } | ||
1386 | um->bidi_cnt++; | ||
1387 | } | ||
1388 | @@ -693,12 +689,10 @@ static int dmatest_func(void *data) | ||
1389 | } | ||
1390 | |||
1391 | if (!tx) { | ||
1392 | - dmaengine_unmap_put(um); | ||
1393 | result("prep error", total_tests, src_off, | ||
1394 | dst_off, len, ret); | ||
1395 | msleep(100); | ||
1396 | - failed_tests++; | ||
1397 | - continue; | ||
1398 | + goto error_unmap_continue; | ||
1399 | } | ||
1400 | |||
1401 | done->done = false; | ||
1402 | @@ -707,12 +701,10 @@ static int dmatest_func(void *data) | ||
1403 | cookie = tx->tx_submit(tx); | ||
1404 | |||
1405 | if (dma_submit_error(cookie)) { | ||
1406 | - dmaengine_unmap_put(um); | ||
1407 | result("submit error", total_tests, src_off, | ||
1408 | dst_off, len, ret); | ||
1409 | msleep(100); | ||
1410 | - failed_tests++; | ||
1411 | - continue; | ||
1412 | + goto error_unmap_continue; | ||
1413 | } | ||
1414 | dma_async_issue_pending(chan); | ||
1415 | |||
1416 | @@ -725,16 +717,14 @@ static int dmatest_func(void *data) | ||
1417 | dmaengine_unmap_put(um); | ||
1418 | result("test timed out", total_tests, src_off, dst_off, | ||
1419 | len, 0); | ||
1420 | - failed_tests++; | ||
1421 | - continue; | ||
1422 | + goto error_unmap_continue; | ||
1423 | } else if (status != DMA_COMPLETE) { | ||
1424 | dmaengine_unmap_put(um); | ||
1425 | result(status == DMA_ERROR ? | ||
1426 | "completion error status" : | ||
1427 | "completion busy status", total_tests, src_off, | ||
1428 | dst_off, len, ret); | ||
1429 | - failed_tests++; | ||
1430 | - continue; | ||
1431 | + goto error_unmap_continue; | ||
1432 | } | ||
1433 | |||
1434 | dmaengine_unmap_put(um); | ||
1435 | @@ -779,6 +769,12 @@ static int dmatest_func(void *data) | ||
1436 | verbose_result("test passed", total_tests, src_off, | ||
1437 | dst_off, len, 0); | ||
1438 | } | ||
1439 | + | ||
1440 | + continue; | ||
1441 | + | ||
1442 | +error_unmap_continue: | ||
1443 | + dmaengine_unmap_put(um); | ||
1444 | + failed_tests++; | ||
1445 | } | ||
1446 | ktime = ktime_sub(ktime_get(), ktime); | ||
1447 | ktime = ktime_sub(ktime, comparetime); | ||
1448 | diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c | ||
1449 | index 6bc8e6640d71..c51462f5aa1e 100644 | ||
1450 | --- a/drivers/firmware/iscsi_ibft.c | ||
1451 | +++ b/drivers/firmware/iscsi_ibft.c | ||
1452 | @@ -542,6 +542,7 @@ static umode_t __init ibft_check_tgt_for(void *data, int type) | ||
1453 | case ISCSI_BOOT_TGT_NIC_ASSOC: | ||
1454 | case ISCSI_BOOT_TGT_CHAP_TYPE: | ||
1455 | rc = S_IRUGO; | ||
1456 | + break; | ||
1457 | case ISCSI_BOOT_TGT_NAME: | ||
1458 | if (tgt->tgt_name_len) | ||
1459 | rc = S_IRUGO; | ||
1460 | diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c | ||
1461 | index d4ad6d0e02a2..7e09ce75ffb2 100644 | ||
1462 | --- a/drivers/gpio/gpio-vf610.c | ||
1463 | +++ b/drivers/gpio/gpio-vf610.c | ||
1464 | @@ -259,6 +259,7 @@ static int vf610_gpio_probe(struct platform_device *pdev) | ||
1465 | struct vf610_gpio_port *port; | ||
1466 | struct resource *iores; | ||
1467 | struct gpio_chip *gc; | ||
1468 | + int i; | ||
1469 | int ret; | ||
1470 | |||
1471 | port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); | ||
1472 | @@ -298,6 +299,10 @@ static int vf610_gpio_probe(struct platform_device *pdev) | ||
1473 | if (ret < 0) | ||
1474 | return ret; | ||
1475 | |||
1476 | + /* Mask all GPIO interrupts */ | ||
1477 | + for (i = 0; i < gc->ngpio; i++) | ||
1478 | + vf610_gpio_writel(0, port->base + PORT_PCR(i)); | ||
1479 | + | ||
1480 | /* Clear the interrupt status register for all GPIO's */ | ||
1481 | vf610_gpio_writel(~0, port->base + PORT_ISFR); | ||
1482 | |||
1483 | diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | ||
1484 | index 7b4e657a95c7..c3df75a9f65d 100644 | ||
1485 | --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | ||
1486 | +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | ||
1487 | @@ -1443,7 +1443,8 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, | ||
1488 | effective_mode &= ~S_IWUSR; | ||
1489 | |||
1490 | if ((adev->flags & AMD_IS_APU) && | ||
1491 | - (attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr || | ||
1492 | + (attr == &sensor_dev_attr_power1_average.dev_attr.attr || | ||
1493 | + attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr || | ||
1494 | attr == &sensor_dev_attr_power1_cap_min.dev_attr.attr|| | ||
1495 | attr == &sensor_dev_attr_power1_cap.dev_attr.attr)) | ||
1496 | return 0; | ||
1497 | diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | ||
1498 | index 1c5d97f4b4dd..8dcf6227ab99 100644 | ||
1499 | --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | ||
1500 | +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | ||
1501 | @@ -37,6 +37,7 @@ | ||
1502 | #include "amdgpu_display.h" | ||
1503 | #include <drm/amdgpu_drm.h> | ||
1504 | #include <linux/dma-buf.h> | ||
1505 | +#include <linux/dma-fence-array.h> | ||
1506 | |||
1507 | static const struct dma_buf_ops amdgpu_dmabuf_ops; | ||
1508 | |||
1509 | @@ -188,6 +189,48 @@ error: | ||
1510 | return ERR_PTR(ret); | ||
1511 | } | ||
1512 | |||
1513 | +static int | ||
1514 | +__reservation_object_make_exclusive(struct reservation_object *obj) | ||
1515 | +{ | ||
1516 | + struct dma_fence **fences; | ||
1517 | + unsigned int count; | ||
1518 | + int r; | ||
1519 | + | ||
1520 | + if (!reservation_object_get_list(obj)) /* no shared fences to convert */ | ||
1521 | + return 0; | ||
1522 | + | ||
1523 | + r = reservation_object_get_fences_rcu(obj, NULL, &count, &fences); | ||
1524 | + if (r) | ||
1525 | + return r; | ||
1526 | + | ||
1527 | + if (count == 0) { | ||
1528 | + /* Now that was unexpected. */ | ||
1529 | + } else if (count == 1) { | ||
1530 | + reservation_object_add_excl_fence(obj, fences[0]); | ||
1531 | + dma_fence_put(fences[0]); | ||
1532 | + kfree(fences); | ||
1533 | + } else { | ||
1534 | + struct dma_fence_array *array; | ||
1535 | + | ||
1536 | + array = dma_fence_array_create(count, fences, | ||
1537 | + dma_fence_context_alloc(1), 0, | ||
1538 | + false); | ||
1539 | + if (!array) | ||
1540 | + goto err_fences_put; | ||
1541 | + | ||
1542 | + reservation_object_add_excl_fence(obj, &array->base); | ||
1543 | + dma_fence_put(&array->base); | ||
1544 | + } | ||
1545 | + | ||
1546 | + return 0; | ||
1547 | + | ||
1548 | +err_fences_put: | ||
1549 | + while (count--) | ||
1550 | + dma_fence_put(fences[count]); | ||
1551 | + kfree(fences); | ||
1552 | + return -ENOMEM; | ||
1553 | +} | ||
1554 | + | ||
1555 | /** | ||
1556 | * amdgpu_gem_map_attach - &dma_buf_ops.attach implementation | ||
1557 | * @dma_buf: shared DMA buffer | ||
1558 | @@ -219,16 +262,16 @@ static int amdgpu_gem_map_attach(struct dma_buf *dma_buf, | ||
1559 | |||
1560 | if (attach->dev->driver != adev->dev->driver) { | ||
1561 | /* | ||
1562 | - * Wait for all shared fences to complete before we switch to future | ||
1563 | - * use of exclusive fence on this prime shared bo. | ||
1564 | + * We only create shared fences for internal use, but importers | ||
1565 | + * of the dmabuf rely on exclusive fences for implicitly | ||
1566 | + * tracking write hazards. As any of the current fences may | ||
1567 | + * correspond to a write, we need to convert all existing | ||
1568 | + * fences on the reservation object into a single exclusive | ||
1569 | + * fence. | ||
1570 | */ | ||
1571 | - r = reservation_object_wait_timeout_rcu(bo->tbo.resv, | ||
1572 | - true, false, | ||
1573 | - MAX_SCHEDULE_TIMEOUT); | ||
1574 | - if (unlikely(r < 0)) { | ||
1575 | - DRM_DEBUG_PRIME("Fence wait failed: %li\n", r); | ||
1576 | + r = __reservation_object_make_exclusive(bo->tbo.resv); | ||
1577 | + if (r) | ||
1578 | goto error_unreserve; | ||
1579 | - } | ||
1580 | } | ||
1581 | |||
1582 | /* pin buffer into GTT */ | ||
1583 | diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | ||
1584 | index 6a84526e20e0..49fe5084c53d 100644 | ||
1585 | --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | ||
1586 | +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | ||
1587 | @@ -3011,14 +3011,15 @@ void amdgpu_vm_get_task_info(struct amdgpu_device *adev, unsigned int pasid, | ||
1588 | struct amdgpu_task_info *task_info) | ||
1589 | { | ||
1590 | struct amdgpu_vm *vm; | ||
1591 | + unsigned long flags; | ||
1592 | |||
1593 | - spin_lock(&adev->vm_manager.pasid_lock); | ||
1594 | + spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags); | ||
1595 | |||
1596 | vm = idr_find(&adev->vm_manager.pasid_idr, pasid); | ||
1597 | if (vm) | ||
1598 | *task_info = vm->task_info; | ||
1599 | |||
1600 | - spin_unlock(&adev->vm_manager.pasid_lock); | ||
1601 | + spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); | ||
1602 | } | ||
1603 | |||
1604 | /** | ||
1605 | diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c | ||
1606 | index d587779a80b4..a97294ac96d5 100644 | ||
1607 | --- a/drivers/gpu/drm/radeon/ci_dpm.c | ||
1608 | +++ b/drivers/gpu/drm/radeon/ci_dpm.c | ||
1609 | @@ -5676,7 +5676,7 @@ int ci_dpm_init(struct radeon_device *rdev) | ||
1610 | u16 data_offset, size; | ||
1611 | u8 frev, crev; | ||
1612 | struct ci_power_info *pi; | ||
1613 | - enum pci_bus_speed speed_cap; | ||
1614 | + enum pci_bus_speed speed_cap = PCI_SPEED_UNKNOWN; | ||
1615 | struct pci_dev *root = rdev->pdev->bus->self; | ||
1616 | int ret; | ||
1617 | |||
1618 | @@ -5685,7 +5685,8 @@ int ci_dpm_init(struct radeon_device *rdev) | ||
1619 | return -ENOMEM; | ||
1620 | rdev->pm.dpm.priv = pi; | ||
1621 | |||
1622 | - speed_cap = pcie_get_speed_cap(root); | ||
1623 | + if (!pci_is_root_bus(rdev->pdev->bus)) | ||
1624 | + speed_cap = pcie_get_speed_cap(root); | ||
1625 | if (speed_cap == PCI_SPEED_UNKNOWN) { | ||
1626 | pi->sys_pcie_mask = 0; | ||
1627 | } else { | ||
1628 | diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c | ||
1629 | index 8fb60b3af015..0a785ef0ab66 100644 | ||
1630 | --- a/drivers/gpu/drm/radeon/si_dpm.c | ||
1631 | +++ b/drivers/gpu/drm/radeon/si_dpm.c | ||
1632 | @@ -6899,7 +6899,7 @@ int si_dpm_init(struct radeon_device *rdev) | ||
1633 | struct ni_power_info *ni_pi; | ||
1634 | struct si_power_info *si_pi; | ||
1635 | struct atom_clock_dividers dividers; | ||
1636 | - enum pci_bus_speed speed_cap; | ||
1637 | + enum pci_bus_speed speed_cap = PCI_SPEED_UNKNOWN; | ||
1638 | struct pci_dev *root = rdev->pdev->bus->self; | ||
1639 | int ret; | ||
1640 | |||
1641 | @@ -6911,7 +6911,8 @@ int si_dpm_init(struct radeon_device *rdev) | ||
1642 | eg_pi = &ni_pi->eg; | ||
1643 | pi = &eg_pi->rv7xx; | ||
1644 | |||
1645 | - speed_cap = pcie_get_speed_cap(root); | ||
1646 | + if (!pci_is_root_bus(rdev->pdev->bus)) | ||
1647 | + speed_cap = pcie_get_speed_cap(root); | ||
1648 | if (speed_cap == PCI_SPEED_UNKNOWN) { | ||
1649 | si_pi->sys_pcie_mask = 0; | ||
1650 | } else { | ||
1651 | diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c | ||
1652 | index 3fb084f802e2..8c31c9ab06f8 100644 | ||
1653 | --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c | ||
1654 | +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c | ||
1655 | @@ -672,6 +672,7 @@ static int sun4i_tcon_init_clocks(struct device *dev, | ||
1656 | return PTR_ERR(tcon->sclk0); | ||
1657 | } | ||
1658 | } | ||
1659 | + clk_prepare_enable(tcon->sclk0); | ||
1660 | |||
1661 | if (tcon->quirks->has_channel_1) { | ||
1662 | tcon->sclk1 = devm_clk_get(dev, "tcon-ch1"); | ||
1663 | @@ -686,6 +687,7 @@ static int sun4i_tcon_init_clocks(struct device *dev, | ||
1664 | |||
1665 | static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon) | ||
1666 | { | ||
1667 | + clk_disable_unprepare(tcon->sclk0); | ||
1668 | clk_disable_unprepare(tcon->clk); | ||
1669 | } | ||
1670 | |||
1671 | diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c | ||
1672 | index 65d06a819307..2ac86096ddd9 100644 | ||
1673 | --- a/drivers/i2c/busses/i2c-omap.c | ||
1674 | +++ b/drivers/i2c/busses/i2c-omap.c | ||
1675 | @@ -1498,8 +1498,7 @@ static int omap_i2c_remove(struct platform_device *pdev) | ||
1676 | return 0; | ||
1677 | } | ||
1678 | |||
1679 | -#ifdef CONFIG_PM | ||
1680 | -static int omap_i2c_runtime_suspend(struct device *dev) | ||
1681 | +static int __maybe_unused omap_i2c_runtime_suspend(struct device *dev) | ||
1682 | { | ||
1683 | struct omap_i2c_dev *omap = dev_get_drvdata(dev); | ||
1684 | |||
1685 | @@ -1525,7 +1524,7 @@ static int omap_i2c_runtime_suspend(struct device *dev) | ||
1686 | return 0; | ||
1687 | } | ||
1688 | |||
1689 | -static int omap_i2c_runtime_resume(struct device *dev) | ||
1690 | +static int __maybe_unused omap_i2c_runtime_resume(struct device *dev) | ||
1691 | { | ||
1692 | struct omap_i2c_dev *omap = dev_get_drvdata(dev); | ||
1693 | |||
1694 | @@ -1540,20 +1539,18 @@ static int omap_i2c_runtime_resume(struct device *dev) | ||
1695 | } | ||
1696 | |||
1697 | static const struct dev_pm_ops omap_i2c_pm_ops = { | ||
1698 | + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | ||
1699 | + pm_runtime_force_resume) | ||
1700 | SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend, | ||
1701 | omap_i2c_runtime_resume, NULL) | ||
1702 | }; | ||
1703 | -#define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops) | ||
1704 | -#else | ||
1705 | -#define OMAP_I2C_PM_OPS NULL | ||
1706 | -#endif /* CONFIG_PM */ | ||
1707 | |||
1708 | static struct platform_driver omap_i2c_driver = { | ||
1709 | .probe = omap_i2c_probe, | ||
1710 | .remove = omap_i2c_remove, | ||
1711 | .driver = { | ||
1712 | .name = "omap_i2c", | ||
1713 | - .pm = OMAP_I2C_PM_OPS, | ||
1714 | + .pm = &omap_i2c_pm_ops, | ||
1715 | .of_match_table = of_match_ptr(omap_i2c_of_match), | ||
1716 | }, | ||
1717 | }; | ||
1718 | diff --git a/drivers/infiniband/hw/hfi1/ud.c b/drivers/infiniband/hw/hfi1/ud.c | ||
1719 | index 70d39fc450a1..54eb69564264 100644 | ||
1720 | --- a/drivers/infiniband/hw/hfi1/ud.c | ||
1721 | +++ b/drivers/infiniband/hw/hfi1/ud.c | ||
1722 | @@ -980,7 +980,6 @@ void hfi1_ud_rcv(struct hfi1_packet *packet) | ||
1723 | opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) { | ||
1724 | wc.ex.imm_data = packet->ohdr->u.ud.imm_data; | ||
1725 | wc.wc_flags = IB_WC_WITH_IMM; | ||
1726 | - tlen -= sizeof(u32); | ||
1727 | } else if (opcode == IB_OPCODE_UD_SEND_ONLY) { | ||
1728 | wc.ex.imm_data = 0; | ||
1729 | wc.wc_flags = 0; | ||
1730 | diff --git a/drivers/infiniband/hw/qib/qib_ud.c b/drivers/infiniband/hw/qib/qib_ud.c | ||
1731 | index f8d029a2390f..bce2b5cd3c7b 100644 | ||
1732 | --- a/drivers/infiniband/hw/qib/qib_ud.c | ||
1733 | +++ b/drivers/infiniband/hw/qib/qib_ud.c | ||
1734 | @@ -513,7 +513,6 @@ void qib_ud_rcv(struct qib_ibport *ibp, struct ib_header *hdr, | ||
1735 | opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) { | ||
1736 | wc.ex.imm_data = ohdr->u.ud.imm_data; | ||
1737 | wc.wc_flags = IB_WC_WITH_IMM; | ||
1738 | - tlen -= sizeof(u32); | ||
1739 | } else if (opcode == IB_OPCODE_UD_SEND_ONLY) { | ||
1740 | wc.ex.imm_data = 0; | ||
1741 | wc.wc_flags = 0; | ||
1742 | diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h | ||
1743 | index 1abe3c62f106..b22d02c9de90 100644 | ||
1744 | --- a/drivers/infiniband/ulp/ipoib/ipoib.h | ||
1745 | +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | ||
1746 | @@ -248,7 +248,6 @@ struct ipoib_cm_tx { | ||
1747 | struct list_head list; | ||
1748 | struct net_device *dev; | ||
1749 | struct ipoib_neigh *neigh; | ||
1750 | - struct ipoib_path *path; | ||
1751 | struct ipoib_tx_buf *tx_ring; | ||
1752 | unsigned int tx_head; | ||
1753 | unsigned int tx_tail; | ||
1754 | diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | ||
1755 | index 0428e01e8f69..aa9dcfc36cd3 100644 | ||
1756 | --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c | ||
1757 | +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | ||
1758 | @@ -1312,7 +1312,6 @@ struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path | ||
1759 | |||
1760 | neigh->cm = tx; | ||
1761 | tx->neigh = neigh; | ||
1762 | - tx->path = path; | ||
1763 | tx->dev = dev; | ||
1764 | list_add(&tx->list, &priv->cm.start_list); | ||
1765 | set_bit(IPOIB_FLAG_INITIALIZED, &tx->flags); | ||
1766 | @@ -1371,7 +1370,7 @@ static void ipoib_cm_tx_start(struct work_struct *work) | ||
1767 | neigh->daddr + QPN_AND_OPTIONS_OFFSET); | ||
1768 | goto free_neigh; | ||
1769 | } | ||
1770 | - memcpy(&pathrec, &p->path->pathrec, sizeof(pathrec)); | ||
1771 | + memcpy(&pathrec, &path->pathrec, sizeof(pathrec)); | ||
1772 | |||
1773 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1774 | netif_tx_unlock_bh(dev); | ||
1775 | diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c | ||
1776 | index 225ae6980182..628ef617bb2f 100644 | ||
1777 | --- a/drivers/input/mouse/elan_i2c_core.c | ||
1778 | +++ b/drivers/input/mouse/elan_i2c_core.c | ||
1779 | @@ -1337,6 +1337,7 @@ static const struct acpi_device_id elan_acpi_id[] = { | ||
1780 | { "ELAN0000", 0 }, | ||
1781 | { "ELAN0100", 0 }, | ||
1782 | { "ELAN0600", 0 }, | ||
1783 | + { "ELAN0601", 0 }, | ||
1784 | { "ELAN0602", 0 }, | ||
1785 | { "ELAN0605", 0 }, | ||
1786 | { "ELAN0608", 0 }, | ||
1787 | diff --git a/drivers/input/tablet/wacom_serial4.c b/drivers/input/tablet/wacom_serial4.c | ||
1788 | index 38bfaca48eab..150f9eecaca7 100644 | ||
1789 | --- a/drivers/input/tablet/wacom_serial4.c | ||
1790 | +++ b/drivers/input/tablet/wacom_serial4.c | ||
1791 | @@ -187,6 +187,7 @@ enum { | ||
1792 | MODEL_DIGITIZER_II = 0x5544, /* UD */ | ||
1793 | MODEL_GRAPHIRE = 0x4554, /* ET */ | ||
1794 | MODEL_PENPARTNER = 0x4354, /* CT */ | ||
1795 | + MODEL_ARTPAD_II = 0x4B54, /* KT */ | ||
1796 | }; | ||
1797 | |||
1798 | static void wacom_handle_model_response(struct wacom *wacom) | ||
1799 | @@ -245,6 +246,7 @@ static void wacom_handle_model_response(struct wacom *wacom) | ||
1800 | wacom->flags = F_HAS_STYLUS2 | F_HAS_SCROLLWHEEL; | ||
1801 | break; | ||
1802 | |||
1803 | + case MODEL_ARTPAD_II: | ||
1804 | case MODEL_DIGITIZER_II: | ||
1805 | wacom->dev->name = "Wacom Digitizer II"; | ||
1806 | wacom->dev->id.version = MODEL_DIGITIZER_II; | ||
1807 | diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c | ||
1808 | index 34c9aa76a7bd..27500abe8ca7 100644 | ||
1809 | --- a/drivers/iommu/amd_iommu.c | ||
1810 | +++ b/drivers/iommu/amd_iommu.c | ||
1811 | @@ -1929,16 +1929,13 @@ static void do_attach(struct iommu_dev_data *dev_data, | ||
1812 | |||
1813 | static void do_detach(struct iommu_dev_data *dev_data) | ||
1814 | { | ||
1815 | + struct protection_domain *domain = dev_data->domain; | ||
1816 | struct amd_iommu *iommu; | ||
1817 | u16 alias; | ||
1818 | |||
1819 | iommu = amd_iommu_rlookup_table[dev_data->devid]; | ||
1820 | alias = dev_data->alias; | ||
1821 | |||
1822 | - /* decrease reference counters */ | ||
1823 | - dev_data->domain->dev_iommu[iommu->index] -= 1; | ||
1824 | - dev_data->domain->dev_cnt -= 1; | ||
1825 | - | ||
1826 | /* Update data structures */ | ||
1827 | dev_data->domain = NULL; | ||
1828 | list_del(&dev_data->list); | ||
1829 | @@ -1948,6 +1945,16 @@ static void do_detach(struct iommu_dev_data *dev_data) | ||
1830 | |||
1831 | /* Flush the DTE entry */ | ||
1832 | device_flush_dte(dev_data); | ||
1833 | + | ||
1834 | + /* Flush IOTLB */ | ||
1835 | + domain_flush_tlb_pde(domain); | ||
1836 | + | ||
1837 | + /* Wait for the flushes to finish */ | ||
1838 | + domain_flush_complete(domain); | ||
1839 | + | ||
1840 | + /* decrease reference counters - needs to happen after the flushes */ | ||
1841 | + domain->dev_iommu[iommu->index] -= 1; | ||
1842 | + domain->dev_cnt -= 1; | ||
1843 | } | ||
1844 | |||
1845 | /* | ||
1846 | @@ -2555,13 +2562,13 @@ out_unmap: | ||
1847 | bus_addr = address + s->dma_address + (j << PAGE_SHIFT); | ||
1848 | iommu_unmap_page(domain, bus_addr, PAGE_SIZE); | ||
1849 | |||
1850 | - if (--mapped_pages) | ||
1851 | + if (--mapped_pages == 0) | ||
1852 | goto out_free_iova; | ||
1853 | } | ||
1854 | } | ||
1855 | |||
1856 | out_free_iova: | ||
1857 | - free_iova_fast(&dma_dom->iovad, address, npages); | ||
1858 | + free_iova_fast(&dma_dom->iovad, address >> PAGE_SHIFT, npages); | ||
1859 | |||
1860 | out_err: | ||
1861 | return 0; | ||
1862 | diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c | ||
1863 | index 4c2246fe5dbe..15579cba1a88 100644 | ||
1864 | --- a/drivers/irqchip/irq-gic-v3-its.c | ||
1865 | +++ b/drivers/irqchip/irq-gic-v3-its.c | ||
1866 | @@ -1581,6 +1581,9 @@ static unsigned long *its_lpi_alloc(int nr_irqs, u32 *base, int *nr_ids) | ||
1867 | nr_irqs /= 2; | ||
1868 | } while (nr_irqs > 0); | ||
1869 | |||
1870 | + if (!nr_irqs) | ||
1871 | + err = -ENOSPC; | ||
1872 | + | ||
1873 | if (err) | ||
1874 | goto out; | ||
1875 | |||
1876 | @@ -1951,6 +1954,29 @@ static void its_free_pending_table(struct page *pt) | ||
1877 | get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K))); | ||
1878 | } | ||
1879 | |||
1880 | +static u64 its_clear_vpend_valid(void __iomem *vlpi_base) | ||
1881 | +{ | ||
1882 | + u32 count = 1000000; /* 1s! */ | ||
1883 | + bool clean; | ||
1884 | + u64 val; | ||
1885 | + | ||
1886 | + val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); | ||
1887 | + val &= ~GICR_VPENDBASER_Valid; | ||
1888 | + gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER); | ||
1889 | + | ||
1890 | + do { | ||
1891 | + val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); | ||
1892 | + clean = !(val & GICR_VPENDBASER_Dirty); | ||
1893 | + if (!clean) { | ||
1894 | + count--; | ||
1895 | + cpu_relax(); | ||
1896 | + udelay(1); | ||
1897 | + } | ||
1898 | + } while (!clean && count); | ||
1899 | + | ||
1900 | + return val; | ||
1901 | +} | ||
1902 | + | ||
1903 | static void its_cpu_init_lpis(void) | ||
1904 | { | ||
1905 | void __iomem *rbase = gic_data_rdist_rd_base(); | ||
1906 | @@ -2024,6 +2050,30 @@ static void its_cpu_init_lpis(void) | ||
1907 | val |= GICR_CTLR_ENABLE_LPIS; | ||
1908 | writel_relaxed(val, rbase + GICR_CTLR); | ||
1909 | |||
1910 | + if (gic_rdists->has_vlpis) { | ||
1911 | + void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); | ||
1912 | + | ||
1913 | + /* | ||
1914 | + * It's possible for CPU to receive VLPIs before it is | ||
1915 | + * sheduled as a vPE, especially for the first CPU, and the | ||
1916 | + * VLPI with INTID larger than 2^(IDbits+1) will be considered | ||
1917 | + * as out of range and dropped by GIC. | ||
1918 | + * So we initialize IDbits to known value to avoid VLPI drop. | ||
1919 | + */ | ||
1920 | + val = (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK; | ||
1921 | + pr_debug("GICv4: CPU%d: Init IDbits to 0x%llx for GICR_VPROPBASER\n", | ||
1922 | + smp_processor_id(), val); | ||
1923 | + gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER); | ||
1924 | + | ||
1925 | + /* | ||
1926 | + * Also clear Valid bit of GICR_VPENDBASER, in case some | ||
1927 | + * ancient programming gets left in and has possibility of | ||
1928 | + * corrupting memory. | ||
1929 | + */ | ||
1930 | + val = its_clear_vpend_valid(vlpi_base); | ||
1931 | + WARN_ON(val & GICR_VPENDBASER_Dirty); | ||
1932 | + } | ||
1933 | + | ||
1934 | /* Make sure the GIC has seen the above */ | ||
1935 | dsb(sy); | ||
1936 | } | ||
1937 | @@ -2644,26 +2694,11 @@ static void its_vpe_schedule(struct its_vpe *vpe) | ||
1938 | static void its_vpe_deschedule(struct its_vpe *vpe) | ||
1939 | { | ||
1940 | void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); | ||
1941 | - u32 count = 1000000; /* 1s! */ | ||
1942 | - bool clean; | ||
1943 | u64 val; | ||
1944 | |||
1945 | - /* We're being scheduled out */ | ||
1946 | - val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); | ||
1947 | - val &= ~GICR_VPENDBASER_Valid; | ||
1948 | - gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER); | ||
1949 | - | ||
1950 | - do { | ||
1951 | - val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); | ||
1952 | - clean = !(val & GICR_VPENDBASER_Dirty); | ||
1953 | - if (!clean) { | ||
1954 | - count--; | ||
1955 | - cpu_relax(); | ||
1956 | - udelay(1); | ||
1957 | - } | ||
1958 | - } while (!clean && count); | ||
1959 | + val = its_clear_vpend_valid(vlpi_base); | ||
1960 | |||
1961 | - if (unlikely(!clean && !count)) { | ||
1962 | + if (unlikely(val & GICR_VPENDBASER_Dirty)) { | ||
1963 | pr_err_ratelimited("ITS virtual pending table not cleaning\n"); | ||
1964 | vpe->idai = false; | ||
1965 | vpe->pending_last = true; | ||
1966 | diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c | ||
1967 | index 25f32e1d7764..3496b61a312a 100644 | ||
1968 | --- a/drivers/irqchip/irq-mmp.c | ||
1969 | +++ b/drivers/irqchip/irq-mmp.c | ||
1970 | @@ -34,6 +34,9 @@ | ||
1971 | #define SEL_INT_PENDING (1 << 6) | ||
1972 | #define SEL_INT_NUM_MASK 0x3f | ||
1973 | |||
1974 | +#define MMP2_ICU_INT_ROUTE_PJ4_IRQ (1 << 5) | ||
1975 | +#define MMP2_ICU_INT_ROUTE_PJ4_FIQ (1 << 6) | ||
1976 | + | ||
1977 | struct icu_chip_data { | ||
1978 | int nr_irqs; | ||
1979 | unsigned int virq_base; | ||
1980 | @@ -190,7 +193,8 @@ static const struct mmp_intc_conf mmp_conf = { | ||
1981 | static const struct mmp_intc_conf mmp2_conf = { | ||
1982 | .conf_enable = 0x20, | ||
1983 | .conf_disable = 0x0, | ||
1984 | - .conf_mask = 0x7f, | ||
1985 | + .conf_mask = MMP2_ICU_INT_ROUTE_PJ4_IRQ | | ||
1986 | + MMP2_ICU_INT_ROUTE_PJ4_FIQ, | ||
1987 | }; | ||
1988 | |||
1989 | static void __exception_irq_entry mmp_handle_irq(struct pt_regs *regs) | ||
1990 | diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c | ||
1991 | index 361abbc00486..6f1fd40fce10 100644 | ||
1992 | --- a/drivers/media/usb/uvc/uvc_driver.c | ||
1993 | +++ b/drivers/media/usb/uvc/uvc_driver.c | ||
1994 | @@ -1065,11 +1065,19 @@ static int uvc_parse_standard_control(struct uvc_device *dev, | ||
1995 | return -EINVAL; | ||
1996 | } | ||
1997 | |||
1998 | - /* Make sure the terminal type MSB is not null, otherwise it | ||
1999 | - * could be confused with a unit. | ||
2000 | + /* | ||
2001 | + * Reject invalid terminal types that would cause issues: | ||
2002 | + * | ||
2003 | + * - The high byte must be non-zero, otherwise it would be | ||
2004 | + * confused with a unit. | ||
2005 | + * | ||
2006 | + * - Bit 15 must be 0, as we use it internally as a terminal | ||
2007 | + * direction flag. | ||
2008 | + * | ||
2009 | + * Other unknown types are accepted. | ||
2010 | */ | ||
2011 | type = get_unaligned_le16(&buffer[4]); | ||
2012 | - if ((type & 0xff00) == 0) { | ||
2013 | + if ((type & 0x7f00) == 0 || (type & 0x8000) != 0) { | ||
2014 | uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " | ||
2015 | "interface %d INPUT_TERMINAL %d has invalid " | ||
2016 | "type 0x%04x, skipping\n", udev->devnum, | ||
2017 | diff --git a/drivers/net/ethernet/altera/altera_msgdma.c b/drivers/net/ethernet/altera/altera_msgdma.c | ||
2018 | index 0fb986ba3290..0ae723f75341 100644 | ||
2019 | --- a/drivers/net/ethernet/altera/altera_msgdma.c | ||
2020 | +++ b/drivers/net/ethernet/altera/altera_msgdma.c | ||
2021 | @@ -145,7 +145,8 @@ u32 msgdma_tx_completions(struct altera_tse_private *priv) | ||
2022 | & 0xffff; | ||
2023 | |||
2024 | if (inuse) { /* Tx FIFO is not empty */ | ||
2025 | - ready = priv->tx_prod - priv->tx_cons - inuse - 1; | ||
2026 | + ready = max_t(int, | ||
2027 | + priv->tx_prod - priv->tx_cons - inuse - 1, 0); | ||
2028 | } else { | ||
2029 | /* Check for buffered last packet */ | ||
2030 | status = csrrd32(priv->tx_dma_csr, msgdma_csroffs(status)); | ||
2031 | diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h | ||
2032 | index 3d45f4c92cf6..9bbaad9f3d63 100644 | ||
2033 | --- a/drivers/net/ethernet/cadence/macb.h | ||
2034 | +++ b/drivers/net/ethernet/cadence/macb.h | ||
2035 | @@ -643,6 +643,7 @@ | ||
2036 | #define MACB_CAPS_JUMBO 0x00000020 | ||
2037 | #define MACB_CAPS_GEM_HAS_PTP 0x00000040 | ||
2038 | #define MACB_CAPS_BD_RD_PREFETCH 0x00000080 | ||
2039 | +#define MACB_CAPS_NEEDS_RSTONUBR 0x00000100 | ||
2040 | #define MACB_CAPS_FIFO_MODE 0x10000000 | ||
2041 | #define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000 | ||
2042 | #define MACB_CAPS_SG_DISABLED 0x40000000 | ||
2043 | @@ -1214,6 +1215,8 @@ struct macb { | ||
2044 | |||
2045 | int rx_bd_rd_prefetch; | ||
2046 | int tx_bd_rd_prefetch; | ||
2047 | + | ||
2048 | + u32 rx_intr_mask; | ||
2049 | }; | ||
2050 | |||
2051 | #ifdef CONFIG_MACB_USE_HWSTAMP | ||
2052 | diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c | ||
2053 | index 8f4b2f9a8e07..8abea1c3844f 100644 | ||
2054 | --- a/drivers/net/ethernet/cadence/macb_main.c | ||
2055 | +++ b/drivers/net/ethernet/cadence/macb_main.c | ||
2056 | @@ -56,8 +56,7 @@ | ||
2057 | /* level of occupied TX descriptors under which we wake up TX process */ | ||
2058 | #define MACB_TX_WAKEUP_THRESH(bp) (3 * (bp)->tx_ring_size / 4) | ||
2059 | |||
2060 | -#define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(RXUBR) \ | ||
2061 | - | MACB_BIT(ISR_ROVR)) | ||
2062 | +#define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(ISR_ROVR)) | ||
2063 | #define MACB_TX_ERR_FLAGS (MACB_BIT(ISR_TUND) \ | ||
2064 | | MACB_BIT(ISR_RLE) \ | ||
2065 | | MACB_BIT(TXERR)) | ||
2066 | @@ -1271,7 +1270,7 @@ static int macb_poll(struct napi_struct *napi, int budget) | ||
2067 | queue_writel(queue, ISR, MACB_BIT(RCOMP)); | ||
2068 | napi_reschedule(napi); | ||
2069 | } else { | ||
2070 | - queue_writel(queue, IER, MACB_RX_INT_FLAGS); | ||
2071 | + queue_writel(queue, IER, bp->rx_intr_mask); | ||
2072 | } | ||
2073 | } | ||
2074 | |||
2075 | @@ -1289,7 +1288,7 @@ static void macb_hresp_error_task(unsigned long data) | ||
2076 | u32 ctrl; | ||
2077 | |||
2078 | for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { | ||
2079 | - queue_writel(queue, IDR, MACB_RX_INT_FLAGS | | ||
2080 | + queue_writel(queue, IDR, bp->rx_intr_mask | | ||
2081 | MACB_TX_INT_FLAGS | | ||
2082 | MACB_BIT(HRESP)); | ||
2083 | } | ||
2084 | @@ -1319,7 +1318,7 @@ static void macb_hresp_error_task(unsigned long data) | ||
2085 | |||
2086 | /* Enable interrupts */ | ||
2087 | queue_writel(queue, IER, | ||
2088 | - MACB_RX_INT_FLAGS | | ||
2089 | + bp->rx_intr_mask | | ||
2090 | MACB_TX_INT_FLAGS | | ||
2091 | MACB_BIT(HRESP)); | ||
2092 | } | ||
2093 | @@ -1373,14 +1372,14 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | ||
2094 | (unsigned int)(queue - bp->queues), | ||
2095 | (unsigned long)status); | ||
2096 | |||
2097 | - if (status & MACB_RX_INT_FLAGS) { | ||
2098 | + if (status & bp->rx_intr_mask) { | ||
2099 | /* There's no point taking any more interrupts | ||
2100 | * until we have processed the buffers. The | ||
2101 | * scheduling call may fail if the poll routine | ||
2102 | * is already scheduled, so disable interrupts | ||
2103 | * now. | ||
2104 | */ | ||
2105 | - queue_writel(queue, IDR, MACB_RX_INT_FLAGS); | ||
2106 | + queue_writel(queue, IDR, bp->rx_intr_mask); | ||
2107 | if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) | ||
2108 | queue_writel(queue, ISR, MACB_BIT(RCOMP)); | ||
2109 | |||
2110 | @@ -1413,8 +1412,9 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | ||
2111 | /* There is a hardware issue under heavy load where DMA can | ||
2112 | * stop, this causes endless "used buffer descriptor read" | ||
2113 | * interrupts but it can be cleared by re-enabling RX. See | ||
2114 | - * the at91 manual, section 41.3.1 or the Zynq manual | ||
2115 | - * section 16.7.4 for details. | ||
2116 | + * the at91rm9200 manual, section 41.3.1 or the Zynq manual | ||
2117 | + * section 16.7.4 for details. RXUBR is only enabled for | ||
2118 | + * these two versions. | ||
2119 | */ | ||
2120 | if (status & MACB_BIT(RXUBR)) { | ||
2121 | ctrl = macb_readl(bp, NCR); | ||
2122 | @@ -2264,7 +2264,7 @@ static void macb_init_hw(struct macb *bp) | ||
2123 | |||
2124 | /* Enable interrupts */ | ||
2125 | queue_writel(queue, IER, | ||
2126 | - MACB_RX_INT_FLAGS | | ||
2127 | + bp->rx_intr_mask | | ||
2128 | MACB_TX_INT_FLAGS | | ||
2129 | MACB_BIT(HRESP)); | ||
2130 | } | ||
2131 | @@ -3912,6 +3912,7 @@ static const struct macb_config sama5d4_config = { | ||
2132 | }; | ||
2133 | |||
2134 | static const struct macb_config emac_config = { | ||
2135 | + .caps = MACB_CAPS_NEEDS_RSTONUBR, | ||
2136 | .clk_init = at91ether_clk_init, | ||
2137 | .init = at91ether_init, | ||
2138 | }; | ||
2139 | @@ -3933,7 +3934,8 @@ static const struct macb_config zynqmp_config = { | ||
2140 | }; | ||
2141 | |||
2142 | static const struct macb_config zynq_config = { | ||
2143 | - .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_NO_GIGABIT_HALF, | ||
2144 | + .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_NO_GIGABIT_HALF | | ||
2145 | + MACB_CAPS_NEEDS_RSTONUBR, | ||
2146 | .dma_burst_length = 16, | ||
2147 | .clk_init = macb_clk_init, | ||
2148 | .init = macb_init, | ||
2149 | @@ -4088,6 +4090,10 @@ static int macb_probe(struct platform_device *pdev) | ||
2150 | macb_dma_desc_get_size(bp); | ||
2151 | } | ||
2152 | |||
2153 | + bp->rx_intr_mask = MACB_RX_INT_FLAGS; | ||
2154 | + if (bp->caps & MACB_CAPS_NEEDS_RSTONUBR) | ||
2155 | + bp->rx_intr_mask |= MACB_BIT(RXUBR); | ||
2156 | + | ||
2157 | mac = of_get_mac_address(np); | ||
2158 | if (mac) { | ||
2159 | ether_addr_copy(bp->dev->dev_addr, mac); | ||
2160 | diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c | ||
2161 | index 6242249c9f4c..b043370c2685 100644 | ||
2162 | --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c | ||
2163 | +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c | ||
2164 | @@ -2419,6 +2419,8 @@ static int hns_nic_dev_probe(struct platform_device *pdev) | ||
2165 | out_notify_fail: | ||
2166 | (void)cancel_work_sync(&priv->service_task); | ||
2167 | out_read_prop_fail: | ||
2168 | + /* safe for ACPI FW */ | ||
2169 | + of_node_put(to_of_node(priv->fwnode)); | ||
2170 | free_netdev(ndev); | ||
2171 | return ret; | ||
2172 | } | ||
2173 | @@ -2448,6 +2450,9 @@ static int hns_nic_dev_remove(struct platform_device *pdev) | ||
2174 | set_bit(NIC_STATE_REMOVING, &priv->state); | ||
2175 | (void)cancel_work_sync(&priv->service_task); | ||
2176 | |||
2177 | + /* safe for ACPI FW */ | ||
2178 | + of_node_put(to_of_node(priv->fwnode)); | ||
2179 | + | ||
2180 | free_netdev(ndev); | ||
2181 | return 0; | ||
2182 | } | ||
2183 | diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | ||
2184 | index 774beda040a1..e2710ff48fb0 100644 | ||
2185 | --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | ||
2186 | +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | ||
2187 | @@ -1157,16 +1157,18 @@ static int hns_get_regs_len(struct net_device *net_dev) | ||
2188 | */ | ||
2189 | static int hns_nic_nway_reset(struct net_device *netdev) | ||
2190 | { | ||
2191 | - int ret = 0; | ||
2192 | struct phy_device *phy = netdev->phydev; | ||
2193 | |||
2194 | - if (netif_running(netdev)) { | ||
2195 | - /* if autoneg is disabled, don't restart auto-negotiation */ | ||
2196 | - if (phy && phy->autoneg == AUTONEG_ENABLE) | ||
2197 | - ret = genphy_restart_aneg(phy); | ||
2198 | - } | ||
2199 | + if (!netif_running(netdev)) | ||
2200 | + return 0; | ||
2201 | |||
2202 | - return ret; | ||
2203 | + if (!phy) | ||
2204 | + return -EOPNOTSUPP; | ||
2205 | + | ||
2206 | + if (phy->autoneg != AUTONEG_ENABLE) | ||
2207 | + return -EINVAL; | ||
2208 | + | ||
2209 | + return genphy_restart_aneg(phy); | ||
2210 | } | ||
2211 | |||
2212 | static u32 | ||
2213 | diff --git a/drivers/net/ethernet/hisilicon/hns_mdio.c b/drivers/net/ethernet/hisilicon/hns_mdio.c | ||
2214 | index 017e08452d8c..baf5cc251f32 100644 | ||
2215 | --- a/drivers/net/ethernet/hisilicon/hns_mdio.c | ||
2216 | +++ b/drivers/net/ethernet/hisilicon/hns_mdio.c | ||
2217 | @@ -321,7 +321,7 @@ static int hns_mdio_read(struct mii_bus *bus, int phy_id, int regnum) | ||
2218 | } | ||
2219 | |||
2220 | hns_mdio_cmd_write(mdio_dev, is_c45, | ||
2221 | - MDIO_C45_WRITE_ADDR, phy_id, devad); | ||
2222 | + MDIO_C45_READ, phy_id, devad); | ||
2223 | } | ||
2224 | |||
2225 | /* Step 5: waitting for MDIO_COMMAND_REG 's mdio_start==0,*/ | ||
2226 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c | ||
2227 | index 2f69ee9221c6..4dd82a1612aa 100644 | ||
2228 | --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c | ||
2229 | +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c | ||
2230 | @@ -473,19 +473,19 @@ static void qed_init_qm_pq(struct qed_hwfn *p_hwfn, | ||
2231 | |||
2232 | /* get pq index according to PQ_FLAGS */ | ||
2233 | static u16 *qed_init_qm_get_idx_from_flags(struct qed_hwfn *p_hwfn, | ||
2234 | - u32 pq_flags) | ||
2235 | + unsigned long pq_flags) | ||
2236 | { | ||
2237 | struct qed_qm_info *qm_info = &p_hwfn->qm_info; | ||
2238 | |||
2239 | /* Can't have multiple flags set here */ | ||
2240 | - if (bitmap_weight((unsigned long *)&pq_flags, | ||
2241 | + if (bitmap_weight(&pq_flags, | ||
2242 | sizeof(pq_flags) * BITS_PER_BYTE) > 1) { | ||
2243 | - DP_ERR(p_hwfn, "requested multiple pq flags 0x%x\n", pq_flags); | ||
2244 | + DP_ERR(p_hwfn, "requested multiple pq flags 0x%lx\n", pq_flags); | ||
2245 | goto err; | ||
2246 | } | ||
2247 | |||
2248 | if (!(qed_get_pq_flags(p_hwfn) & pq_flags)) { | ||
2249 | - DP_ERR(p_hwfn, "pq flag 0x%x is not set\n", pq_flags); | ||
2250 | + DP_ERR(p_hwfn, "pq flag 0x%lx is not set\n", pq_flags); | ||
2251 | goto err; | ||
2252 | } | ||
2253 | |||
2254 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c | ||
2255 | index 67c02ea93906..64ac95ca4df2 100644 | ||
2256 | --- a/drivers/net/ethernet/qlogic/qed/qed_l2.c | ||
2257 | +++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c | ||
2258 | @@ -609,6 +609,10 @@ qed_sp_update_accept_mode(struct qed_hwfn *p_hwfn, | ||
2259 | (!!(accept_filter & QED_ACCEPT_MCAST_MATCHED) && | ||
2260 | !!(accept_filter & QED_ACCEPT_MCAST_UNMATCHED))); | ||
2261 | |||
2262 | + SET_FIELD(state, ETH_VPORT_TX_MODE_UCAST_ACCEPT_ALL, | ||
2263 | + (!!(accept_filter & QED_ACCEPT_UCAST_MATCHED) && | ||
2264 | + !!(accept_filter & QED_ACCEPT_UCAST_UNMATCHED))); | ||
2265 | + | ||
2266 | SET_FIELD(state, ETH_VPORT_TX_MODE_BCAST_ACCEPT_ALL, | ||
2267 | !!(accept_filter & QED_ACCEPT_BCAST)); | ||
2268 | |||
2269 | @@ -744,6 +748,11 @@ int qed_sp_vport_update(struct qed_hwfn *p_hwfn, | ||
2270 | return rc; | ||
2271 | } | ||
2272 | |||
2273 | + if (p_params->update_ctl_frame_check) { | ||
2274 | + p_cmn->ctl_frame_mac_check_en = p_params->mac_chk_en; | ||
2275 | + p_cmn->ctl_frame_ethtype_check_en = p_params->ethtype_chk_en; | ||
2276 | + } | ||
2277 | + | ||
2278 | /* Update mcast bins for VFs, PF doesn't use this functionality */ | ||
2279 | qed_sp_update_mcast_bin(p_hwfn, p_ramrod, p_params); | ||
2280 | |||
2281 | @@ -2207,7 +2216,7 @@ static int qed_fill_eth_dev_info(struct qed_dev *cdev, | ||
2282 | u16 num_queues = 0; | ||
2283 | |||
2284 | /* Since the feature controls only queue-zones, | ||
2285 | - * make sure we have the contexts [rx, tx, xdp] to | ||
2286 | + * make sure we have the contexts [rx, xdp, tcs] to | ||
2287 | * match. | ||
2288 | */ | ||
2289 | for_each_hwfn(cdev, i) { | ||
2290 | @@ -2217,7 +2226,8 @@ static int qed_fill_eth_dev_info(struct qed_dev *cdev, | ||
2291 | u16 cids; | ||
2292 | |||
2293 | cids = hwfn->pf_params.eth_pf_params.num_cons; | ||
2294 | - num_queues += min_t(u16, l2_queues, cids / 3); | ||
2295 | + cids /= (2 + info->num_tc); | ||
2296 | + num_queues += min_t(u16, l2_queues, cids); | ||
2297 | } | ||
2298 | |||
2299 | /* queues might theoretically be >256, but interrupts' | ||
2300 | @@ -2688,7 +2698,8 @@ static int qed_configure_filter_rx_mode(struct qed_dev *cdev, | ||
2301 | if (type == QED_FILTER_RX_MODE_TYPE_PROMISC) { | ||
2302 | accept_flags.rx_accept_filter |= QED_ACCEPT_UCAST_UNMATCHED | | ||
2303 | QED_ACCEPT_MCAST_UNMATCHED; | ||
2304 | - accept_flags.tx_accept_filter |= QED_ACCEPT_MCAST_UNMATCHED; | ||
2305 | + accept_flags.tx_accept_filter |= QED_ACCEPT_UCAST_UNMATCHED | | ||
2306 | + QED_ACCEPT_MCAST_UNMATCHED; | ||
2307 | } else if (type == QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC) { | ||
2308 | accept_flags.rx_accept_filter |= QED_ACCEPT_MCAST_UNMATCHED; | ||
2309 | accept_flags.tx_accept_filter |= QED_ACCEPT_MCAST_UNMATCHED; | ||
2310 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.h b/drivers/net/ethernet/qlogic/qed/qed_l2.h | ||
2311 | index 8d80f1095d17..7127d5aaac42 100644 | ||
2312 | --- a/drivers/net/ethernet/qlogic/qed/qed_l2.h | ||
2313 | +++ b/drivers/net/ethernet/qlogic/qed/qed_l2.h | ||
2314 | @@ -219,6 +219,9 @@ struct qed_sp_vport_update_params { | ||
2315 | struct qed_rss_params *rss_params; | ||
2316 | struct qed_filter_accept_flags accept_flags; | ||
2317 | struct qed_sge_tpa_params *sge_tpa_params; | ||
2318 | + u8 update_ctl_frame_check; | ||
2319 | + u8 mac_chk_en; | ||
2320 | + u8 ethtype_chk_en; | ||
2321 | }; | ||
2322 | |||
2323 | int qed_sp_vport_update(struct qed_hwfn *p_hwfn, | ||
2324 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c | ||
2325 | index 92cd8abeb41d..015de1e0addd 100644 | ||
2326 | --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c | ||
2327 | +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c | ||
2328 | @@ -2430,19 +2430,24 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb, | ||
2329 | { | ||
2330 | struct qed_ll2_tx_pkt_info pkt; | ||
2331 | const skb_frag_t *frag; | ||
2332 | + u8 flags = 0, nr_frags; | ||
2333 | int rc = -EINVAL, i; | ||
2334 | dma_addr_t mapping; | ||
2335 | u16 vlan = 0; | ||
2336 | - u8 flags = 0; | ||
2337 | |||
2338 | if (unlikely(skb->ip_summed != CHECKSUM_NONE)) { | ||
2339 | DP_INFO(cdev, "Cannot transmit a checksummed packet\n"); | ||
2340 | return -EINVAL; | ||
2341 | } | ||
2342 | |||
2343 | - if (1 + skb_shinfo(skb)->nr_frags > CORE_LL2_TX_MAX_BDS_PER_PACKET) { | ||
2344 | + /* Cache number of fragments from SKB since SKB may be freed by | ||
2345 | + * the completion routine after calling qed_ll2_prepare_tx_packet() | ||
2346 | + */ | ||
2347 | + nr_frags = skb_shinfo(skb)->nr_frags; | ||
2348 | + | ||
2349 | + if (1 + nr_frags > CORE_LL2_TX_MAX_BDS_PER_PACKET) { | ||
2350 | DP_ERR(cdev, "Cannot transmit a packet with %d fragments\n", | ||
2351 | - 1 + skb_shinfo(skb)->nr_frags); | ||
2352 | + 1 + nr_frags); | ||
2353 | return -EINVAL; | ||
2354 | } | ||
2355 | |||
2356 | @@ -2464,7 +2469,7 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb, | ||
2357 | } | ||
2358 | |||
2359 | memset(&pkt, 0, sizeof(pkt)); | ||
2360 | - pkt.num_of_bds = 1 + skb_shinfo(skb)->nr_frags; | ||
2361 | + pkt.num_of_bds = 1 + nr_frags; | ||
2362 | pkt.vlan = vlan; | ||
2363 | pkt.bd_flags = flags; | ||
2364 | pkt.tx_dest = QED_LL2_TX_DEST_NW; | ||
2365 | @@ -2475,12 +2480,17 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb, | ||
2366 | test_bit(QED_LL2_XMIT_FLAGS_FIP_DISCOVERY, &xmit_flags)) | ||
2367 | pkt.remove_stag = true; | ||
2368 | |||
2369 | + /* qed_ll2_prepare_tx_packet() may actually send the packet if | ||
2370 | + * there are no fragments in the skb and subsequently the completion | ||
2371 | + * routine may run and free the SKB, so no dereferencing the SKB | ||
2372 | + * beyond this point unless skb has any fragments. | ||
2373 | + */ | ||
2374 | rc = qed_ll2_prepare_tx_packet(&cdev->hwfns[0], cdev->ll2->handle, | ||
2375 | &pkt, 1); | ||
2376 | if (rc) | ||
2377 | goto err; | ||
2378 | |||
2379 | - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | ||
2380 | + for (i = 0; i < nr_frags; i++) { | ||
2381 | frag = &skb_shinfo(skb)->frags[i]; | ||
2382 | |||
2383 | mapping = skb_frag_dma_map(&cdev->pdev->dev, frag, 0, | ||
2384 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp.h b/drivers/net/ethernet/qlogic/qed/qed_sp.h | ||
2385 | index 3157c0d99441..dae2896e1d8e 100644 | ||
2386 | --- a/drivers/net/ethernet/qlogic/qed/qed_sp.h | ||
2387 | +++ b/drivers/net/ethernet/qlogic/qed/qed_sp.h | ||
2388 | @@ -380,6 +380,7 @@ void qed_consq_setup(struct qed_hwfn *p_hwfn); | ||
2389 | * @param p_hwfn | ||
2390 | */ | ||
2391 | void qed_consq_free(struct qed_hwfn *p_hwfn); | ||
2392 | +int qed_spq_pend_post(struct qed_hwfn *p_hwfn); | ||
2393 | |||
2394 | /** | ||
2395 | * @file | ||
2396 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c | ||
2397 | index 7106ad17afe2..a0ee847f379b 100644 | ||
2398 | --- a/drivers/net/ethernet/qlogic/qed/qed_spq.c | ||
2399 | +++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c | ||
2400 | @@ -402,6 +402,11 @@ int qed_eq_completion(struct qed_hwfn *p_hwfn, void *cookie) | ||
2401 | |||
2402 | qed_eq_prod_update(p_hwfn, qed_chain_get_prod_idx(p_chain)); | ||
2403 | |||
2404 | + /* Attempt to post pending requests */ | ||
2405 | + spin_lock_bh(&p_hwfn->p_spq->lock); | ||
2406 | + rc = qed_spq_pend_post(p_hwfn); | ||
2407 | + spin_unlock_bh(&p_hwfn->p_spq->lock); | ||
2408 | + | ||
2409 | return rc; | ||
2410 | } | ||
2411 | |||
2412 | @@ -745,7 +750,7 @@ static int qed_spq_post_list(struct qed_hwfn *p_hwfn, | ||
2413 | return 0; | ||
2414 | } | ||
2415 | |||
2416 | -static int qed_spq_pend_post(struct qed_hwfn *p_hwfn) | ||
2417 | +int qed_spq_pend_post(struct qed_hwfn *p_hwfn) | ||
2418 | { | ||
2419 | struct qed_spq *p_spq = p_hwfn->p_spq; | ||
2420 | struct qed_spq_entry *p_ent = NULL; | ||
2421 | @@ -883,7 +888,6 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn, | ||
2422 | struct qed_spq_entry *p_ent = NULL; | ||
2423 | struct qed_spq_entry *tmp; | ||
2424 | struct qed_spq_entry *found = NULL; | ||
2425 | - int rc; | ||
2426 | |||
2427 | if (!p_hwfn) | ||
2428 | return -EINVAL; | ||
2429 | @@ -941,12 +945,7 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn, | ||
2430 | */ | ||
2431 | qed_spq_return_entry(p_hwfn, found); | ||
2432 | |||
2433 | - /* Attempt to post pending requests */ | ||
2434 | - spin_lock_bh(&p_spq->lock); | ||
2435 | - rc = qed_spq_pend_post(p_hwfn); | ||
2436 | - spin_unlock_bh(&p_spq->lock); | ||
2437 | - | ||
2438 | - return rc; | ||
2439 | + return 0; | ||
2440 | } | ||
2441 | |||
2442 | int qed_consq_alloc(struct qed_hwfn *p_hwfn) | ||
2443 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c | ||
2444 | index ca6290fa0f30..71a7af134dd8 100644 | ||
2445 | --- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c | ||
2446 | +++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c | ||
2447 | @@ -1969,7 +1969,9 @@ static void qed_iov_vf_mbx_start_vport(struct qed_hwfn *p_hwfn, | ||
2448 | params.vport_id = vf->vport_id; | ||
2449 | params.max_buffers_per_cqe = start->max_buffers_per_cqe; | ||
2450 | params.mtu = vf->mtu; | ||
2451 | - params.check_mac = true; | ||
2452 | + | ||
2453 | + /* Non trusted VFs should enable control frame filtering */ | ||
2454 | + params.check_mac = !vf->p_vf_info.is_trusted_configured; | ||
2455 | |||
2456 | rc = qed_sp_eth_vport_start(p_hwfn, ¶ms); | ||
2457 | if (rc) { | ||
2458 | @@ -5130,6 +5132,9 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn) | ||
2459 | params.opaque_fid = vf->opaque_fid; | ||
2460 | params.vport_id = vf->vport_id; | ||
2461 | |||
2462 | + params.update_ctl_frame_check = 1; | ||
2463 | + params.mac_chk_en = !vf_info->is_trusted_configured; | ||
2464 | + | ||
2465 | if (vf_info->rx_accept_mode & mask) { | ||
2466 | flags->update_rx_mode_config = 1; | ||
2467 | flags->rx_accept_filter = vf_info->rx_accept_mode; | ||
2468 | @@ -5147,7 +5152,8 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn) | ||
2469 | } | ||
2470 | |||
2471 | if (flags->update_rx_mode_config || | ||
2472 | - flags->update_tx_mode_config) | ||
2473 | + flags->update_tx_mode_config || | ||
2474 | + params.update_ctl_frame_check) | ||
2475 | qed_sp_vport_update(hwfn, ¶ms, | ||
2476 | QED_SPQ_MODE_EBLOCK, NULL); | ||
2477 | } | ||
2478 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_vf.c b/drivers/net/ethernet/qlogic/qed/qed_vf.c | ||
2479 | index be118d057b92..6ab3fb008139 100644 | ||
2480 | --- a/drivers/net/ethernet/qlogic/qed/qed_vf.c | ||
2481 | +++ b/drivers/net/ethernet/qlogic/qed/qed_vf.c | ||
2482 | @@ -261,6 +261,7 @@ static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn) | ||
2483 | struct pfvf_acquire_resp_tlv *resp = &p_iov->pf2vf_reply->acquire_resp; | ||
2484 | struct pf_vf_pfdev_info *pfdev_info = &resp->pfdev_info; | ||
2485 | struct vf_pf_resc_request *p_resc; | ||
2486 | + u8 retry_cnt = VF_ACQUIRE_THRESH; | ||
2487 | bool resources_acquired = false; | ||
2488 | struct vfpf_acquire_tlv *req; | ||
2489 | int rc = 0, attempts = 0; | ||
2490 | @@ -314,6 +315,15 @@ static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn) | ||
2491 | |||
2492 | /* send acquire request */ | ||
2493 | rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); | ||
2494 | + | ||
2495 | + /* Re-try acquire in case of vf-pf hw channel timeout */ | ||
2496 | + if (retry_cnt && rc == -EBUSY) { | ||
2497 | + DP_VERBOSE(p_hwfn, QED_MSG_IOV, | ||
2498 | + "VF retrying to acquire due to VPC timeout\n"); | ||
2499 | + retry_cnt--; | ||
2500 | + continue; | ||
2501 | + } | ||
2502 | + | ||
2503 | if (rc) | ||
2504 | goto exit; | ||
2505 | |||
2506 | diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h | ||
2507 | index 6a4d266fb8e2..d242a5724069 100644 | ||
2508 | --- a/drivers/net/ethernet/qlogic/qede/qede.h | ||
2509 | +++ b/drivers/net/ethernet/qlogic/qede/qede.h | ||
2510 | @@ -489,6 +489,9 @@ struct qede_reload_args { | ||
2511 | |||
2512 | /* Datapath functions definition */ | ||
2513 | netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev); | ||
2514 | +u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb, | ||
2515 | + struct net_device *sb_dev, | ||
2516 | + select_queue_fallback_t fallback); | ||
2517 | netdev_features_t qede_features_check(struct sk_buff *skb, | ||
2518 | struct net_device *dev, | ||
2519 | netdev_features_t features); | ||
2520 | diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c | ||
2521 | index 1a78027de071..a96da16f3404 100644 | ||
2522 | --- a/drivers/net/ethernet/qlogic/qede/qede_fp.c | ||
2523 | +++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c | ||
2524 | @@ -1695,6 +1695,19 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev) | ||
2525 | return NETDEV_TX_OK; | ||
2526 | } | ||
2527 | |||
2528 | +u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb, | ||
2529 | + struct net_device *sb_dev, | ||
2530 | + select_queue_fallback_t fallback) | ||
2531 | +{ | ||
2532 | + struct qede_dev *edev = netdev_priv(dev); | ||
2533 | + int total_txq; | ||
2534 | + | ||
2535 | + total_txq = QEDE_TSS_COUNT(edev) * edev->dev_info.num_tc; | ||
2536 | + | ||
2537 | + return QEDE_TSS_COUNT(edev) ? | ||
2538 | + fallback(dev, skb, NULL) % total_txq : 0; | ||
2539 | +} | ||
2540 | + | ||
2541 | /* 8B udp header + 8B base tunnel header + 32B option length */ | ||
2542 | #define QEDE_MAX_TUN_HDR_LEN 48 | ||
2543 | |||
2544 | diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c | ||
2545 | index 46d0f2eaa0c0..f3d9c40c4115 100644 | ||
2546 | --- a/drivers/net/ethernet/qlogic/qede/qede_main.c | ||
2547 | +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c | ||
2548 | @@ -631,6 +631,7 @@ static const struct net_device_ops qede_netdev_ops = { | ||
2549 | .ndo_open = qede_open, | ||
2550 | .ndo_stop = qede_close, | ||
2551 | .ndo_start_xmit = qede_start_xmit, | ||
2552 | + .ndo_select_queue = qede_select_queue, | ||
2553 | .ndo_set_rx_mode = qede_set_rx_mode, | ||
2554 | .ndo_set_mac_address = qede_set_mac_addr, | ||
2555 | .ndo_validate_addr = eth_validate_addr, | ||
2556 | @@ -666,6 +667,7 @@ static const struct net_device_ops qede_netdev_vf_ops = { | ||
2557 | .ndo_open = qede_open, | ||
2558 | .ndo_stop = qede_close, | ||
2559 | .ndo_start_xmit = qede_start_xmit, | ||
2560 | + .ndo_select_queue = qede_select_queue, | ||
2561 | .ndo_set_rx_mode = qede_set_rx_mode, | ||
2562 | .ndo_set_mac_address = qede_set_mac_addr, | ||
2563 | .ndo_validate_addr = eth_validate_addr, | ||
2564 | @@ -684,6 +686,7 @@ static const struct net_device_ops qede_netdev_vf_xdp_ops = { | ||
2565 | .ndo_open = qede_open, | ||
2566 | .ndo_stop = qede_close, | ||
2567 | .ndo_start_xmit = qede_start_xmit, | ||
2568 | + .ndo_select_queue = qede_select_queue, | ||
2569 | .ndo_set_rx_mode = qede_set_rx_mode, | ||
2570 | .ndo_set_mac_address = qede_set_mac_addr, | ||
2571 | .ndo_validate_addr = eth_validate_addr, | ||
2572 | diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | ||
2573 | index 7b923362ee55..3b174eae77c1 100644 | ||
2574 | --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | ||
2575 | +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | ||
2576 | @@ -1342,8 +1342,10 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) | ||
2577 | } | ||
2578 | |||
2579 | ret = phy_power_on(bsp_priv, true); | ||
2580 | - if (ret) | ||
2581 | + if (ret) { | ||
2582 | + gmac_clk_enable(bsp_priv, false); | ||
2583 | return ret; | ||
2584 | + } | ||
2585 | |||
2586 | pm_runtime_enable(dev); | ||
2587 | pm_runtime_get_sync(dev); | ||
2588 | diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | ||
2589 | index 9caf79ba5ef1..4d5fb4b51cc4 100644 | ||
2590 | --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | ||
2591 | +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | ||
2592 | @@ -719,8 +719,11 @@ static u32 stmmac_usec2riwt(u32 usec, struct stmmac_priv *priv) | ||
2593 | { | ||
2594 | unsigned long clk = clk_get_rate(priv->plat->stmmac_clk); | ||
2595 | |||
2596 | - if (!clk) | ||
2597 | - return 0; | ||
2598 | + if (!clk) { | ||
2599 | + clk = priv->plat->clk_ref_rate; | ||
2600 | + if (!clk) | ||
2601 | + return 0; | ||
2602 | + } | ||
2603 | |||
2604 | return (usec * (clk / 1000000)) / 256; | ||
2605 | } | ||
2606 | @@ -729,8 +732,11 @@ static u32 stmmac_riwt2usec(u32 riwt, struct stmmac_priv *priv) | ||
2607 | { | ||
2608 | unsigned long clk = clk_get_rate(priv->plat->stmmac_clk); | ||
2609 | |||
2610 | - if (!clk) | ||
2611 | - return 0; | ||
2612 | + if (!clk) { | ||
2613 | + clk = priv->plat->clk_ref_rate; | ||
2614 | + if (!clk) | ||
2615 | + return 0; | ||
2616 | + } | ||
2617 | |||
2618 | return (riwt * 256) / (clk / 1000000); | ||
2619 | } | ||
2620 | diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | ||
2621 | index 123b74e25ed8..43ab9e905bed 100644 | ||
2622 | --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | ||
2623 | +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | ||
2624 | @@ -3028,10 +3028,22 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | ||
2625 | |||
2626 | tx_q = &priv->tx_queue[queue]; | ||
2627 | |||
2628 | + if (priv->tx_path_in_lpi_mode) | ||
2629 | + stmmac_disable_eee_mode(priv); | ||
2630 | + | ||
2631 | /* Manage oversized TCP frames for GMAC4 device */ | ||
2632 | if (skb_is_gso(skb) && priv->tso) { | ||
2633 | - if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) | ||
2634 | + if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { | ||
2635 | + /* | ||
2636 | + * There is no way to determine the number of TSO | ||
2637 | + * capable Queues. Let's use always the Queue 0 | ||
2638 | + * because if TSO is supported then at least this | ||
2639 | + * one will be capable. | ||
2640 | + */ | ||
2641 | + skb_set_queue_mapping(skb, 0); | ||
2642 | + | ||
2643 | return stmmac_tso_xmit(skb, dev); | ||
2644 | + } | ||
2645 | } | ||
2646 | |||
2647 | if (unlikely(stmmac_tx_avail(priv, queue) < nfrags + 1)) { | ||
2648 | @@ -3046,9 +3058,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | ||
2649 | return NETDEV_TX_BUSY; | ||
2650 | } | ||
2651 | |||
2652 | - if (priv->tx_path_in_lpi_mode) | ||
2653 | - stmmac_disable_eee_mode(priv); | ||
2654 | - | ||
2655 | entry = tx_q->cur_tx; | ||
2656 | first_entry = entry; | ||
2657 | WARN_ON(tx_q->tx_skbuff[first_entry]); | ||
2658 | diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c | ||
2659 | index c070a9e51ebf..fae572b38416 100644 | ||
2660 | --- a/drivers/net/wireless/ath/ath9k/init.c | ||
2661 | +++ b/drivers/net/wireless/ath/ath9k/init.c | ||
2662 | @@ -636,15 +636,15 @@ static int ath9k_of_init(struct ath_softc *sc) | ||
2663 | ret = ath9k_eeprom_request(sc, eeprom_name); | ||
2664 | if (ret) | ||
2665 | return ret; | ||
2666 | + | ||
2667 | + ah->ah_flags &= ~AH_USE_EEPROM; | ||
2668 | + ah->ah_flags |= AH_NO_EEP_SWAP; | ||
2669 | } | ||
2670 | |||
2671 | mac = of_get_mac_address(np); | ||
2672 | if (mac) | ||
2673 | ether_addr_copy(common->macaddr, mac); | ||
2674 | |||
2675 | - ah->ah_flags &= ~AH_USE_EEPROM; | ||
2676 | - ah->ah_flags |= AH_NO_EEP_SWAP; | ||
2677 | - | ||
2678 | return 0; | ||
2679 | } | ||
2680 | |||
2681 | diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c | ||
2682 | index 750bea3574ee..627df164b7b6 100644 | ||
2683 | --- a/drivers/net/wireless/ti/wlcore/sdio.c | ||
2684 | +++ b/drivers/net/wireless/ti/wlcore/sdio.c | ||
2685 | @@ -164,6 +164,12 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) | ||
2686 | } | ||
2687 | |||
2688 | sdio_claim_host(func); | ||
2689 | + /* | ||
2690 | + * To guarantee that the SDIO card is power cycled, as required to make | ||
2691 | + * the FW programming to succeed, let's do a brute force HW reset. | ||
2692 | + */ | ||
2693 | + mmc_hw_reset(card->host); | ||
2694 | + | ||
2695 | sdio_enable_func(func); | ||
2696 | sdio_release_host(func); | ||
2697 | |||
2698 | @@ -174,20 +180,13 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue) | ||
2699 | { | ||
2700 | struct sdio_func *func = dev_to_sdio_func(glue->dev); | ||
2701 | struct mmc_card *card = func->card; | ||
2702 | - int error; | ||
2703 | |||
2704 | sdio_claim_host(func); | ||
2705 | sdio_disable_func(func); | ||
2706 | sdio_release_host(func); | ||
2707 | |||
2708 | /* Let runtime PM know the card is powered off */ | ||
2709 | - error = pm_runtime_put(&card->dev); | ||
2710 | - if (error < 0 && error != -EBUSY) { | ||
2711 | - dev_err(&card->dev, "%s failed: %i\n", __func__, error); | ||
2712 | - | ||
2713 | - return error; | ||
2714 | - } | ||
2715 | - | ||
2716 | + pm_runtime_put(&card->dev); | ||
2717 | return 0; | ||
2718 | } | ||
2719 | |||
2720 | diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c | ||
2721 | index e0d2b7473901..2cdb3032ca0f 100644 | ||
2722 | --- a/drivers/nvme/host/core.c | ||
2723 | +++ b/drivers/nvme/host/core.c | ||
2724 | @@ -1182,6 +1182,7 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, | ||
2725 | * effects say only one namespace is affected. | ||
2726 | */ | ||
2727 | if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) { | ||
2728 | + mutex_lock(&ctrl->scan_lock); | ||
2729 | nvme_start_freeze(ctrl); | ||
2730 | nvme_wait_freeze(ctrl); | ||
2731 | } | ||
2732 | @@ -1210,8 +1211,10 @@ static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects) | ||
2733 | */ | ||
2734 | if (effects & NVME_CMD_EFFECTS_LBCC) | ||
2735 | nvme_update_formats(ctrl); | ||
2736 | - if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) | ||
2737 | + if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) { | ||
2738 | nvme_unfreeze(ctrl); | ||
2739 | + mutex_unlock(&ctrl->scan_lock); | ||
2740 | + } | ||
2741 | if (effects & NVME_CMD_EFFECTS_CCC) | ||
2742 | nvme_init_identify(ctrl); | ||
2743 | if (effects & (NVME_CMD_EFFECTS_NIC | NVME_CMD_EFFECTS_NCC)) | ||
2744 | @@ -3292,6 +3295,7 @@ static void nvme_scan_work(struct work_struct *work) | ||
2745 | if (nvme_identify_ctrl(ctrl, &id)) | ||
2746 | return; | ||
2747 | |||
2748 | + mutex_lock(&ctrl->scan_lock); | ||
2749 | nn = le32_to_cpu(id->nn); | ||
2750 | if (ctrl->vs >= NVME_VS(1, 1, 0) && | ||
2751 | !(ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS)) { | ||
2752 | @@ -3300,6 +3304,7 @@ static void nvme_scan_work(struct work_struct *work) | ||
2753 | } | ||
2754 | nvme_scan_ns_sequential(ctrl, nn); | ||
2755 | out_free_id: | ||
2756 | + mutex_unlock(&ctrl->scan_lock); | ||
2757 | kfree(id); | ||
2758 | down_write(&ctrl->namespaces_rwsem); | ||
2759 | list_sort(NULL, &ctrl->namespaces, ns_cmp); | ||
2760 | @@ -3535,6 +3540,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, | ||
2761 | |||
2762 | ctrl->state = NVME_CTRL_NEW; | ||
2763 | spin_lock_init(&ctrl->lock); | ||
2764 | + mutex_init(&ctrl->scan_lock); | ||
2765 | INIT_LIST_HEAD(&ctrl->namespaces); | ||
2766 | init_rwsem(&ctrl->namespaces_rwsem); | ||
2767 | ctrl->dev = dev; | ||
2768 | diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h | ||
2769 | index 60220de2db52..e82cdaec81c9 100644 | ||
2770 | --- a/drivers/nvme/host/nvme.h | ||
2771 | +++ b/drivers/nvme/host/nvme.h | ||
2772 | @@ -148,6 +148,7 @@ struct nvme_ctrl { | ||
2773 | enum nvme_ctrl_state state; | ||
2774 | bool identified; | ||
2775 | spinlock_t lock; | ||
2776 | + struct mutex scan_lock; | ||
2777 | const struct nvme_ctrl_ops *ops; | ||
2778 | struct request_queue *admin_q; | ||
2779 | struct request_queue *connect_q; | ||
2780 | diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c | ||
2781 | index f46313f441ec..7b9ef8e734e7 100644 | ||
2782 | --- a/drivers/nvme/host/pci.c | ||
2783 | +++ b/drivers/nvme/host/pci.c | ||
2784 | @@ -2260,27 +2260,18 @@ static void nvme_reset_work(struct work_struct *work) | ||
2785 | if (dev->ctrl.ctrl_config & NVME_CC_ENABLE) | ||
2786 | nvme_dev_disable(dev, false); | ||
2787 | |||
2788 | - /* | ||
2789 | - * Introduce CONNECTING state from nvme-fc/rdma transports to mark the | ||
2790 | - * initializing procedure here. | ||
2791 | - */ | ||
2792 | - if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_CONNECTING)) { | ||
2793 | - dev_warn(dev->ctrl.device, | ||
2794 | - "failed to mark controller CONNECTING\n"); | ||
2795 | - goto out; | ||
2796 | - } | ||
2797 | - | ||
2798 | + mutex_lock(&dev->shutdown_lock); | ||
2799 | result = nvme_pci_enable(dev); | ||
2800 | if (result) | ||
2801 | - goto out; | ||
2802 | + goto out_unlock; | ||
2803 | |||
2804 | result = nvme_pci_configure_admin_queue(dev); | ||
2805 | if (result) | ||
2806 | - goto out; | ||
2807 | + goto out_unlock; | ||
2808 | |||
2809 | result = nvme_alloc_admin_tags(dev); | ||
2810 | if (result) | ||
2811 | - goto out; | ||
2812 | + goto out_unlock; | ||
2813 | |||
2814 | /* | ||
2815 | * Limit the max command size to prevent iod->sg allocations going | ||
2816 | @@ -2288,6 +2279,17 @@ static void nvme_reset_work(struct work_struct *work) | ||
2817 | */ | ||
2818 | dev->ctrl.max_hw_sectors = NVME_MAX_KB_SZ << 1; | ||
2819 | dev->ctrl.max_segments = NVME_MAX_SEGS; | ||
2820 | + mutex_unlock(&dev->shutdown_lock); | ||
2821 | + | ||
2822 | + /* | ||
2823 | + * Introduce CONNECTING state from nvme-fc/rdma transports to mark the | ||
2824 | + * initializing procedure here. | ||
2825 | + */ | ||
2826 | + if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_CONNECTING)) { | ||
2827 | + dev_warn(dev->ctrl.device, | ||
2828 | + "failed to mark controller CONNECTING\n"); | ||
2829 | + goto out; | ||
2830 | + } | ||
2831 | |||
2832 | result = nvme_init_identify(&dev->ctrl); | ||
2833 | if (result) | ||
2834 | @@ -2352,6 +2354,8 @@ static void nvme_reset_work(struct work_struct *work) | ||
2835 | nvme_start_ctrl(&dev->ctrl); | ||
2836 | return; | ||
2837 | |||
2838 | + out_unlock: | ||
2839 | + mutex_unlock(&dev->shutdown_lock); | ||
2840 | out: | ||
2841 | nvme_remove_dead_ctrl(dev, result); | ||
2842 | } | ||
2843 | diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c | ||
2844 | index cf73a403d22d..cecbce21d01f 100644 | ||
2845 | --- a/drivers/pinctrl/pinctrl-mcp23s08.c | ||
2846 | +++ b/drivers/pinctrl/pinctrl-mcp23s08.c | ||
2847 | @@ -832,8 +832,13 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, | ||
2848 | break; | ||
2849 | |||
2850 | case MCP_TYPE_S18: | ||
2851 | + one_regmap_config = | ||
2852 | + devm_kmemdup(dev, &mcp23x17_regmap, | ||
2853 | + sizeof(struct regmap_config), GFP_KERNEL); | ||
2854 | + if (!one_regmap_config) | ||
2855 | + return -ENOMEM; | ||
2856 | mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp, | ||
2857 | - &mcp23x17_regmap); | ||
2858 | + one_regmap_config); | ||
2859 | mcp->reg_shift = 1; | ||
2860 | mcp->chip.ngpio = 16; | ||
2861 | mcp->chip.label = "mcp23s18"; | ||
2862 | diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig | ||
2863 | index 0c1aa6c314f5..7563c07e14e4 100644 | ||
2864 | --- a/drivers/platform/x86/Kconfig | ||
2865 | +++ b/drivers/platform/x86/Kconfig | ||
2866 | @@ -856,6 +856,7 @@ config TOSHIBA_WMI | ||
2867 | config ACPI_CMPC | ||
2868 | tristate "CMPC Laptop Extras" | ||
2869 | depends on ACPI && INPUT | ||
2870 | + depends on BACKLIGHT_LCD_SUPPORT | ||
2871 | depends on RFKILL || RFKILL=n | ||
2872 | select BACKLIGHT_CLASS_DEVICE | ||
2873 | help | ||
2874 | @@ -1077,6 +1078,7 @@ config INTEL_OAKTRAIL | ||
2875 | config SAMSUNG_Q10 | ||
2876 | tristate "Samsung Q10 Extras" | ||
2877 | depends on ACPI | ||
2878 | + depends on BACKLIGHT_LCD_SUPPORT | ||
2879 | select BACKLIGHT_CLASS_DEVICE | ||
2880 | ---help--- | ||
2881 | This driver provides support for backlight control on Samsung Q10 | ||
2882 | diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h | ||
2883 | index 970654fcc48d..2d1f6a583641 100644 | ||
2884 | --- a/drivers/s390/net/qeth_core.h | ||
2885 | +++ b/drivers/s390/net/qeth_core.h | ||
2886 | @@ -22,6 +22,7 @@ | ||
2887 | #include <linux/hashtable.h> | ||
2888 | #include <linux/ip.h> | ||
2889 | #include <linux/refcount.h> | ||
2890 | +#include <linux/workqueue.h> | ||
2891 | |||
2892 | #include <net/ipv6.h> | ||
2893 | #include <net/if_inet6.h> | ||
2894 | diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c | ||
2895 | index b03515d43745..56aacf32f71b 100644 | ||
2896 | --- a/drivers/s390/net/qeth_core_main.c | ||
2897 | +++ b/drivers/s390/net/qeth_core_main.c | ||
2898 | @@ -565,6 +565,7 @@ static int __qeth_issue_next_read(struct qeth_card *card) | ||
2899 | QETH_DBF_MESSAGE(2, "%s error in starting next read ccw! " | ||
2900 | "rc=%i\n", dev_name(&card->gdev->dev), rc); | ||
2901 | atomic_set(&channel->irq_pending, 0); | ||
2902 | + qeth_release_buffer(channel, iob); | ||
2903 | card->read_or_write_problem = 1; | ||
2904 | qeth_schedule_recovery(card); | ||
2905 | wake_up(&card->wait_q); | ||
2906 | @@ -1187,6 +1188,8 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, | ||
2907 | rc = qeth_get_problem(cdev, irb); | ||
2908 | if (rc) { | ||
2909 | card->read_or_write_problem = 1; | ||
2910 | + if (iob) | ||
2911 | + qeth_release_buffer(iob->channel, iob); | ||
2912 | qeth_clear_ipacmd_list(card); | ||
2913 | qeth_schedule_recovery(card); | ||
2914 | goto out; | ||
2915 | @@ -1852,6 +1855,7 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, | ||
2916 | QETH_DBF_MESSAGE(2, "Error2 in activating channel rc=%d\n", rc); | ||
2917 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | ||
2918 | atomic_set(&channel->irq_pending, 0); | ||
2919 | + qeth_release_buffer(channel, iob); | ||
2920 | wake_up(&card->wait_q); | ||
2921 | return rc; | ||
2922 | } | ||
2923 | @@ -1923,6 +1927,7 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, | ||
2924 | rc); | ||
2925 | QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); | ||
2926 | atomic_set(&channel->irq_pending, 0); | ||
2927 | + qeth_release_buffer(channel, iob); | ||
2928 | wake_up(&card->wait_q); | ||
2929 | return rc; | ||
2930 | } | ||
2931 | @@ -2110,6 +2115,7 @@ int qeth_send_control_data(struct qeth_card *card, int len, | ||
2932 | } | ||
2933 | reply = qeth_alloc_reply(card); | ||
2934 | if (!reply) { | ||
2935 | + qeth_release_buffer(channel, iob); | ||
2936 | return -ENOMEM; | ||
2937 | } | ||
2938 | reply->callback = reply_cb; | ||
2939 | @@ -2448,11 +2454,12 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx) | ||
2940 | return 0; | ||
2941 | } | ||
2942 | |||
2943 | -static void qeth_free_qdio_out_buf(struct qeth_qdio_out_q *q) | ||
2944 | +static void qeth_free_output_queue(struct qeth_qdio_out_q *q) | ||
2945 | { | ||
2946 | if (!q) | ||
2947 | return; | ||
2948 | |||
2949 | + qeth_clear_outq_buffers(q, 1); | ||
2950 | qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); | ||
2951 | kfree(q); | ||
2952 | } | ||
2953 | @@ -2526,10 +2533,8 @@ out_freeoutqbufs: | ||
2954 | card->qdio.out_qs[i]->bufs[j] = NULL; | ||
2955 | } | ||
2956 | out_freeoutq: | ||
2957 | - while (i > 0) { | ||
2958 | - qeth_free_qdio_out_buf(card->qdio.out_qs[--i]); | ||
2959 | - qeth_clear_outq_buffers(card->qdio.out_qs[i], 1); | ||
2960 | - } | ||
2961 | + while (i > 0) | ||
2962 | + qeth_free_output_queue(card->qdio.out_qs[--i]); | ||
2963 | kfree(card->qdio.out_qs); | ||
2964 | card->qdio.out_qs = NULL; | ||
2965 | out_freepool: | ||
2966 | @@ -2562,10 +2567,8 @@ static void qeth_free_qdio_buffers(struct qeth_card *card) | ||
2967 | qeth_free_buffer_pool(card); | ||
2968 | /* free outbound qdio_qs */ | ||
2969 | if (card->qdio.out_qs) { | ||
2970 | - for (i = 0; i < card->qdio.no_out_queues; ++i) { | ||
2971 | - qeth_clear_outq_buffers(card->qdio.out_qs[i], 1); | ||
2972 | - qeth_free_qdio_out_buf(card->qdio.out_qs[i]); | ||
2973 | - } | ||
2974 | + for (i = 0; i < card->qdio.no_out_queues; i++) | ||
2975 | + qeth_free_output_queue(card->qdio.out_qs[i]); | ||
2976 | kfree(card->qdio.out_qs); | ||
2977 | card->qdio.out_qs = NULL; | ||
2978 | } | ||
2979 | diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c | ||
2980 | index 76b2fba5fba2..b7513c5848cf 100644 | ||
2981 | --- a/drivers/s390/net/qeth_l2_main.c | ||
2982 | +++ b/drivers/s390/net/qeth_l2_main.c | ||
2983 | @@ -854,6 +854,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) | ||
2984 | |||
2985 | if (cgdev->state == CCWGROUP_ONLINE) | ||
2986 | qeth_l2_set_offline(cgdev); | ||
2987 | + | ||
2988 | + cancel_work_sync(&card->close_dev_work); | ||
2989 | if (qeth_netdev_is_registered(card->dev)) | ||
2990 | unregister_netdev(card->dev); | ||
2991 | } | ||
2992 | diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c | ||
2993 | index b7f6a8384543..7f71ca0d08e7 100644 | ||
2994 | --- a/drivers/s390/net/qeth_l3_main.c | ||
2995 | +++ b/drivers/s390/net/qeth_l3_main.c | ||
2996 | @@ -2611,6 +2611,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) | ||
2997 | if (cgdev->state == CCWGROUP_ONLINE) | ||
2998 | qeth_l3_set_offline(cgdev); | ||
2999 | |||
3000 | + cancel_work_sync(&card->close_dev_work); | ||
3001 | if (qeth_netdev_is_registered(card->dev)) | ||
3002 | unregister_netdev(card->dev); | ||
3003 | qeth_l3_clear_ip_htable(card, 0); | ||
3004 | diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c | ||
3005 | index 6be77b3aa8a5..ac79f2088b31 100644 | ||
3006 | --- a/drivers/scsi/53c700.c | ||
3007 | +++ b/drivers/scsi/53c700.c | ||
3008 | @@ -295,7 +295,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, | ||
3009 | if(tpnt->sdev_attrs == NULL) | ||
3010 | tpnt->sdev_attrs = NCR_700_dev_attrs; | ||
3011 | |||
3012 | - memory = dma_alloc_attrs(hostdata->dev, TOTAL_MEM_SIZE, &pScript, | ||
3013 | + memory = dma_alloc_attrs(dev, TOTAL_MEM_SIZE, &pScript, | ||
3014 | GFP_KERNEL, DMA_ATTR_NON_CONSISTENT); | ||
3015 | if(memory == NULL) { | ||
3016 | printk(KERN_ERR "53c700: Failed to allocate memory for driver, detaching\n"); | ||
3017 | diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c | ||
3018 | index 6e1b022a823d..3236240a4edd 100644 | ||
3019 | --- a/drivers/scsi/aacraid/commsup.c | ||
3020 | +++ b/drivers/scsi/aacraid/commsup.c | ||
3021 | @@ -1304,8 +1304,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | ||
3022 | ADD : DELETE; | ||
3023 | break; | ||
3024 | } | ||
3025 | - case AifBuManagerEvent: | ||
3026 | - aac_handle_aif_bu(dev, aifcmd); | ||
3027 | + break; | ||
3028 | + case AifBuManagerEvent: | ||
3029 | + aac_handle_aif_bu(dev, aifcmd); | ||
3030 | break; | ||
3031 | } | ||
3032 | |||
3033 | diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c | ||
3034 | index 350257c13a5b..bc9f2a2365f4 100644 | ||
3035 | --- a/drivers/scsi/bnx2fc/bnx2fc_io.c | ||
3036 | +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c | ||
3037 | @@ -240,6 +240,7 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) | ||
3038 | return NULL; | ||
3039 | } | ||
3040 | |||
3041 | + cmgr->hba = hba; | ||
3042 | cmgr->free_list = kcalloc(arr_sz, sizeof(*cmgr->free_list), | ||
3043 | GFP_KERNEL); | ||
3044 | if (!cmgr->free_list) { | ||
3045 | @@ -256,7 +257,6 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) | ||
3046 | goto mem_err; | ||
3047 | } | ||
3048 | |||
3049 | - cmgr->hba = hba; | ||
3050 | cmgr->cmds = (struct bnx2fc_cmd **)(cmgr + 1); | ||
3051 | |||
3052 | for (i = 0; i < arr_sz; i++) { | ||
3053 | @@ -295,7 +295,7 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) | ||
3054 | |||
3055 | /* Allocate pool of io_bdts - one for each bnx2fc_cmd */ | ||
3056 | mem_size = num_ios * sizeof(struct io_bdt *); | ||
3057 | - cmgr->io_bdt_pool = kmalloc(mem_size, GFP_KERNEL); | ||
3058 | + cmgr->io_bdt_pool = kzalloc(mem_size, GFP_KERNEL); | ||
3059 | if (!cmgr->io_bdt_pool) { | ||
3060 | printk(KERN_ERR PFX "failed to alloc io_bdt_pool\n"); | ||
3061 | goto mem_err; | ||
3062 | diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c | ||
3063 | index be83590ed955..ff943f477d6f 100644 | ||
3064 | --- a/drivers/scsi/libfc/fc_lport.c | ||
3065 | +++ b/drivers/scsi/libfc/fc_lport.c | ||
3066 | @@ -1726,14 +1726,14 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, | ||
3067 | fc_frame_payload_op(fp) != ELS_LS_ACC) { | ||
3068 | FC_LPORT_DBG(lport, "FLOGI not accepted or bad response\n"); | ||
3069 | fc_lport_error(lport, fp); | ||
3070 | - goto err; | ||
3071 | + goto out; | ||
3072 | } | ||
3073 | |||
3074 | flp = fc_frame_payload_get(fp, sizeof(*flp)); | ||
3075 | if (!flp) { | ||
3076 | FC_LPORT_DBG(lport, "FLOGI bad response\n"); | ||
3077 | fc_lport_error(lport, fp); | ||
3078 | - goto err; | ||
3079 | + goto out; | ||
3080 | } | ||
3081 | |||
3082 | mfs = ntohs(flp->fl_csp.sp_bb_data) & | ||
3083 | @@ -1743,7 +1743,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, | ||
3084 | FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, " | ||
3085 | "lport->mfs:%hu\n", mfs, lport->mfs); | ||
3086 | fc_lport_error(lport, fp); | ||
3087 | - goto err; | ||
3088 | + goto out; | ||
3089 | } | ||
3090 | |||
3091 | if (mfs <= lport->mfs) { | ||
3092 | diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c | ||
3093 | index 372387a450df..1797e47fab38 100644 | ||
3094 | --- a/drivers/scsi/libfc/fc_rport.c | ||
3095 | +++ b/drivers/scsi/libfc/fc_rport.c | ||
3096 | @@ -184,7 +184,6 @@ void fc_rport_destroy(struct kref *kref) | ||
3097 | struct fc_rport_priv *rdata; | ||
3098 | |||
3099 | rdata = container_of(kref, struct fc_rport_priv, kref); | ||
3100 | - WARN_ON(!list_empty(&rdata->peers)); | ||
3101 | kfree_rcu(rdata, rcu); | ||
3102 | } | ||
3103 | EXPORT_SYMBOL(fc_rport_destroy); | ||
3104 | diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c | ||
3105 | index 60bcc6df97a9..65305b3848bc 100644 | ||
3106 | --- a/drivers/scsi/scsi_debug.c | ||
3107 | +++ b/drivers/scsi/scsi_debug.c | ||
3108 | @@ -62,7 +62,7 @@ | ||
3109 | |||
3110 | /* make sure inq_product_rev string corresponds to this version */ | ||
3111 | #define SDEBUG_VERSION "0188" /* format to fit INQUIRY revision field */ | ||
3112 | -static const char *sdebug_version_date = "20180128"; | ||
3113 | +static const char *sdebug_version_date = "20190125"; | ||
3114 | |||
3115 | #define MY_NAME "scsi_debug" | ||
3116 | |||
3117 | @@ -735,7 +735,7 @@ static inline bool scsi_debug_lbp(void) | ||
3118 | (sdebug_lbpu || sdebug_lbpws || sdebug_lbpws10); | ||
3119 | } | ||
3120 | |||
3121 | -static void *fake_store(unsigned long long lba) | ||
3122 | +static void *lba2fake_store(unsigned long long lba) | ||
3123 | { | ||
3124 | lba = do_div(lba, sdebug_store_sectors); | ||
3125 | |||
3126 | @@ -2514,8 +2514,8 @@ static int do_device_access(struct scsi_cmnd *scmd, u32 sg_skip, u64 lba, | ||
3127 | return ret; | ||
3128 | } | ||
3129 | |||
3130 | -/* If fake_store(lba,num) compares equal to arr(num), then copy top half of | ||
3131 | - * arr into fake_store(lba,num) and return true. If comparison fails then | ||
3132 | +/* If lba2fake_store(lba,num) compares equal to arr(num), then copy top half of | ||
3133 | + * arr into lba2fake_store(lba,num) and return true. If comparison fails then | ||
3134 | * return false. */ | ||
3135 | static bool comp_write_worker(u64 lba, u32 num, const u8 *arr) | ||
3136 | { | ||
3137 | @@ -2643,7 +2643,7 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, | ||
3138 | if (sdt->app_tag == cpu_to_be16(0xffff)) | ||
3139 | continue; | ||
3140 | |||
3141 | - ret = dif_verify(sdt, fake_store(sector), sector, ei_lba); | ||
3142 | + ret = dif_verify(sdt, lba2fake_store(sector), sector, ei_lba); | ||
3143 | if (ret) { | ||
3144 | dif_errors++; | ||
3145 | return ret; | ||
3146 | @@ -3261,10 +3261,12 @@ err_out: | ||
3147 | static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, | ||
3148 | u32 ei_lba, bool unmap, bool ndob) | ||
3149 | { | ||
3150 | + int ret; | ||
3151 | unsigned long iflags; | ||
3152 | unsigned long long i; | ||
3153 | - int ret; | ||
3154 | - u64 lba_off; | ||
3155 | + u32 lb_size = sdebug_sector_size; | ||
3156 | + u64 block, lbaa; | ||
3157 | + u8 *fs1p; | ||
3158 | |||
3159 | ret = check_device_access_params(scp, lba, num); | ||
3160 | if (ret) | ||
3161 | @@ -3276,31 +3278,30 @@ static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, | ||
3162 | unmap_region(lba, num); | ||
3163 | goto out; | ||
3164 | } | ||
3165 | - | ||
3166 | - lba_off = lba * sdebug_sector_size; | ||
3167 | + lbaa = lba; | ||
3168 | + block = do_div(lbaa, sdebug_store_sectors); | ||
3169 | /* if ndob then zero 1 logical block, else fetch 1 logical block */ | ||
3170 | + fs1p = fake_storep + (block * lb_size); | ||
3171 | if (ndob) { | ||
3172 | - memset(fake_storep + lba_off, 0, sdebug_sector_size); | ||
3173 | + memset(fs1p, 0, lb_size); | ||
3174 | ret = 0; | ||
3175 | } else | ||
3176 | - ret = fetch_to_dev_buffer(scp, fake_storep + lba_off, | ||
3177 | - sdebug_sector_size); | ||
3178 | + ret = fetch_to_dev_buffer(scp, fs1p, lb_size); | ||
3179 | |||
3180 | if (-1 == ret) { | ||
3181 | write_unlock_irqrestore(&atomic_rw, iflags); | ||
3182 | return DID_ERROR << 16; | ||
3183 | - } else if (sdebug_verbose && !ndob && (ret < sdebug_sector_size)) | ||
3184 | + } else if (sdebug_verbose && !ndob && (ret < lb_size)) | ||
3185 | sdev_printk(KERN_INFO, scp->device, | ||
3186 | "%s: %s: lb size=%u, IO sent=%d bytes\n", | ||
3187 | - my_name, "write same", | ||
3188 | - sdebug_sector_size, ret); | ||
3189 | + my_name, "write same", lb_size, ret); | ||
3190 | |||
3191 | /* Copy first sector to remaining blocks */ | ||
3192 | - for (i = 1 ; i < num ; i++) | ||
3193 | - memcpy(fake_storep + ((lba + i) * sdebug_sector_size), | ||
3194 | - fake_storep + lba_off, | ||
3195 | - sdebug_sector_size); | ||
3196 | - | ||
3197 | + for (i = 1 ; i < num ; i++) { | ||
3198 | + lbaa = lba + i; | ||
3199 | + block = do_div(lbaa, sdebug_store_sectors); | ||
3200 | + memmove(fake_storep + (block * lb_size), fs1p, lb_size); | ||
3201 | + } | ||
3202 | if (scsi_debug_lbp()) | ||
3203 | map_region(lba, num); | ||
3204 | out: | ||
3205 | diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c | ||
3206 | index 8cc015183043..a4ac6073c555 100644 | ||
3207 | --- a/drivers/soc/fsl/qbman/qman.c | ||
3208 | +++ b/drivers/soc/fsl/qbman/qman.c | ||
3209 | @@ -1081,18 +1081,19 @@ static void qm_mr_process_task(struct work_struct *work); | ||
3210 | static irqreturn_t portal_isr(int irq, void *ptr) | ||
3211 | { | ||
3212 | struct qman_portal *p = ptr; | ||
3213 | - | ||
3214 | - u32 clear = QM_DQAVAIL_MASK | p->irq_sources; | ||
3215 | u32 is = qm_in(&p->p, QM_REG_ISR) & p->irq_sources; | ||
3216 | + u32 clear = 0; | ||
3217 | |||
3218 | if (unlikely(!is)) | ||
3219 | return IRQ_NONE; | ||
3220 | |||
3221 | /* DQRR-handling if it's interrupt-driven */ | ||
3222 | - if (is & QM_PIRQ_DQRI) | ||
3223 | + if (is & QM_PIRQ_DQRI) { | ||
3224 | __poll_portal_fast(p, QMAN_POLL_LIMIT); | ||
3225 | + clear = QM_DQAVAIL_MASK | QM_PIRQ_DQRI; | ||
3226 | + } | ||
3227 | /* Handling of anything else that's interrupt-driven */ | ||
3228 | - clear |= __poll_portal_slow(p, is); | ||
3229 | + clear |= __poll_portal_slow(p, is) & QM_PIRQ_SLOW; | ||
3230 | qm_out(&p->p, QM_REG_ISR, clear); | ||
3231 | return IRQ_HANDLED; | ||
3232 | } | ||
3233 | diff --git a/drivers/staging/erofs/inode.c b/drivers/staging/erofs/inode.c | ||
3234 | index 9e7815f55a17..7448744cc515 100644 | ||
3235 | --- a/drivers/staging/erofs/inode.c | ||
3236 | +++ b/drivers/staging/erofs/inode.c | ||
3237 | @@ -184,16 +184,16 @@ static int fill_inode(struct inode *inode, int isdir) | ||
3238 | /* setup the new inode */ | ||
3239 | if (S_ISREG(inode->i_mode)) { | ||
3240 | #ifdef CONFIG_EROFS_FS_XATTR | ||
3241 | - if (vi->xattr_isize) | ||
3242 | - inode->i_op = &erofs_generic_xattr_iops; | ||
3243 | + inode->i_op = &erofs_generic_xattr_iops; | ||
3244 | #endif | ||
3245 | inode->i_fop = &generic_ro_fops; | ||
3246 | } else if (S_ISDIR(inode->i_mode)) { | ||
3247 | inode->i_op = | ||
3248 | #ifdef CONFIG_EROFS_FS_XATTR | ||
3249 | - vi->xattr_isize ? &erofs_dir_xattr_iops : | ||
3250 | -#endif | ||
3251 | + &erofs_dir_xattr_iops; | ||
3252 | +#else | ||
3253 | &erofs_dir_iops; | ||
3254 | +#endif | ||
3255 | inode->i_fop = &erofs_dir_fops; | ||
3256 | } else if (S_ISLNK(inode->i_mode)) { | ||
3257 | /* by default, page_get_link is used for symlink */ | ||
3258 | diff --git a/drivers/staging/erofs/internal.h b/drivers/staging/erofs/internal.h | ||
3259 | index 9f44ed8f0023..c70f0c5237ea 100644 | ||
3260 | --- a/drivers/staging/erofs/internal.h | ||
3261 | +++ b/drivers/staging/erofs/internal.h | ||
3262 | @@ -327,12 +327,17 @@ static inline erofs_off_t iloc(struct erofs_sb_info *sbi, erofs_nid_t nid) | ||
3263 | return blknr_to_addr(sbi->meta_blkaddr) + (nid << sbi->islotbits); | ||
3264 | } | ||
3265 | |||
3266 | -#define inode_set_inited_xattr(inode) (EROFS_V(inode)->flags |= 1) | ||
3267 | -#define inode_has_inited_xattr(inode) (EROFS_V(inode)->flags & 1) | ||
3268 | +/* atomic flag definitions */ | ||
3269 | +#define EROFS_V_EA_INITED_BIT 0 | ||
3270 | + | ||
3271 | +/* bitlock definitions (arranged in reverse order) */ | ||
3272 | +#define EROFS_V_BL_XATTR_BIT (BITS_PER_LONG - 1) | ||
3273 | |||
3274 | struct erofs_vnode { | ||
3275 | erofs_nid_t nid; | ||
3276 | - unsigned int flags; | ||
3277 | + | ||
3278 | + /* atomic flags (including bitlocks) */ | ||
3279 | + unsigned long flags; | ||
3280 | |||
3281 | unsigned char data_mapping_mode; | ||
3282 | /* inline size in bytes */ | ||
3283 | @@ -485,8 +490,9 @@ struct erofs_map_blocks_iter { | ||
3284 | }; | ||
3285 | |||
3286 | |||
3287 | -static inline struct page *erofs_get_inline_page(struct inode *inode, | ||
3288 | - erofs_blk_t blkaddr) | ||
3289 | +static inline struct page * | ||
3290 | +erofs_get_inline_page(struct inode *inode, | ||
3291 | + erofs_blk_t blkaddr) | ||
3292 | { | ||
3293 | return erofs_get_meta_page(inode->i_sb, | ||
3294 | blkaddr, S_ISDIR(inode->i_mode)); | ||
3295 | diff --git a/drivers/staging/erofs/namei.c b/drivers/staging/erofs/namei.c | ||
3296 | index 546a47156101..023f64fa2c87 100644 | ||
3297 | --- a/drivers/staging/erofs/namei.c | ||
3298 | +++ b/drivers/staging/erofs/namei.c | ||
3299 | @@ -15,74 +15,77 @@ | ||
3300 | |||
3301 | #include <trace/events/erofs.h> | ||
3302 | |||
3303 | -/* based on the value of qn->len is accurate */ | ||
3304 | -static inline int dirnamecmp(struct qstr *qn, | ||
3305 | - struct qstr *qd, unsigned *matched) | ||
3306 | +struct erofs_qstr { | ||
3307 | + const unsigned char *name; | ||
3308 | + const unsigned char *end; | ||
3309 | +}; | ||
3310 | + | ||
3311 | +/* based on the end of qn is accurate and it must have the trailing '\0' */ | ||
3312 | +static inline int dirnamecmp(const struct erofs_qstr *qn, | ||
3313 | + const struct erofs_qstr *qd, | ||
3314 | + unsigned int *matched) | ||
3315 | { | ||
3316 | - unsigned i = *matched, len = min(qn->len, qd->len); | ||
3317 | -loop: | ||
3318 | - if (unlikely(i >= len)) { | ||
3319 | - *matched = i; | ||
3320 | - if (qn->len < qd->len) { | ||
3321 | - /* | ||
3322 | - * actually (qn->len == qd->len) | ||
3323 | - * when qd->name[i] == '\0' | ||
3324 | - */ | ||
3325 | - return qd->name[i] == '\0' ? 0 : -1; | ||
3326 | + unsigned int i = *matched; | ||
3327 | + | ||
3328 | + /* | ||
3329 | + * on-disk error, let's only BUG_ON in the debugging mode. | ||
3330 | + * otherwise, it will return 1 to just skip the invalid name | ||
3331 | + * and go on (in consideration of the lookup performance). | ||
3332 | + */ | ||
3333 | + DBG_BUGON(qd->name > qd->end); | ||
3334 | + | ||
3335 | + /* qd could not have trailing '\0' */ | ||
3336 | + /* However it is absolutely safe if < qd->end */ | ||
3337 | + while (qd->name + i < qd->end && qd->name[i] != '\0') { | ||
3338 | + if (qn->name[i] != qd->name[i]) { | ||
3339 | + *matched = i; | ||
3340 | + return qn->name[i] > qd->name[i] ? 1 : -1; | ||
3341 | } | ||
3342 | - return (qn->len > qd->len); | ||
3343 | + ++i; | ||
3344 | } | ||
3345 | - | ||
3346 | - if (qn->name[i] != qd->name[i]) { | ||
3347 | - *matched = i; | ||
3348 | - return qn->name[i] > qd->name[i] ? 1 : -1; | ||
3349 | - } | ||
3350 | - | ||
3351 | - ++i; | ||
3352 | - goto loop; | ||
3353 | + *matched = i; | ||
3354 | + /* See comments in __d_alloc on the terminating NUL character */ | ||
3355 | + return qn->name[i] == '\0' ? 0 : 1; | ||
3356 | } | ||
3357 | |||
3358 | -static struct erofs_dirent *find_target_dirent( | ||
3359 | - struct qstr *name, | ||
3360 | - u8 *data, int maxsize) | ||
3361 | +#define nameoff_from_disk(off, sz) (le16_to_cpu(off) & ((sz) - 1)) | ||
3362 | + | ||
3363 | +static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name, | ||
3364 | + u8 *data, | ||
3365 | + unsigned int dirblksize, | ||
3366 | + const int ndirents) | ||
3367 | { | ||
3368 | - unsigned ndirents, head, back; | ||
3369 | - unsigned startprfx, endprfx; | ||
3370 | + int head, back; | ||
3371 | + unsigned int startprfx, endprfx; | ||
3372 | struct erofs_dirent *const de = (struct erofs_dirent *)data; | ||
3373 | |||
3374 | - /* make sure that maxsize is valid */ | ||
3375 | - BUG_ON(maxsize < sizeof(struct erofs_dirent)); | ||
3376 | - | ||
3377 | - ndirents = le16_to_cpu(de->nameoff) / sizeof(*de); | ||
3378 | - | ||
3379 | - /* corrupted dir (may be unnecessary...) */ | ||
3380 | - BUG_ON(!ndirents); | ||
3381 | - | ||
3382 | - head = 0; | ||
3383 | + /* since the 1st dirent has been evaluated previously */ | ||
3384 | + head = 1; | ||
3385 | back = ndirents - 1; | ||
3386 | startprfx = endprfx = 0; | ||
3387 | |||
3388 | while (head <= back) { | ||
3389 | - unsigned mid = head + (back - head) / 2; | ||
3390 | - unsigned nameoff = le16_to_cpu(de[mid].nameoff); | ||
3391 | - unsigned matched = min(startprfx, endprfx); | ||
3392 | - | ||
3393 | - struct qstr dname = QSTR_INIT(data + nameoff, | ||
3394 | - unlikely(mid >= ndirents - 1) ? | ||
3395 | - maxsize - nameoff : | ||
3396 | - le16_to_cpu(de[mid + 1].nameoff) - nameoff); | ||
3397 | + const int mid = head + (back - head) / 2; | ||
3398 | + const int nameoff = nameoff_from_disk(de[mid].nameoff, | ||
3399 | + dirblksize); | ||
3400 | + unsigned int matched = min(startprfx, endprfx); | ||
3401 | + struct erofs_qstr dname = { | ||
3402 | + .name = data + nameoff, | ||
3403 | + .end = unlikely(mid >= ndirents - 1) ? | ||
3404 | + data + dirblksize : | ||
3405 | + data + nameoff_from_disk(de[mid + 1].nameoff, | ||
3406 | + dirblksize) | ||
3407 | + }; | ||
3408 | |||
3409 | /* string comparison without already matched prefix */ | ||
3410 | int ret = dirnamecmp(name, &dname, &matched); | ||
3411 | |||
3412 | - if (unlikely(!ret)) | ||
3413 | + if (unlikely(!ret)) { | ||
3414 | return de + mid; | ||
3415 | - else if (ret > 0) { | ||
3416 | + } else if (ret > 0) { | ||
3417 | head = mid + 1; | ||
3418 | startprfx = matched; | ||
3419 | - } else if (unlikely(mid < 1)) /* fix "mid" overflow */ | ||
3420 | - break; | ||
3421 | - else { | ||
3422 | + } else { | ||
3423 | back = mid - 1; | ||
3424 | endprfx = matched; | ||
3425 | } | ||
3426 | @@ -91,12 +94,12 @@ static struct erofs_dirent *find_target_dirent( | ||
3427 | return ERR_PTR(-ENOENT); | ||
3428 | } | ||
3429 | |||
3430 | -static struct page *find_target_block_classic( | ||
3431 | - struct inode *dir, | ||
3432 | - struct qstr *name, int *_diff) | ||
3433 | +static struct page *find_target_block_classic(struct inode *dir, | ||
3434 | + struct erofs_qstr *name, | ||
3435 | + int *_ndirents) | ||
3436 | { | ||
3437 | - unsigned startprfx, endprfx; | ||
3438 | - unsigned head, back; | ||
3439 | + unsigned int startprfx, endprfx; | ||
3440 | + int head, back; | ||
3441 | struct address_space *const mapping = dir->i_mapping; | ||
3442 | struct page *candidate = ERR_PTR(-ENOENT); | ||
3443 | |||
3444 | @@ -105,41 +108,43 @@ static struct page *find_target_block_classic( | ||
3445 | back = inode_datablocks(dir) - 1; | ||
3446 | |||
3447 | while (head <= back) { | ||
3448 | - unsigned mid = head + (back - head) / 2; | ||
3449 | + const int mid = head + (back - head) / 2; | ||
3450 | struct page *page = read_mapping_page(mapping, mid, NULL); | ||
3451 | |||
3452 | - if (IS_ERR(page)) { | ||
3453 | -exact_out: | ||
3454 | - if (!IS_ERR(candidate)) /* valid candidate */ | ||
3455 | - put_page(candidate); | ||
3456 | - return page; | ||
3457 | - } else { | ||
3458 | - int diff; | ||
3459 | - unsigned ndirents, matched; | ||
3460 | - struct qstr dname; | ||
3461 | + if (!IS_ERR(page)) { | ||
3462 | struct erofs_dirent *de = kmap_atomic(page); | ||
3463 | - unsigned nameoff = le16_to_cpu(de->nameoff); | ||
3464 | - | ||
3465 | - ndirents = nameoff / sizeof(*de); | ||
3466 | + const int nameoff = nameoff_from_disk(de->nameoff, | ||
3467 | + EROFS_BLKSIZ); | ||
3468 | + const int ndirents = nameoff / sizeof(*de); | ||
3469 | + int diff; | ||
3470 | + unsigned int matched; | ||
3471 | + struct erofs_qstr dname; | ||
3472 | |||
3473 | - /* corrupted dir (should have one entry at least) */ | ||
3474 | - BUG_ON(!ndirents || nameoff > PAGE_SIZE); | ||
3475 | + if (unlikely(!ndirents)) { | ||
3476 | + DBG_BUGON(1); | ||
3477 | + kunmap_atomic(de); | ||
3478 | + put_page(page); | ||
3479 | + page = ERR_PTR(-EIO); | ||
3480 | + goto out; | ||
3481 | + } | ||
3482 | |||
3483 | matched = min(startprfx, endprfx); | ||
3484 | |||
3485 | dname.name = (u8 *)de + nameoff; | ||
3486 | - dname.len = ndirents == 1 ? | ||
3487 | - /* since the rest of the last page is 0 */ | ||
3488 | - EROFS_BLKSIZ - nameoff | ||
3489 | - : le16_to_cpu(de[1].nameoff) - nameoff; | ||
3490 | + if (ndirents == 1) | ||
3491 | + dname.end = (u8 *)de + EROFS_BLKSIZ; | ||
3492 | + else | ||
3493 | + dname.end = (u8 *)de + | ||
3494 | + nameoff_from_disk(de[1].nameoff, | ||
3495 | + EROFS_BLKSIZ); | ||
3496 | |||
3497 | /* string comparison without already matched prefix */ | ||
3498 | diff = dirnamecmp(name, &dname, &matched); | ||
3499 | kunmap_atomic(de); | ||
3500 | |||
3501 | if (unlikely(!diff)) { | ||
3502 | - *_diff = 0; | ||
3503 | - goto exact_out; | ||
3504 | + *_ndirents = 0; | ||
3505 | + goto out; | ||
3506 | } else if (diff > 0) { | ||
3507 | head = mid + 1; | ||
3508 | startprfx = matched; | ||
3509 | @@ -147,45 +152,51 @@ exact_out: | ||
3510 | if (likely(!IS_ERR(candidate))) | ||
3511 | put_page(candidate); | ||
3512 | candidate = page; | ||
3513 | + *_ndirents = ndirents; | ||
3514 | } else { | ||
3515 | put_page(page); | ||
3516 | |||
3517 | - if (unlikely(mid < 1)) /* fix "mid" overflow */ | ||
3518 | - break; | ||
3519 | - | ||
3520 | back = mid - 1; | ||
3521 | endprfx = matched; | ||
3522 | } | ||
3523 | + continue; | ||
3524 | } | ||
3525 | +out: /* free if the candidate is valid */ | ||
3526 | + if (!IS_ERR(candidate)) | ||
3527 | + put_page(candidate); | ||
3528 | + return page; | ||
3529 | } | ||
3530 | - *_diff = 1; | ||
3531 | return candidate; | ||
3532 | } | ||
3533 | |||
3534 | int erofs_namei(struct inode *dir, | ||
3535 | - struct qstr *name, | ||
3536 | - erofs_nid_t *nid, unsigned *d_type) | ||
3537 | + struct qstr *name, | ||
3538 | + erofs_nid_t *nid, unsigned int *d_type) | ||
3539 | { | ||
3540 | - int diff; | ||
3541 | + int ndirents; | ||
3542 | struct page *page; | ||
3543 | - u8 *data; | ||
3544 | + void *data; | ||
3545 | struct erofs_dirent *de; | ||
3546 | + struct erofs_qstr qn; | ||
3547 | |||
3548 | if (unlikely(!dir->i_size)) | ||
3549 | return -ENOENT; | ||
3550 | |||
3551 | - diff = 1; | ||
3552 | - page = find_target_block_classic(dir, name, &diff); | ||
3553 | + qn.name = name->name; | ||
3554 | + qn.end = name->name + name->len; | ||
3555 | + | ||
3556 | + ndirents = 0; | ||
3557 | + page = find_target_block_classic(dir, &qn, &ndirents); | ||
3558 | |||
3559 | if (unlikely(IS_ERR(page))) | ||
3560 | return PTR_ERR(page); | ||
3561 | |||
3562 | data = kmap_atomic(page); | ||
3563 | /* the target page has been mapped */ | ||
3564 | - de = likely(diff) ? | ||
3565 | - /* since the rest of the last page is 0 */ | ||
3566 | - find_target_dirent(name, data, EROFS_BLKSIZ) : | ||
3567 | - (struct erofs_dirent *)data; | ||
3568 | + if (ndirents) | ||
3569 | + de = find_target_dirent(&qn, data, EROFS_BLKSIZ, ndirents); | ||
3570 | + else | ||
3571 | + de = (struct erofs_dirent *)data; | ||
3572 | |||
3573 | if (likely(!IS_ERR(de))) { | ||
3574 | *nid = le64_to_cpu(de->nid); | ||
3575 | diff --git a/drivers/staging/erofs/xattr.c b/drivers/staging/erofs/xattr.c | ||
3576 | index 0e9cfeccdf99..2db99cff3c99 100644 | ||
3577 | --- a/drivers/staging/erofs/xattr.c | ||
3578 | +++ b/drivers/staging/erofs/xattr.c | ||
3579 | @@ -24,36 +24,77 @@ struct xattr_iter { | ||
3580 | |||
3581 | static inline void xattr_iter_end(struct xattr_iter *it, bool atomic) | ||
3582 | { | ||
3583 | - /* only init_inode_xattrs use non-atomic once */ | ||
3584 | + /* the only user of kunmap() is 'init_inode_xattrs' */ | ||
3585 | if (unlikely(!atomic)) | ||
3586 | kunmap(it->page); | ||
3587 | else | ||
3588 | kunmap_atomic(it->kaddr); | ||
3589 | + | ||
3590 | unlock_page(it->page); | ||
3591 | put_page(it->page); | ||
3592 | } | ||
3593 | |||
3594 | -static void init_inode_xattrs(struct inode *inode) | ||
3595 | +static inline void xattr_iter_end_final(struct xattr_iter *it) | ||
3596 | +{ | ||
3597 | + if (!it->page) | ||
3598 | + return; | ||
3599 | + | ||
3600 | + xattr_iter_end(it, true); | ||
3601 | +} | ||
3602 | + | ||
3603 | +static int init_inode_xattrs(struct inode *inode) | ||
3604 | { | ||
3605 | + struct erofs_vnode *const vi = EROFS_V(inode); | ||
3606 | struct xattr_iter it; | ||
3607 | unsigned i; | ||
3608 | struct erofs_xattr_ibody_header *ih; | ||
3609 | struct erofs_sb_info *sbi; | ||
3610 | - struct erofs_vnode *vi; | ||
3611 | bool atomic_map; | ||
3612 | + int ret = 0; | ||
3613 | |||
3614 | - if (likely(inode_has_inited_xattr(inode))) | ||
3615 | - return; | ||
3616 | + /* the most case is that xattrs of this inode are initialized. */ | ||
3617 | + if (test_bit(EROFS_V_EA_INITED_BIT, &vi->flags)) | ||
3618 | + return 0; | ||
3619 | + | ||
3620 | + if (wait_on_bit_lock(&vi->flags, EROFS_V_BL_XATTR_BIT, TASK_KILLABLE)) | ||
3621 | + return -ERESTARTSYS; | ||
3622 | |||
3623 | - vi = EROFS_V(inode); | ||
3624 | - BUG_ON(!vi->xattr_isize); | ||
3625 | + /* someone has initialized xattrs for us? */ | ||
3626 | + if (test_bit(EROFS_V_EA_INITED_BIT, &vi->flags)) | ||
3627 | + goto out_unlock; | ||
3628 | + | ||
3629 | + /* | ||
3630 | + * bypass all xattr operations if ->xattr_isize is not greater than | ||
3631 | + * sizeof(struct erofs_xattr_ibody_header), in detail: | ||
3632 | + * 1) it is not enough to contain erofs_xattr_ibody_header then | ||
3633 | + * ->xattr_isize should be 0 (it means no xattr); | ||
3634 | + * 2) it is just to contain erofs_xattr_ibody_header, which is on-disk | ||
3635 | + * undefined right now (maybe use later with some new sb feature). | ||
3636 | + */ | ||
3637 | + if (vi->xattr_isize == sizeof(struct erofs_xattr_ibody_header)) { | ||
3638 | + errln("xattr_isize %d of nid %llu is not supported yet", | ||
3639 | + vi->xattr_isize, vi->nid); | ||
3640 | + ret = -ENOTSUPP; | ||
3641 | + goto out_unlock; | ||
3642 | + } else if (vi->xattr_isize < sizeof(struct erofs_xattr_ibody_header)) { | ||
3643 | + if (unlikely(vi->xattr_isize)) { | ||
3644 | + DBG_BUGON(1); | ||
3645 | + ret = -EIO; | ||
3646 | + goto out_unlock; /* xattr ondisk layout error */ | ||
3647 | + } | ||
3648 | + ret = -ENOATTR; | ||
3649 | + goto out_unlock; | ||
3650 | + } | ||
3651 | |||
3652 | sbi = EROFS_I_SB(inode); | ||
3653 | it.blkaddr = erofs_blknr(iloc(sbi, vi->nid) + vi->inode_isize); | ||
3654 | it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize); | ||
3655 | |||
3656 | it.page = erofs_get_inline_page(inode, it.blkaddr); | ||
3657 | - BUG_ON(IS_ERR(it.page)); | ||
3658 | + if (IS_ERR(it.page)) { | ||
3659 | + ret = PTR_ERR(it.page); | ||
3660 | + goto out_unlock; | ||
3661 | + } | ||
3662 | |||
3663 | /* read in shared xattr array (non-atomic, see kmalloc below) */ | ||
3664 | it.kaddr = kmap(it.page); | ||
3665 | @@ -62,9 +103,13 @@ static void init_inode_xattrs(struct inode *inode) | ||
3666 | ih = (struct erofs_xattr_ibody_header *)(it.kaddr + it.ofs); | ||
3667 | |||
3668 | vi->xattr_shared_count = ih->h_shared_count; | ||
3669 | - vi->xattr_shared_xattrs = (unsigned *)kmalloc_array( | ||
3670 | - vi->xattr_shared_count, sizeof(unsigned), | ||
3671 | - GFP_KERNEL | __GFP_NOFAIL); | ||
3672 | + vi->xattr_shared_xattrs = kmalloc_array(vi->xattr_shared_count, | ||
3673 | + sizeof(uint), GFP_KERNEL); | ||
3674 | + if (!vi->xattr_shared_xattrs) { | ||
3675 | + xattr_iter_end(&it, atomic_map); | ||
3676 | + ret = -ENOMEM; | ||
3677 | + goto out_unlock; | ||
3678 | + } | ||
3679 | |||
3680 | /* let's skip ibody header */ | ||
3681 | it.ofs += sizeof(struct erofs_xattr_ibody_header); | ||
3682 | @@ -77,7 +122,12 @@ static void init_inode_xattrs(struct inode *inode) | ||
3683 | |||
3684 | it.page = erofs_get_meta_page(inode->i_sb, | ||
3685 | ++it.blkaddr, S_ISDIR(inode->i_mode)); | ||
3686 | - BUG_ON(IS_ERR(it.page)); | ||
3687 | + if (IS_ERR(it.page)) { | ||
3688 | + kfree(vi->xattr_shared_xattrs); | ||
3689 | + vi->xattr_shared_xattrs = NULL; | ||
3690 | + ret = PTR_ERR(it.page); | ||
3691 | + goto out_unlock; | ||
3692 | + } | ||
3693 | |||
3694 | it.kaddr = kmap_atomic(it.page); | ||
3695 | atomic_map = true; | ||
3696 | @@ -89,7 +139,11 @@ static void init_inode_xattrs(struct inode *inode) | ||
3697 | } | ||
3698 | xattr_iter_end(&it, atomic_map); | ||
3699 | |||
3700 | - inode_set_inited_xattr(inode); | ||
3701 | + set_bit(EROFS_V_EA_INITED_BIT, &vi->flags); | ||
3702 | + | ||
3703 | +out_unlock: | ||
3704 | + clear_and_wake_up_bit(EROFS_V_BL_XATTR_BIT, &vi->flags); | ||
3705 | + return ret; | ||
3706 | } | ||
3707 | |||
3708 | struct xattr_iter_handlers { | ||
3709 | @@ -99,18 +153,25 @@ struct xattr_iter_handlers { | ||
3710 | void (*value)(struct xattr_iter *, unsigned, char *, unsigned); | ||
3711 | }; | ||
3712 | |||
3713 | -static void xattr_iter_fixup(struct xattr_iter *it) | ||
3714 | +static inline int xattr_iter_fixup(struct xattr_iter *it) | ||
3715 | { | ||
3716 | - if (unlikely(it->ofs >= EROFS_BLKSIZ)) { | ||
3717 | - xattr_iter_end(it, true); | ||
3718 | + if (it->ofs < EROFS_BLKSIZ) | ||
3719 | + return 0; | ||
3720 | |||
3721 | - it->blkaddr += erofs_blknr(it->ofs); | ||
3722 | - it->page = erofs_get_meta_page(it->sb, it->blkaddr, false); | ||
3723 | - BUG_ON(IS_ERR(it->page)); | ||
3724 | + xattr_iter_end(it, true); | ||
3725 | |||
3726 | - it->kaddr = kmap_atomic(it->page); | ||
3727 | - it->ofs = erofs_blkoff(it->ofs); | ||
3728 | + it->blkaddr += erofs_blknr(it->ofs); | ||
3729 | + it->page = erofs_get_meta_page(it->sb, it->blkaddr, false); | ||
3730 | + if (IS_ERR(it->page)) { | ||
3731 | + int err = PTR_ERR(it->page); | ||
3732 | + | ||
3733 | + it->page = NULL; | ||
3734 | + return err; | ||
3735 | } | ||
3736 | + | ||
3737 | + it->kaddr = kmap_atomic(it->page); | ||
3738 | + it->ofs = erofs_blkoff(it->ofs); | ||
3739 | + return 0; | ||
3740 | } | ||
3741 | |||
3742 | static int inline_xattr_iter_begin(struct xattr_iter *it, | ||
3743 | @@ -132,21 +193,24 @@ static int inline_xattr_iter_begin(struct xattr_iter *it, | ||
3744 | it->ofs = erofs_blkoff(iloc(sbi, vi->nid) + inline_xattr_ofs); | ||
3745 | |||
3746 | it->page = erofs_get_inline_page(inode, it->blkaddr); | ||
3747 | - BUG_ON(IS_ERR(it->page)); | ||
3748 | - it->kaddr = kmap_atomic(it->page); | ||
3749 | + if (IS_ERR(it->page)) | ||
3750 | + return PTR_ERR(it->page); | ||
3751 | |||
3752 | + it->kaddr = kmap_atomic(it->page); | ||
3753 | return vi->xattr_isize - xattr_header_sz; | ||
3754 | } | ||
3755 | |||
3756 | static int xattr_foreach(struct xattr_iter *it, | ||
3757 | - struct xattr_iter_handlers *op, unsigned *tlimit) | ||
3758 | + const struct xattr_iter_handlers *op, unsigned int *tlimit) | ||
3759 | { | ||
3760 | struct erofs_xattr_entry entry; | ||
3761 | unsigned value_sz, processed, slice; | ||
3762 | int err; | ||
3763 | |||
3764 | /* 0. fixup blkaddr, ofs, ipage */ | ||
3765 | - xattr_iter_fixup(it); | ||
3766 | + err = xattr_iter_fixup(it); | ||
3767 | + if (err) | ||
3768 | + return err; | ||
3769 | |||
3770 | /* | ||
3771 | * 1. read xattr entry to the memory, | ||
3772 | @@ -178,7 +242,9 @@ static int xattr_foreach(struct xattr_iter *it, | ||
3773 | if (it->ofs >= EROFS_BLKSIZ) { | ||
3774 | BUG_ON(it->ofs > EROFS_BLKSIZ); | ||
3775 | |||
3776 | - xattr_iter_fixup(it); | ||
3777 | + err = xattr_iter_fixup(it); | ||
3778 | + if (err) | ||
3779 | + goto out; | ||
3780 | it->ofs = 0; | ||
3781 | } | ||
3782 | |||
3783 | @@ -210,7 +276,10 @@ static int xattr_foreach(struct xattr_iter *it, | ||
3784 | while (processed < value_sz) { | ||
3785 | if (it->ofs >= EROFS_BLKSIZ) { | ||
3786 | BUG_ON(it->ofs > EROFS_BLKSIZ); | ||
3787 | - xattr_iter_fixup(it); | ||
3788 | + | ||
3789 | + err = xattr_iter_fixup(it); | ||
3790 | + if (err) | ||
3791 | + goto out; | ||
3792 | it->ofs = 0; | ||
3793 | } | ||
3794 | |||
3795 | @@ -270,7 +339,7 @@ static void xattr_copyvalue(struct xattr_iter *_it, | ||
3796 | memcpy(it->buffer + processed, buf, len); | ||
3797 | } | ||
3798 | |||
3799 | -static struct xattr_iter_handlers find_xattr_handlers = { | ||
3800 | +static const struct xattr_iter_handlers find_xattr_handlers = { | ||
3801 | .entry = xattr_entrymatch, | ||
3802 | .name = xattr_namematch, | ||
3803 | .alloc_buffer = xattr_checkbuffer, | ||
3804 | @@ -291,8 +360,11 @@ static int inline_getxattr(struct inode *inode, struct getxattr_iter *it) | ||
3805 | ret = xattr_foreach(&it->it, &find_xattr_handlers, &remaining); | ||
3806 | if (ret >= 0) | ||
3807 | break; | ||
3808 | + | ||
3809 | + if (ret != -ENOATTR) /* -ENOMEM, -EIO, etc. */ | ||
3810 | + break; | ||
3811 | } | ||
3812 | - xattr_iter_end(&it->it, true); | ||
3813 | + xattr_iter_end_final(&it->it); | ||
3814 | |||
3815 | return ret < 0 ? ret : it->buffer_size; | ||
3816 | } | ||
3817 | @@ -315,8 +387,10 @@ static int shared_getxattr(struct inode *inode, struct getxattr_iter *it) | ||
3818 | xattr_iter_end(&it->it, true); | ||
3819 | |||
3820 | it->it.page = erofs_get_meta_page(inode->i_sb, | ||
3821 | - blkaddr, false); | ||
3822 | - BUG_ON(IS_ERR(it->it.page)); | ||
3823 | + blkaddr, false); | ||
3824 | + if (IS_ERR(it->it.page)) | ||
3825 | + return PTR_ERR(it->it.page); | ||
3826 | + | ||
3827 | it->it.kaddr = kmap_atomic(it->it.page); | ||
3828 | it->it.blkaddr = blkaddr; | ||
3829 | } | ||
3830 | @@ -324,9 +398,12 @@ static int shared_getxattr(struct inode *inode, struct getxattr_iter *it) | ||
3831 | ret = xattr_foreach(&it->it, &find_xattr_handlers, NULL); | ||
3832 | if (ret >= 0) | ||
3833 | break; | ||
3834 | + | ||
3835 | + if (ret != -ENOATTR) /* -ENOMEM, -EIO, etc. */ | ||
3836 | + break; | ||
3837 | } | ||
3838 | if (vi->xattr_shared_count) | ||
3839 | - xattr_iter_end(&it->it, true); | ||
3840 | + xattr_iter_end_final(&it->it); | ||
3841 | |||
3842 | return ret < 0 ? ret : it->buffer_size; | ||
3843 | } | ||
3844 | @@ -351,7 +428,9 @@ int erofs_getxattr(struct inode *inode, int index, | ||
3845 | if (unlikely(name == NULL)) | ||
3846 | return -EINVAL; | ||
3847 | |||
3848 | - init_inode_xattrs(inode); | ||
3849 | + ret = init_inode_xattrs(inode); | ||
3850 | + if (ret) | ||
3851 | + return ret; | ||
3852 | |||
3853 | it.index = index; | ||
3854 | |||
3855 | @@ -374,7 +453,6 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler, | ||
3856 | struct dentry *unused, struct inode *inode, | ||
3857 | const char *name, void *buffer, size_t size) | ||
3858 | { | ||
3859 | - struct erofs_vnode *const vi = EROFS_V(inode); | ||
3860 | struct erofs_sb_info *const sbi = EROFS_I_SB(inode); | ||
3861 | |||
3862 | switch (handler->flags) { | ||
3863 | @@ -392,9 +470,6 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler, | ||
3864 | return -EINVAL; | ||
3865 | } | ||
3866 | |||
3867 | - if (!vi->xattr_isize) | ||
3868 | - return -ENOATTR; | ||
3869 | - | ||
3870 | return erofs_getxattr(inode, handler->flags, name, buffer, size); | ||
3871 | } | ||
3872 | |||
3873 | @@ -494,7 +569,7 @@ static int xattr_skipvalue(struct xattr_iter *_it, | ||
3874 | return 1; | ||
3875 | } | ||
3876 | |||
3877 | -static struct xattr_iter_handlers list_xattr_handlers = { | ||
3878 | +static const struct xattr_iter_handlers list_xattr_handlers = { | ||
3879 | .entry = xattr_entrylist, | ||
3880 | .name = xattr_namelist, | ||
3881 | .alloc_buffer = xattr_skipvalue, | ||
3882 | @@ -516,7 +591,7 @@ static int inline_listxattr(struct listxattr_iter *it) | ||
3883 | if (ret < 0) | ||
3884 | break; | ||
3885 | } | ||
3886 | - xattr_iter_end(&it->it, true); | ||
3887 | + xattr_iter_end_final(&it->it); | ||
3888 | return ret < 0 ? ret : it->buffer_ofs; | ||
3889 | } | ||
3890 | |||
3891 | @@ -538,8 +613,10 @@ static int shared_listxattr(struct listxattr_iter *it) | ||
3892 | xattr_iter_end(&it->it, true); | ||
3893 | |||
3894 | it->it.page = erofs_get_meta_page(inode->i_sb, | ||
3895 | - blkaddr, false); | ||
3896 | - BUG_ON(IS_ERR(it->it.page)); | ||
3897 | + blkaddr, false); | ||
3898 | + if (IS_ERR(it->it.page)) | ||
3899 | + return PTR_ERR(it->it.page); | ||
3900 | + | ||
3901 | it->it.kaddr = kmap_atomic(it->it.page); | ||
3902 | it->it.blkaddr = blkaddr; | ||
3903 | } | ||
3904 | @@ -549,7 +626,7 @@ static int shared_listxattr(struct listxattr_iter *it) | ||
3905 | break; | ||
3906 | } | ||
3907 | if (vi->xattr_shared_count) | ||
3908 | - xattr_iter_end(&it->it, true); | ||
3909 | + xattr_iter_end_final(&it->it); | ||
3910 | |||
3911 | return ret < 0 ? ret : it->buffer_ofs; | ||
3912 | } | ||
3913 | @@ -560,7 +637,9 @@ ssize_t erofs_listxattr(struct dentry *dentry, | ||
3914 | int ret; | ||
3915 | struct listxattr_iter it; | ||
3916 | |||
3917 | - init_inode_xattrs(d_inode(dentry)); | ||
3918 | + ret = init_inode_xattrs(d_inode(dentry)); | ||
3919 | + if (ret) | ||
3920 | + return ret; | ||
3921 | |||
3922 | it.dentry = dentry; | ||
3923 | it.buffer = buffer; | ||
3924 | diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig | ||
3925 | index d7312eed6088..91ea3083e7ad 100644 | ||
3926 | --- a/drivers/usb/phy/Kconfig | ||
3927 | +++ b/drivers/usb/phy/Kconfig | ||
3928 | @@ -21,7 +21,7 @@ config AB8500_USB | ||
3929 | |||
3930 | config FSL_USB2_OTG | ||
3931 | bool "Freescale USB OTG Transceiver Driver" | ||
3932 | - depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG_FSM && PM | ||
3933 | + depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG_FSM=y && PM | ||
3934 | depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y' | ||
3935 | select USB_PHY | ||
3936 | help | ||
3937 | diff --git a/fs/autofs/expire.c b/fs/autofs/expire.c | ||
3938 | index d441244b79df..28d9c2b1b3bb 100644 | ||
3939 | --- a/fs/autofs/expire.c | ||
3940 | +++ b/fs/autofs/expire.c | ||
3941 | @@ -596,7 +596,6 @@ int autofs_expire_run(struct super_block *sb, | ||
3942 | pkt.len = dentry->d_name.len; | ||
3943 | memcpy(pkt.name, dentry->d_name.name, pkt.len); | ||
3944 | pkt.name[pkt.len] = '\0'; | ||
3945 | - dput(dentry); | ||
3946 | |||
3947 | if (copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire))) | ||
3948 | ret = -EFAULT; | ||
3949 | @@ -609,6 +608,8 @@ int autofs_expire_run(struct super_block *sb, | ||
3950 | complete_all(&ino->expire_complete); | ||
3951 | spin_unlock(&sbi->fs_lock); | ||
3952 | |||
3953 | + dput(dentry); | ||
3954 | + | ||
3955 | return ret; | ||
3956 | } | ||
3957 | |||
3958 | diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c | ||
3959 | index 846c052569dd..3c14a8e45ffb 100644 | ||
3960 | --- a/fs/autofs/inode.c | ||
3961 | +++ b/fs/autofs/inode.c | ||
3962 | @@ -255,8 +255,10 @@ int autofs_fill_super(struct super_block *s, void *data, int silent) | ||
3963 | } | ||
3964 | root_inode = autofs_get_inode(s, S_IFDIR | 0755); | ||
3965 | root = d_make_root(root_inode); | ||
3966 | - if (!root) | ||
3967 | + if (!root) { | ||
3968 | + ret = -ENOMEM; | ||
3969 | goto fail_ino; | ||
3970 | + } | ||
3971 | pipe = NULL; | ||
3972 | |||
3973 | root->d_fsdata = ino; | ||
3974 | diff --git a/fs/buffer.c b/fs/buffer.c | ||
3975 | index 6f1ae3ac9789..c083c4b3c1e7 100644 | ||
3976 | --- a/fs/buffer.c | ||
3977 | +++ b/fs/buffer.c | ||
3978 | @@ -200,6 +200,7 @@ __find_get_block_slow(struct block_device *bdev, sector_t block) | ||
3979 | struct buffer_head *head; | ||
3980 | struct page *page; | ||
3981 | int all_mapped = 1; | ||
3982 | + static DEFINE_RATELIMIT_STATE(last_warned, HZ, 1); | ||
3983 | |||
3984 | index = block >> (PAGE_SHIFT - bd_inode->i_blkbits); | ||
3985 | page = find_get_page_flags(bd_mapping, index, FGP_ACCESSED); | ||
3986 | @@ -227,15 +228,15 @@ __find_get_block_slow(struct block_device *bdev, sector_t block) | ||
3987 | * file io on the block device and getblk. It gets dealt with | ||
3988 | * elsewhere, don't buffer_error if we had some unmapped buffers | ||
3989 | */ | ||
3990 | - if (all_mapped) { | ||
3991 | - printk("__find_get_block_slow() failed. " | ||
3992 | - "block=%llu, b_blocknr=%llu\n", | ||
3993 | - (unsigned long long)block, | ||
3994 | - (unsigned long long)bh->b_blocknr); | ||
3995 | - printk("b_state=0x%08lx, b_size=%zu\n", | ||
3996 | - bh->b_state, bh->b_size); | ||
3997 | - printk("device %pg blocksize: %d\n", bdev, | ||
3998 | - 1 << bd_inode->i_blkbits); | ||
3999 | + ratelimit_set_flags(&last_warned, RATELIMIT_MSG_ON_RELEASE); | ||
4000 | + if (all_mapped && __ratelimit(&last_warned)) { | ||
4001 | + printk("__find_get_block_slow() failed. block=%llu, " | ||
4002 | + "b_blocknr=%llu, b_state=0x%08lx, b_size=%zu, " | ||
4003 | + "device %pg blocksize: %d\n", | ||
4004 | + (unsigned long long)block, | ||
4005 | + (unsigned long long)bh->b_blocknr, | ||
4006 | + bh->b_state, bh->b_size, bdev, | ||
4007 | + 1 << bd_inode->i_blkbits); | ||
4008 | } | ||
4009 | out_unlock: | ||
4010 | spin_unlock(&bd_mapping->private_lock); | ||
4011 | diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c | ||
4012 | index 1e5a1171212f..a2d701775c49 100644 | ||
4013 | --- a/fs/cifs/smb2pdu.c | ||
4014 | +++ b/fs/cifs/smb2pdu.c | ||
4015 | @@ -2243,10 +2243,12 @@ SMB2_open_free(struct smb_rqst *rqst) | ||
4016 | { | ||
4017 | int i; | ||
4018 | |||
4019 | - cifs_small_buf_release(rqst->rq_iov[0].iov_base); | ||
4020 | - for (i = 1; i < rqst->rq_nvec; i++) | ||
4021 | - if (rqst->rq_iov[i].iov_base != smb2_padding) | ||
4022 | - kfree(rqst->rq_iov[i].iov_base); | ||
4023 | + if (rqst && rqst->rq_iov) { | ||
4024 | + cifs_small_buf_release(rqst->rq_iov[0].iov_base); | ||
4025 | + for (i = 1; i < rqst->rq_nvec; i++) | ||
4026 | + if (rqst->rq_iov[i].iov_base != smb2_padding) | ||
4027 | + kfree(rqst->rq_iov[i].iov_base); | ||
4028 | + } | ||
4029 | } | ||
4030 | |||
4031 | int | ||
4032 | @@ -2535,7 +2537,8 @@ SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, | ||
4033 | void | ||
4034 | SMB2_close_free(struct smb_rqst *rqst) | ||
4035 | { | ||
4036 | - cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ | ||
4037 | + if (rqst && rqst->rq_iov) | ||
4038 | + cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ | ||
4039 | } | ||
4040 | |||
4041 | int | ||
4042 | @@ -2685,7 +2688,8 @@ SMB2_query_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, | ||
4043 | void | ||
4044 | SMB2_query_info_free(struct smb_rqst *rqst) | ||
4045 | { | ||
4046 | - cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ | ||
4047 | + if (rqst && rqst->rq_iov) | ||
4048 | + cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ | ||
4049 | } | ||
4050 | |||
4051 | static int | ||
4052 | diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h | ||
4053 | index 8fb7887f2b3d..437257d1116f 100644 | ||
4054 | --- a/fs/cifs/smb2pdu.h | ||
4055 | +++ b/fs/cifs/smb2pdu.h | ||
4056 | @@ -84,8 +84,8 @@ | ||
4057 | |||
4058 | #define NUMBER_OF_SMB2_COMMANDS 0x0013 | ||
4059 | |||
4060 | -/* 4 len + 52 transform hdr + 64 hdr + 56 create rsp */ | ||
4061 | -#define MAX_SMB2_HDR_SIZE 0x00b0 | ||
4062 | +/* 52 transform hdr + 64 hdr + 88 create rsp */ | ||
4063 | +#define MAX_SMB2_HDR_SIZE 204 | ||
4064 | |||
4065 | #define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe) | ||
4066 | #define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd) | ||
4067 | diff --git a/fs/drop_caches.c b/fs/drop_caches.c | ||
4068 | index 82377017130f..d31b6c72b476 100644 | ||
4069 | --- a/fs/drop_caches.c | ||
4070 | +++ b/fs/drop_caches.c | ||
4071 | @@ -21,8 +21,13 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused) | ||
4072 | spin_lock(&sb->s_inode_list_lock); | ||
4073 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { | ||
4074 | spin_lock(&inode->i_lock); | ||
4075 | + /* | ||
4076 | + * We must skip inodes in unusual state. We may also skip | ||
4077 | + * inodes without pages but we deliberately won't in case | ||
4078 | + * we need to reschedule to avoid softlockups. | ||
4079 | + */ | ||
4080 | if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) || | ||
4081 | - (inode->i_mapping->nrpages == 0)) { | ||
4082 | + (inode->i_mapping->nrpages == 0 && !need_resched())) { | ||
4083 | spin_unlock(&inode->i_lock); | ||
4084 | continue; | ||
4085 | } | ||
4086 | @@ -30,6 +35,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused) | ||
4087 | spin_unlock(&inode->i_lock); | ||
4088 | spin_unlock(&sb->s_inode_list_lock); | ||
4089 | |||
4090 | + cond_resched(); | ||
4091 | invalidate_mapping_pages(inode->i_mapping, 0, -1); | ||
4092 | iput(toput_inode); | ||
4093 | toput_inode = inode; | ||
4094 | diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c | ||
4095 | index 4614ee25f621..9d566e62684c 100644 | ||
4096 | --- a/fs/gfs2/glock.c | ||
4097 | +++ b/fs/gfs2/glock.c | ||
4098 | @@ -107,7 +107,7 @@ static int glock_wake_function(wait_queue_entry_t *wait, unsigned int mode, | ||
4099 | |||
4100 | static wait_queue_head_t *glock_waitqueue(struct lm_lockname *name) | ||
4101 | { | ||
4102 | - u32 hash = jhash2((u32 *)name, sizeof(*name) / 4, 0); | ||
4103 | + u32 hash = jhash2((u32 *)name, ht_parms.key_len / 4, 0); | ||
4104 | |||
4105 | return glock_wait_table + hash_32(hash, GLOCK_WAIT_TABLE_BITS); | ||
4106 | } | ||
4107 | diff --git a/fs/iomap.c b/fs/iomap.c | ||
4108 | index e57fb1e534c5..fac45206418a 100644 | ||
4109 | --- a/fs/iomap.c | ||
4110 | +++ b/fs/iomap.c | ||
4111 | @@ -117,6 +117,12 @@ iomap_page_create(struct inode *inode, struct page *page) | ||
4112 | atomic_set(&iop->read_count, 0); | ||
4113 | atomic_set(&iop->write_count, 0); | ||
4114 | bitmap_zero(iop->uptodate, PAGE_SIZE / SECTOR_SIZE); | ||
4115 | + | ||
4116 | + /* | ||
4117 | + * migrate_page_move_mapping() assumes that pages with private data have | ||
4118 | + * their count elevated by 1. | ||
4119 | + */ | ||
4120 | + get_page(page); | ||
4121 | set_page_private(page, (unsigned long)iop); | ||
4122 | SetPagePrivate(page); | ||
4123 | return iop; | ||
4124 | @@ -133,6 +139,7 @@ iomap_page_release(struct page *page) | ||
4125 | WARN_ON_ONCE(atomic_read(&iop->write_count)); | ||
4126 | ClearPagePrivate(page); | ||
4127 | set_page_private(page, 0); | ||
4128 | + put_page(page); | ||
4129 | kfree(iop); | ||
4130 | } | ||
4131 | |||
4132 | @@ -565,8 +572,10 @@ iomap_migrate_page(struct address_space *mapping, struct page *newpage, | ||
4133 | |||
4134 | if (page_has_private(page)) { | ||
4135 | ClearPagePrivate(page); | ||
4136 | + get_page(newpage); | ||
4137 | set_page_private(newpage, page_private(page)); | ||
4138 | set_page_private(page, 0); | ||
4139 | + put_page(page); | ||
4140 | SetPagePrivate(newpage); | ||
4141 | } | ||
4142 | |||
4143 | @@ -1778,6 +1787,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, | ||
4144 | loff_t pos = iocb->ki_pos, start = pos; | ||
4145 | loff_t end = iocb->ki_pos + count - 1, ret = 0; | ||
4146 | unsigned int flags = IOMAP_DIRECT; | ||
4147 | + bool wait_for_completion = is_sync_kiocb(iocb); | ||
4148 | struct blk_plug plug; | ||
4149 | struct iomap_dio *dio; | ||
4150 | |||
4151 | @@ -1797,7 +1807,6 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, | ||
4152 | dio->end_io = end_io; | ||
4153 | dio->error = 0; | ||
4154 | dio->flags = 0; | ||
4155 | - dio->wait_for_completion = is_sync_kiocb(iocb); | ||
4156 | |||
4157 | dio->submit.iter = iter; | ||
4158 | dio->submit.waiter = current; | ||
4159 | @@ -1852,7 +1861,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, | ||
4160 | dio_warn_stale_pagecache(iocb->ki_filp); | ||
4161 | ret = 0; | ||
4162 | |||
4163 | - if (iov_iter_rw(iter) == WRITE && !dio->wait_for_completion && | ||
4164 | + if (iov_iter_rw(iter) == WRITE && !wait_for_completion && | ||
4165 | !inode->i_sb->s_dio_done_wq) { | ||
4166 | ret = sb_init_dio_done_wq(inode->i_sb); | ||
4167 | if (ret < 0) | ||
4168 | @@ -1868,7 +1877,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, | ||
4169 | if (ret <= 0) { | ||
4170 | /* magic error code to fall back to buffered I/O */ | ||
4171 | if (ret == -ENOTBLK) { | ||
4172 | - dio->wait_for_completion = true; | ||
4173 | + wait_for_completion = true; | ||
4174 | ret = 0; | ||
4175 | } | ||
4176 | break; | ||
4177 | @@ -1890,8 +1899,24 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, | ||
4178 | if (dio->flags & IOMAP_DIO_WRITE_FUA) | ||
4179 | dio->flags &= ~IOMAP_DIO_NEED_SYNC; | ||
4180 | |||
4181 | + /* | ||
4182 | + * We are about to drop our additional submission reference, which | ||
4183 | + * might be the last reference to the dio. There are three three | ||
4184 | + * different ways we can progress here: | ||
4185 | + * | ||
4186 | + * (a) If this is the last reference we will always complete and free | ||
4187 | + * the dio ourselves. | ||
4188 | + * (b) If this is not the last reference, and we serve an asynchronous | ||
4189 | + * iocb, we must never touch the dio after the decrement, the | ||
4190 | + * I/O completion handler will complete and free it. | ||
4191 | + * (c) If this is not the last reference, but we serve a synchronous | ||
4192 | + * iocb, the I/O completion handler will wake us up on the drop | ||
4193 | + * of the final reference, and we will complete and free it here | ||
4194 | + * after we got woken by the I/O completion handler. | ||
4195 | + */ | ||
4196 | + dio->wait_for_completion = wait_for_completion; | ||
4197 | if (!atomic_dec_and_test(&dio->ref)) { | ||
4198 | - if (!dio->wait_for_completion) | ||
4199 | + if (!wait_for_completion) | ||
4200 | return -EIOCBQUEUED; | ||
4201 | |||
4202 | for (;;) { | ||
4203 | @@ -1908,9 +1933,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, | ||
4204 | __set_current_state(TASK_RUNNING); | ||
4205 | } | ||
4206 | |||
4207 | - ret = iomap_dio_complete(dio); | ||
4208 | - | ||
4209 | - return ret; | ||
4210 | + return iomap_dio_complete(dio); | ||
4211 | |||
4212 | out_free_dio: | ||
4213 | kfree(dio); | ||
4214 | diff --git a/fs/nfs/super.c b/fs/nfs/super.c | ||
4215 | index 5ef2c71348bd..6b666d187907 100644 | ||
4216 | --- a/fs/nfs/super.c | ||
4217 | +++ b/fs/nfs/super.c | ||
4218 | @@ -1906,6 +1906,11 @@ static int nfs_parse_devname(const char *dev_name, | ||
4219 | size_t len; | ||
4220 | char *end; | ||
4221 | |||
4222 | + if (unlikely(!dev_name || !*dev_name)) { | ||
4223 | + dfprintk(MOUNT, "NFS: device name not specified\n"); | ||
4224 | + return -EINVAL; | ||
4225 | + } | ||
4226 | + | ||
4227 | /* Is the host name protected with square brakcets? */ | ||
4228 | if (*dev_name == '[') { | ||
4229 | end = strchr(++dev_name, ']'); | ||
4230 | diff --git a/fs/proc/generic.c b/fs/proc/generic.c | ||
4231 | index 8ae109429a88..e39bac94dead 100644 | ||
4232 | --- a/fs/proc/generic.c | ||
4233 | +++ b/fs/proc/generic.c | ||
4234 | @@ -256,7 +256,7 @@ struct dentry *proc_lookup_de(struct inode *dir, struct dentry *dentry, | ||
4235 | inode = proc_get_inode(dir->i_sb, de); | ||
4236 | if (!inode) | ||
4237 | return ERR_PTR(-ENOMEM); | ||
4238 | - d_set_d_op(dentry, &proc_misc_dentry_ops); | ||
4239 | + d_set_d_op(dentry, de->proc_dops); | ||
4240 | return d_splice_alias(inode, dentry); | ||
4241 | } | ||
4242 | read_unlock(&proc_subdir_lock); | ||
4243 | @@ -429,6 +429,8 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent, | ||
4244 | INIT_LIST_HEAD(&ent->pde_openers); | ||
4245 | proc_set_user(ent, (*parent)->uid, (*parent)->gid); | ||
4246 | |||
4247 | + ent->proc_dops = &proc_misc_dentry_ops; | ||
4248 | + | ||
4249 | out: | ||
4250 | return ent; | ||
4251 | } | ||
4252 | diff --git a/fs/proc/internal.h b/fs/proc/internal.h | ||
4253 | index 5185d7f6a51e..95b14196f284 100644 | ||
4254 | --- a/fs/proc/internal.h | ||
4255 | +++ b/fs/proc/internal.h | ||
4256 | @@ -44,6 +44,7 @@ struct proc_dir_entry { | ||
4257 | struct completion *pde_unload_completion; | ||
4258 | const struct inode_operations *proc_iops; | ||
4259 | const struct file_operations *proc_fops; | ||
4260 | + const struct dentry_operations *proc_dops; | ||
4261 | union { | ||
4262 | const struct seq_operations *seq_ops; | ||
4263 | int (*single_show)(struct seq_file *, void *); | ||
4264 | diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c | ||
4265 | index d5e0fcb3439e..a7b12435519e 100644 | ||
4266 | --- a/fs/proc/proc_net.c | ||
4267 | +++ b/fs/proc/proc_net.c | ||
4268 | @@ -38,6 +38,22 @@ static struct net *get_proc_net(const struct inode *inode) | ||
4269 | return maybe_get_net(PDE_NET(PDE(inode))); | ||
4270 | } | ||
4271 | |||
4272 | +static int proc_net_d_revalidate(struct dentry *dentry, unsigned int flags) | ||
4273 | +{ | ||
4274 | + return 0; | ||
4275 | +} | ||
4276 | + | ||
4277 | +static const struct dentry_operations proc_net_dentry_ops = { | ||
4278 | + .d_revalidate = proc_net_d_revalidate, | ||
4279 | + .d_delete = always_delete_dentry, | ||
4280 | +}; | ||
4281 | + | ||
4282 | +static void pde_force_lookup(struct proc_dir_entry *pde) | ||
4283 | +{ | ||
4284 | + /* /proc/net/ entries can be changed under us by setns(CLONE_NEWNET) */ | ||
4285 | + pde->proc_dops = &proc_net_dentry_ops; | ||
4286 | +} | ||
4287 | + | ||
4288 | static int seq_open_net(struct inode *inode, struct file *file) | ||
4289 | { | ||
4290 | unsigned int state_size = PDE(inode)->state_size; | ||
4291 | @@ -90,6 +106,7 @@ struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode, | ||
4292 | p = proc_create_reg(name, mode, &parent, data); | ||
4293 | if (!p) | ||
4294 | return NULL; | ||
4295 | + pde_force_lookup(p); | ||
4296 | p->proc_fops = &proc_net_seq_fops; | ||
4297 | p->seq_ops = ops; | ||
4298 | p->state_size = state_size; | ||
4299 | @@ -133,6 +150,7 @@ struct proc_dir_entry *proc_create_net_data_write(const char *name, umode_t mode | ||
4300 | p = proc_create_reg(name, mode, &parent, data); | ||
4301 | if (!p) | ||
4302 | return NULL; | ||
4303 | + pde_force_lookup(p); | ||
4304 | p->proc_fops = &proc_net_seq_fops; | ||
4305 | p->seq_ops = ops; | ||
4306 | p->state_size = state_size; | ||
4307 | @@ -181,6 +199,7 @@ struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode, | ||
4308 | p = proc_create_reg(name, mode, &parent, data); | ||
4309 | if (!p) | ||
4310 | return NULL; | ||
4311 | + pde_force_lookup(p); | ||
4312 | p->proc_fops = &proc_net_single_fops; | ||
4313 | p->single_show = show; | ||
4314 | return proc_register(parent, p); | ||
4315 | @@ -223,6 +242,7 @@ struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mo | ||
4316 | p = proc_create_reg(name, mode, &parent, data); | ||
4317 | if (!p) | ||
4318 | return NULL; | ||
4319 | + pde_force_lookup(p); | ||
4320 | p->proc_fops = &proc_net_single_fops; | ||
4321 | p->single_show = show; | ||
4322 | p->write = write; | ||
4323 | diff --git a/include/drm/drm_cache.h b/include/drm/drm_cache.h | ||
4324 | index bfe1639df02d..97fc498dc767 100644 | ||
4325 | --- a/include/drm/drm_cache.h | ||
4326 | +++ b/include/drm/drm_cache.h | ||
4327 | @@ -47,6 +47,24 @@ static inline bool drm_arch_can_wc_memory(void) | ||
4328 | return false; | ||
4329 | #elif defined(CONFIG_MIPS) && defined(CONFIG_CPU_LOONGSON3) | ||
4330 | return false; | ||
4331 | +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64) | ||
4332 | + /* | ||
4333 | + * The DRM driver stack is designed to work with cache coherent devices | ||
4334 | + * only, but permits an optimization to be enabled in some cases, where | ||
4335 | + * for some buffers, both the CPU and the GPU use uncached mappings, | ||
4336 | + * removing the need for DMA snooping and allocation in the CPU caches. | ||
4337 | + * | ||
4338 | + * The use of uncached GPU mappings relies on the correct implementation | ||
4339 | + * of the PCIe NoSnoop TLP attribute by the platform, otherwise the GPU | ||
4340 | + * will use cached mappings nonetheless. On x86 platforms, this does not | ||
4341 | + * seem to matter, as uncached CPU mappings will snoop the caches in any | ||
4342 | + * case. However, on ARM and arm64, enabling this optimization on a | ||
4343 | + * platform where NoSnoop is ignored results in loss of coherency, which | ||
4344 | + * breaks correct operation of the device. Since we have no way of | ||
4345 | + * detecting whether NoSnoop works or not, just disable this | ||
4346 | + * optimization entirely for ARM and arm64. | ||
4347 | + */ | ||
4348 | + return false; | ||
4349 | #else | ||
4350 | return true; | ||
4351 | #endif | ||
4352 | diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h | ||
4353 | index 8bdbb5f29494..3188c0bef3e7 100644 | ||
4354 | --- a/include/linux/irqchip/arm-gic-v3.h | ||
4355 | +++ b/include/linux/irqchip/arm-gic-v3.h | ||
4356 | @@ -319,7 +319,7 @@ | ||
4357 | #define GITS_TYPER_PLPIS (1UL << 0) | ||
4358 | #define GITS_TYPER_VLPIS (1UL << 1) | ||
4359 | #define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4 | ||
4360 | -#define GITS_TYPER_ITT_ENTRY_SIZE(r) ((((r) >> GITS_TYPER_ITT_ENTRY_SIZE_SHIFT) & 0x1f) + 1) | ||
4361 | +#define GITS_TYPER_ITT_ENTRY_SIZE(r) ((((r) >> GITS_TYPER_ITT_ENTRY_SIZE_SHIFT) & 0xf) + 1) | ||
4362 | #define GITS_TYPER_IDBITS_SHIFT 8 | ||
4363 | #define GITS_TYPER_DEVBITS_SHIFT 13 | ||
4364 | #define GITS_TYPER_DEVBITS(r) ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) | ||
4365 | diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h | ||
4366 | index 7ddfc65586b0..4335bd771ce5 100644 | ||
4367 | --- a/include/linux/stmmac.h | ||
4368 | +++ b/include/linux/stmmac.h | ||
4369 | @@ -184,6 +184,7 @@ struct plat_stmmacenet_data { | ||
4370 | struct clk *pclk; | ||
4371 | struct clk *clk_ptp_ref; | ||
4372 | unsigned int clk_ptp_rate; | ||
4373 | + unsigned int clk_ref_rate; | ||
4374 | struct reset_control *stmmac_rst; | ||
4375 | struct stmmac_axi *axi; | ||
4376 | int has_gmac4; | ||
4377 | diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c | ||
4378 | index 03cc59ee9c95..cebadd6af4d9 100644 | ||
4379 | --- a/kernel/bpf/hashtab.c | ||
4380 | +++ b/kernel/bpf/hashtab.c | ||
4381 | @@ -677,7 +677,7 @@ static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l) | ||
4382 | } | ||
4383 | |||
4384 | if (htab_is_prealloc(htab)) { | ||
4385 | - pcpu_freelist_push(&htab->freelist, &l->fnode); | ||
4386 | + __pcpu_freelist_push(&htab->freelist, &l->fnode); | ||
4387 | } else { | ||
4388 | atomic_dec(&htab->count); | ||
4389 | l->htab = htab; | ||
4390 | @@ -739,7 +739,7 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, | ||
4391 | } else { | ||
4392 | struct pcpu_freelist_node *l; | ||
4393 | |||
4394 | - l = pcpu_freelist_pop(&htab->freelist); | ||
4395 | + l = __pcpu_freelist_pop(&htab->freelist); | ||
4396 | if (!l) | ||
4397 | return ERR_PTR(-E2BIG); | ||
4398 | l_new = container_of(l, struct htab_elem, fnode); | ||
4399 | diff --git a/kernel/bpf/percpu_freelist.c b/kernel/bpf/percpu_freelist.c | ||
4400 | index 673fa6fe2d73..0c1b4ba9e90e 100644 | ||
4401 | --- a/kernel/bpf/percpu_freelist.c | ||
4402 | +++ b/kernel/bpf/percpu_freelist.c | ||
4403 | @@ -28,8 +28,8 @@ void pcpu_freelist_destroy(struct pcpu_freelist *s) | ||
4404 | free_percpu(s->freelist); | ||
4405 | } | ||
4406 | |||
4407 | -static inline void __pcpu_freelist_push(struct pcpu_freelist_head *head, | ||
4408 | - struct pcpu_freelist_node *node) | ||
4409 | +static inline void ___pcpu_freelist_push(struct pcpu_freelist_head *head, | ||
4410 | + struct pcpu_freelist_node *node) | ||
4411 | { | ||
4412 | raw_spin_lock(&head->lock); | ||
4413 | node->next = head->first; | ||
4414 | @@ -37,12 +37,22 @@ static inline void __pcpu_freelist_push(struct pcpu_freelist_head *head, | ||
4415 | raw_spin_unlock(&head->lock); | ||
4416 | } | ||
4417 | |||
4418 | -void pcpu_freelist_push(struct pcpu_freelist *s, | ||
4419 | +void __pcpu_freelist_push(struct pcpu_freelist *s, | ||
4420 | struct pcpu_freelist_node *node) | ||
4421 | { | ||
4422 | struct pcpu_freelist_head *head = this_cpu_ptr(s->freelist); | ||
4423 | |||
4424 | - __pcpu_freelist_push(head, node); | ||
4425 | + ___pcpu_freelist_push(head, node); | ||
4426 | +} | ||
4427 | + | ||
4428 | +void pcpu_freelist_push(struct pcpu_freelist *s, | ||
4429 | + struct pcpu_freelist_node *node) | ||
4430 | +{ | ||
4431 | + unsigned long flags; | ||
4432 | + | ||
4433 | + local_irq_save(flags); | ||
4434 | + __pcpu_freelist_push(s, node); | ||
4435 | + local_irq_restore(flags); | ||
4436 | } | ||
4437 | |||
4438 | void pcpu_freelist_populate(struct pcpu_freelist *s, void *buf, u32 elem_size, | ||
4439 | @@ -63,7 +73,7 @@ void pcpu_freelist_populate(struct pcpu_freelist *s, void *buf, u32 elem_size, | ||
4440 | for_each_possible_cpu(cpu) { | ||
4441 | again: | ||
4442 | head = per_cpu_ptr(s->freelist, cpu); | ||
4443 | - __pcpu_freelist_push(head, buf); | ||
4444 | + ___pcpu_freelist_push(head, buf); | ||
4445 | i++; | ||
4446 | buf += elem_size; | ||
4447 | if (i == nr_elems) | ||
4448 | @@ -74,14 +84,12 @@ again: | ||
4449 | local_irq_restore(flags); | ||
4450 | } | ||
4451 | |||
4452 | -struct pcpu_freelist_node *pcpu_freelist_pop(struct pcpu_freelist *s) | ||
4453 | +struct pcpu_freelist_node *__pcpu_freelist_pop(struct pcpu_freelist *s) | ||
4454 | { | ||
4455 | struct pcpu_freelist_head *head; | ||
4456 | struct pcpu_freelist_node *node; | ||
4457 | - unsigned long flags; | ||
4458 | int orig_cpu, cpu; | ||
4459 | |||
4460 | - local_irq_save(flags); | ||
4461 | orig_cpu = cpu = raw_smp_processor_id(); | ||
4462 | while (1) { | ||
4463 | head = per_cpu_ptr(s->freelist, cpu); | ||
4464 | @@ -89,16 +97,25 @@ struct pcpu_freelist_node *pcpu_freelist_pop(struct pcpu_freelist *s) | ||
4465 | node = head->first; | ||
4466 | if (node) { | ||
4467 | head->first = node->next; | ||
4468 | - raw_spin_unlock_irqrestore(&head->lock, flags); | ||
4469 | + raw_spin_unlock(&head->lock); | ||
4470 | return node; | ||
4471 | } | ||
4472 | raw_spin_unlock(&head->lock); | ||
4473 | cpu = cpumask_next(cpu, cpu_possible_mask); | ||
4474 | if (cpu >= nr_cpu_ids) | ||
4475 | cpu = 0; | ||
4476 | - if (cpu == orig_cpu) { | ||
4477 | - local_irq_restore(flags); | ||
4478 | + if (cpu == orig_cpu) | ||
4479 | return NULL; | ||
4480 | - } | ||
4481 | } | ||
4482 | } | ||
4483 | + | ||
4484 | +struct pcpu_freelist_node *pcpu_freelist_pop(struct pcpu_freelist *s) | ||
4485 | +{ | ||
4486 | + struct pcpu_freelist_node *ret; | ||
4487 | + unsigned long flags; | ||
4488 | + | ||
4489 | + local_irq_save(flags); | ||
4490 | + ret = __pcpu_freelist_pop(s); | ||
4491 | + local_irq_restore(flags); | ||
4492 | + return ret; | ||
4493 | +} | ||
4494 | diff --git a/kernel/bpf/percpu_freelist.h b/kernel/bpf/percpu_freelist.h | ||
4495 | index 3049aae8ea1e..c3960118e617 100644 | ||
4496 | --- a/kernel/bpf/percpu_freelist.h | ||
4497 | +++ b/kernel/bpf/percpu_freelist.h | ||
4498 | @@ -22,8 +22,12 @@ struct pcpu_freelist_node { | ||
4499 | struct pcpu_freelist_node *next; | ||
4500 | }; | ||
4501 | |||
4502 | +/* pcpu_freelist_* do spin_lock_irqsave. */ | ||
4503 | void pcpu_freelist_push(struct pcpu_freelist *, struct pcpu_freelist_node *); | ||
4504 | struct pcpu_freelist_node *pcpu_freelist_pop(struct pcpu_freelist *); | ||
4505 | +/* __pcpu_freelist_* do spin_lock only. caller must disable irqs. */ | ||
4506 | +void __pcpu_freelist_push(struct pcpu_freelist *, struct pcpu_freelist_node *); | ||
4507 | +struct pcpu_freelist_node *__pcpu_freelist_pop(struct pcpu_freelist *); | ||
4508 | void pcpu_freelist_populate(struct pcpu_freelist *s, void *buf, u32 elem_size, | ||
4509 | u32 nr_elems); | ||
4510 | int pcpu_freelist_init(struct pcpu_freelist *); | ||
4511 | diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c | ||
4512 | index 382c09dddf93..cc40b8be1171 100644 | ||
4513 | --- a/kernel/bpf/syscall.c | ||
4514 | +++ b/kernel/bpf/syscall.c | ||
4515 | @@ -701,8 +701,13 @@ static int map_lookup_elem(union bpf_attr *attr) | ||
4516 | |||
4517 | if (bpf_map_is_dev_bound(map)) { | ||
4518 | err = bpf_map_offload_lookup_elem(map, key, value); | ||
4519 | - } else if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || | ||
4520 | - map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { | ||
4521 | + goto done; | ||
4522 | + } | ||
4523 | + | ||
4524 | + preempt_disable(); | ||
4525 | + this_cpu_inc(bpf_prog_active); | ||
4526 | + if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || | ||
4527 | + map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { | ||
4528 | err = bpf_percpu_hash_copy(map, key, value); | ||
4529 | } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) { | ||
4530 | err = bpf_percpu_array_copy(map, key, value); | ||
4531 | @@ -722,7 +727,10 @@ static int map_lookup_elem(union bpf_attr *attr) | ||
4532 | rcu_read_unlock(); | ||
4533 | err = ptr ? 0 : -ENOENT; | ||
4534 | } | ||
4535 | + this_cpu_dec(bpf_prog_active); | ||
4536 | + preempt_enable(); | ||
4537 | |||
4538 | +done: | ||
4539 | if (err) | ||
4540 | goto free_value; | ||
4541 | |||
4542 | diff --git a/kernel/events/core.c b/kernel/events/core.c | ||
4543 | index 4fb9d5054618..aa996a0854b9 100644 | ||
4544 | --- a/kernel/events/core.c | ||
4545 | +++ b/kernel/events/core.c | ||
4546 | @@ -436,18 +436,18 @@ int perf_proc_update_handler(struct ctl_table *table, int write, | ||
4547 | void __user *buffer, size_t *lenp, | ||
4548 | loff_t *ppos) | ||
4549 | { | ||
4550 | - int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); | ||
4551 | - | ||
4552 | - if (ret || !write) | ||
4553 | - return ret; | ||
4554 | - | ||
4555 | + int ret; | ||
4556 | + int perf_cpu = sysctl_perf_cpu_time_max_percent; | ||
4557 | /* | ||
4558 | * If throttling is disabled don't allow the write: | ||
4559 | */ | ||
4560 | - if (sysctl_perf_cpu_time_max_percent == 100 || | ||
4561 | - sysctl_perf_cpu_time_max_percent == 0) | ||
4562 | + if (write && (perf_cpu == 100 || perf_cpu == 0)) | ||
4563 | return -EINVAL; | ||
4564 | |||
4565 | + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); | ||
4566 | + if (ret || !write) | ||
4567 | + return ret; | ||
4568 | + | ||
4569 | max_samples_per_tick = DIV_ROUND_UP(sysctl_perf_event_sample_rate, HZ); | ||
4570 | perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate; | ||
4571 | update_perf_cpu_limits(); | ||
4572 | diff --git a/kernel/relay.c b/kernel/relay.c | ||
4573 | index 04f248644e06..9e0f52375487 100644 | ||
4574 | --- a/kernel/relay.c | ||
4575 | +++ b/kernel/relay.c | ||
4576 | @@ -428,6 +428,8 @@ static struct dentry *relay_create_buf_file(struct rchan *chan, | ||
4577 | dentry = chan->cb->create_buf_file(tmpname, chan->parent, | ||
4578 | S_IRUSR, buf, | ||
4579 | &chan->is_global); | ||
4580 | + if (IS_ERR(dentry)) | ||
4581 | + dentry = NULL; | ||
4582 | |||
4583 | kfree(tmpname); | ||
4584 | |||
4585 | @@ -461,7 +463,7 @@ static struct rchan_buf *relay_open_buf(struct rchan *chan, unsigned int cpu) | ||
4586 | dentry = chan->cb->create_buf_file(NULL, NULL, | ||
4587 | S_IRUSR, buf, | ||
4588 | &chan->is_global); | ||
4589 | - if (WARN_ON(dentry)) | ||
4590 | + if (IS_ERR_OR_NULL(dentry)) | ||
4591 | goto free_buf; | ||
4592 | } | ||
4593 | |||
4594 | diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c | ||
4595 | index 9864a35c8bb5..6c28d519447d 100644 | ||
4596 | --- a/kernel/trace/bpf_trace.c | ||
4597 | +++ b/kernel/trace/bpf_trace.c | ||
4598 | @@ -1158,22 +1158,12 @@ static int __bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog * | ||
4599 | |||
4600 | int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *prog) | ||
4601 | { | ||
4602 | - int err; | ||
4603 | - | ||
4604 | - mutex_lock(&bpf_event_mutex); | ||
4605 | - err = __bpf_probe_register(btp, prog); | ||
4606 | - mutex_unlock(&bpf_event_mutex); | ||
4607 | - return err; | ||
4608 | + return __bpf_probe_register(btp, prog); | ||
4609 | } | ||
4610 | |||
4611 | int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *prog) | ||
4612 | { | ||
4613 | - int err; | ||
4614 | - | ||
4615 | - mutex_lock(&bpf_event_mutex); | ||
4616 | - err = tracepoint_probe_unregister(btp->tp, (void *)btp->bpf_func, prog); | ||
4617 | - mutex_unlock(&bpf_event_mutex); | ||
4618 | - return err; | ||
4619 | + return tracepoint_probe_unregister(btp->tp, (void *)btp->bpf_func, prog); | ||
4620 | } | ||
4621 | |||
4622 | int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id, | ||
4623 | diff --git a/lib/test_kmod.c b/lib/test_kmod.c | ||
4624 | index d82d022111e0..9cf77628fc91 100644 | ||
4625 | --- a/lib/test_kmod.c | ||
4626 | +++ b/lib/test_kmod.c | ||
4627 | @@ -632,7 +632,7 @@ static void __kmod_config_free(struct test_config *config) | ||
4628 | config->test_driver = NULL; | ||
4629 | |||
4630 | kfree_const(config->test_fs); | ||
4631 | - config->test_driver = NULL; | ||
4632 | + config->test_fs = NULL; | ||
4633 | } | ||
4634 | |||
4635 | static void kmod_config_free(struct kmod_test_device *test_dev) | ||
4636 | diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c | ||
4637 | index c6119ad3561e..156991edec2a 100644 | ||
4638 | --- a/mm/memory_hotplug.c | ||
4639 | +++ b/mm/memory_hotplug.c | ||
4640 | @@ -1213,11 +1213,13 @@ static inline int pageblock_free(struct page *page) | ||
4641 | return PageBuddy(page) && page_order(page) >= pageblock_order; | ||
4642 | } | ||
4643 | |||
4644 | -/* Return the start of the next active pageblock after a given page */ | ||
4645 | -static struct page *next_active_pageblock(struct page *page) | ||
4646 | +/* Return the pfn of the start of the next active pageblock after a given pfn */ | ||
4647 | +static unsigned long next_active_pageblock(unsigned long pfn) | ||
4648 | { | ||
4649 | + struct page *page = pfn_to_page(pfn); | ||
4650 | + | ||
4651 | /* Ensure the starting page is pageblock-aligned */ | ||
4652 | - BUG_ON(page_to_pfn(page) & (pageblock_nr_pages - 1)); | ||
4653 | + BUG_ON(pfn & (pageblock_nr_pages - 1)); | ||
4654 | |||
4655 | /* If the entire pageblock is free, move to the end of free page */ | ||
4656 | if (pageblock_free(page)) { | ||
4657 | @@ -1225,16 +1227,16 @@ static struct page *next_active_pageblock(struct page *page) | ||
4658 | /* be careful. we don't have locks, page_order can be changed.*/ | ||
4659 | order = page_order(page); | ||
4660 | if ((order < MAX_ORDER) && (order >= pageblock_order)) | ||
4661 | - return page + (1 << order); | ||
4662 | + return pfn + (1 << order); | ||
4663 | } | ||
4664 | |||
4665 | - return page + pageblock_nr_pages; | ||
4666 | + return pfn + pageblock_nr_pages; | ||
4667 | } | ||
4668 | |||
4669 | -static bool is_pageblock_removable_nolock(struct page *page) | ||
4670 | +static bool is_pageblock_removable_nolock(unsigned long pfn) | ||
4671 | { | ||
4672 | + struct page *page = pfn_to_page(pfn); | ||
4673 | struct zone *zone; | ||
4674 | - unsigned long pfn; | ||
4675 | |||
4676 | /* | ||
4677 | * We have to be careful here because we are iterating over memory | ||
4678 | @@ -1257,12 +1259,14 @@ static bool is_pageblock_removable_nolock(struct page *page) | ||
4679 | /* Checks if this range of memory is likely to be hot-removable. */ | ||
4680 | bool is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages) | ||
4681 | { | ||
4682 | - struct page *page = pfn_to_page(start_pfn); | ||
4683 | - struct page *end_page = page + nr_pages; | ||
4684 | + unsigned long end_pfn, pfn; | ||
4685 | + | ||
4686 | + end_pfn = min(start_pfn + nr_pages, | ||
4687 | + zone_end_pfn(page_zone(pfn_to_page(start_pfn)))); | ||
4688 | |||
4689 | /* Check the starting page of each pageblock within the range */ | ||
4690 | - for (; page < end_page; page = next_active_pageblock(page)) { | ||
4691 | - if (!is_pageblock_removable_nolock(page)) | ||
4692 | + for (pfn = start_pfn; pfn < end_pfn; pfn = next_active_pageblock(pfn)) { | ||
4693 | + if (!is_pageblock_removable_nolock(pfn)) | ||
4694 | return false; | ||
4695 | cond_resched(); | ||
4696 | } | ||
4697 | @@ -1298,6 +1302,9 @@ int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn, | ||
4698 | i++; | ||
4699 | if (i == MAX_ORDER_NR_PAGES || pfn + i >= end_pfn) | ||
4700 | continue; | ||
4701 | + /* Check if we got outside of the zone */ | ||
4702 | + if (zone && !zone_spans_pfn(zone, pfn + i)) | ||
4703 | + return 0; | ||
4704 | page = pfn_to_page(pfn + i); | ||
4705 | if (zone && page_zone(page) != zone) | ||
4706 | return 0; | ||
4707 | diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c | ||
4708 | index e8090f099eb8..ef0dec20c7d8 100644 | ||
4709 | --- a/net/batman-adv/bat_v_elp.c | ||
4710 | +++ b/net/batman-adv/bat_v_elp.c | ||
4711 | @@ -104,6 +104,9 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) | ||
4712 | |||
4713 | ret = cfg80211_get_station(real_netdev, neigh->addr, &sinfo); | ||
4714 | |||
4715 | + /* free the TID stats immediately */ | ||
4716 | + cfg80211_sinfo_release_content(&sinfo); | ||
4717 | + | ||
4718 | dev_put(real_netdev); | ||
4719 | if (ret == -ENOENT) { | ||
4720 | /* Node is not associated anymore! It would be | ||
4721 | diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c | ||
4722 | index 5e55cef0cec3..6693e209efe8 100644 | ||
4723 | --- a/net/bridge/netfilter/ebtables.c | ||
4724 | +++ b/net/bridge/netfilter/ebtables.c | ||
4725 | @@ -2293,9 +2293,12 @@ static int compat_do_replace(struct net *net, void __user *user, | ||
4726 | |||
4727 | xt_compat_lock(NFPROTO_BRIDGE); | ||
4728 | |||
4729 | - ret = xt_compat_init_offsets(NFPROTO_BRIDGE, tmp.nentries); | ||
4730 | - if (ret < 0) | ||
4731 | - goto out_unlock; | ||
4732 | + if (tmp.nentries) { | ||
4733 | + ret = xt_compat_init_offsets(NFPROTO_BRIDGE, tmp.nentries); | ||
4734 | + if (ret < 0) | ||
4735 | + goto out_unlock; | ||
4736 | + } | ||
4737 | + | ||
4738 | ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state); | ||
4739 | if (ret < 0) | ||
4740 | goto out_unlock; | ||
4741 | diff --git a/net/core/filter.c b/net/core/filter.c | ||
4742 | index fb0080e84bd4..bed9061102f4 100644 | ||
4743 | --- a/net/core/filter.c | ||
4744 | +++ b/net/core/filter.c | ||
4745 | @@ -3909,10 +3909,12 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock, | ||
4746 | /* Only some socketops are supported */ | ||
4747 | switch (optname) { | ||
4748 | case SO_RCVBUF: | ||
4749 | + val = min_t(u32, val, sysctl_rmem_max); | ||
4750 | sk->sk_userlocks |= SOCK_RCVBUF_LOCK; | ||
4751 | sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF); | ||
4752 | break; | ||
4753 | case SO_SNDBUF: | ||
4754 | + val = min_t(u32, val, sysctl_wmem_max); | ||
4755 | sk->sk_userlocks |= SOCK_SNDBUF_LOCK; | ||
4756 | sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF); | ||
4757 | break; | ||
4758 | diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c | ||
4759 | index 7f56944b020f..40a7cd56e008 100644 | ||
4760 | --- a/net/ipv4/ip_vti.c | ||
4761 | +++ b/net/ipv4/ip_vti.c | ||
4762 | @@ -74,6 +74,33 @@ drop: | ||
4763 | return 0; | ||
4764 | } | ||
4765 | |||
4766 | +static int vti_input_ipip(struct sk_buff *skb, int nexthdr, __be32 spi, | ||
4767 | + int encap_type) | ||
4768 | +{ | ||
4769 | + struct ip_tunnel *tunnel; | ||
4770 | + const struct iphdr *iph = ip_hdr(skb); | ||
4771 | + struct net *net = dev_net(skb->dev); | ||
4772 | + struct ip_tunnel_net *itn = net_generic(net, vti_net_id); | ||
4773 | + | ||
4774 | + tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, | ||
4775 | + iph->saddr, iph->daddr, 0); | ||
4776 | + if (tunnel) { | ||
4777 | + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) | ||
4778 | + goto drop; | ||
4779 | + | ||
4780 | + XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel; | ||
4781 | + | ||
4782 | + skb->dev = tunnel->dev; | ||
4783 | + | ||
4784 | + return xfrm_input(skb, nexthdr, spi, encap_type); | ||
4785 | + } | ||
4786 | + | ||
4787 | + return -EINVAL; | ||
4788 | +drop: | ||
4789 | + kfree_skb(skb); | ||
4790 | + return 0; | ||
4791 | +} | ||
4792 | + | ||
4793 | static int vti_rcv(struct sk_buff *skb) | ||
4794 | { | ||
4795 | XFRM_SPI_SKB_CB(skb)->family = AF_INET; | ||
4796 | @@ -82,6 +109,14 @@ static int vti_rcv(struct sk_buff *skb) | ||
4797 | return vti_input(skb, ip_hdr(skb)->protocol, 0, 0); | ||
4798 | } | ||
4799 | |||
4800 | +static int vti_rcv_ipip(struct sk_buff *skb) | ||
4801 | +{ | ||
4802 | + XFRM_SPI_SKB_CB(skb)->family = AF_INET; | ||
4803 | + XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr); | ||
4804 | + | ||
4805 | + return vti_input_ipip(skb, ip_hdr(skb)->protocol, ip_hdr(skb)->saddr, 0); | ||
4806 | +} | ||
4807 | + | ||
4808 | static int vti_rcv_cb(struct sk_buff *skb, int err) | ||
4809 | { | ||
4810 | unsigned short family; | ||
4811 | @@ -435,6 +470,12 @@ static struct xfrm4_protocol vti_ipcomp4_protocol __read_mostly = { | ||
4812 | .priority = 100, | ||
4813 | }; | ||
4814 | |||
4815 | +static struct xfrm_tunnel ipip_handler __read_mostly = { | ||
4816 | + .handler = vti_rcv_ipip, | ||
4817 | + .err_handler = vti4_err, | ||
4818 | + .priority = 0, | ||
4819 | +}; | ||
4820 | + | ||
4821 | static int __net_init vti_init_net(struct net *net) | ||
4822 | { | ||
4823 | int err; | ||
4824 | @@ -603,6 +644,13 @@ static int __init vti_init(void) | ||
4825 | if (err < 0) | ||
4826 | goto xfrm_proto_comp_failed; | ||
4827 | |||
4828 | + msg = "ipip tunnel"; | ||
4829 | + err = xfrm4_tunnel_register(&ipip_handler, AF_INET); | ||
4830 | + if (err < 0) { | ||
4831 | + pr_info("%s: cant't register tunnel\n",__func__); | ||
4832 | + goto xfrm_tunnel_failed; | ||
4833 | + } | ||
4834 | + | ||
4835 | msg = "netlink interface"; | ||
4836 | err = rtnl_link_register(&vti_link_ops); | ||
4837 | if (err < 0) | ||
4838 | @@ -612,6 +660,8 @@ static int __init vti_init(void) | ||
4839 | |||
4840 | rtnl_link_failed: | ||
4841 | xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP); | ||
4842 | +xfrm_tunnel_failed: | ||
4843 | + xfrm4_tunnel_deregister(&ipip_handler, AF_INET); | ||
4844 | xfrm_proto_comp_failed: | ||
4845 | xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH); | ||
4846 | xfrm_proto_ah_failed: | ||
4847 | diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c | ||
4848 | index 518364f4abcc..55a77314340a 100644 | ||
4849 | --- a/net/netfilter/ipvs/ip_vs_ctl.c | ||
4850 | +++ b/net/netfilter/ipvs/ip_vs_ctl.c | ||
4851 | @@ -2220,6 +2220,18 @@ static int ip_vs_set_timeout(struct netns_ipvs *ipvs, struct ip_vs_timeout_user | ||
4852 | u->tcp_fin_timeout, | ||
4853 | u->udp_timeout); | ||
4854 | |||
4855 | +#ifdef CONFIG_IP_VS_PROTO_TCP | ||
4856 | + if (u->tcp_timeout < 0 || u->tcp_timeout > (INT_MAX / HZ) || | ||
4857 | + u->tcp_fin_timeout < 0 || u->tcp_fin_timeout > (INT_MAX / HZ)) { | ||
4858 | + return -EINVAL; | ||
4859 | + } | ||
4860 | +#endif | ||
4861 | + | ||
4862 | +#ifdef CONFIG_IP_VS_PROTO_UDP | ||
4863 | + if (u->udp_timeout < 0 || u->udp_timeout > (INT_MAX / HZ)) | ||
4864 | + return -EINVAL; | ||
4865 | +#endif | ||
4866 | + | ||
4867 | #ifdef CONFIG_IP_VS_PROTO_TCP | ||
4868 | if (u->tcp_timeout) { | ||
4869 | pd = ip_vs_proto_data_get(ipvs, IPPROTO_TCP); | ||
4870 | diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c | ||
4871 | index 277d02a8cac8..895171a2e1f1 100644 | ||
4872 | --- a/net/netfilter/nf_conntrack_core.c | ||
4873 | +++ b/net/netfilter/nf_conntrack_core.c | ||
4874 | @@ -1007,6 +1007,22 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, | ||
4875 | } | ||
4876 | |||
4877 | if (nf_ct_key_equal(h, tuple, zone, net)) { | ||
4878 | + /* Tuple is taken already, so caller will need to find | ||
4879 | + * a new source port to use. | ||
4880 | + * | ||
4881 | + * Only exception: | ||
4882 | + * If the *original tuples* are identical, then both | ||
4883 | + * conntracks refer to the same flow. | ||
4884 | + * This is a rare situation, it can occur e.g. when | ||
4885 | + * more than one UDP packet is sent from same socket | ||
4886 | + * in different threads. | ||
4887 | + * | ||
4888 | + * Let nf_ct_resolve_clash() deal with this later. | ||
4889 | + */ | ||
4890 | + if (nf_ct_tuple_equal(&ignored_conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple, | ||
4891 | + &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple)) | ||
4892 | + continue; | ||
4893 | + | ||
4894 | NF_CT_STAT_INC_ATOMIC(net, found); | ||
4895 | rcu_read_unlock(); | ||
4896 | return 1; | ||
4897 | diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c | ||
4898 | index 0d0d68c989df..1dae02a97ee3 100644 | ||
4899 | --- a/net/netfilter/xt_TEE.c | ||
4900 | +++ b/net/netfilter/xt_TEE.c | ||
4901 | @@ -14,6 +14,8 @@ | ||
4902 | #include <linux/skbuff.h> | ||
4903 | #include <linux/route.h> | ||
4904 | #include <linux/netfilter/x_tables.h> | ||
4905 | +#include <net/net_namespace.h> | ||
4906 | +#include <net/netns/generic.h> | ||
4907 | #include <net/route.h> | ||
4908 | #include <net/netfilter/ipv4/nf_dup_ipv4.h> | ||
4909 | #include <net/netfilter/ipv6/nf_dup_ipv6.h> | ||
4910 | @@ -25,8 +27,15 @@ struct xt_tee_priv { | ||
4911 | int oif; | ||
4912 | }; | ||
4913 | |||
4914 | +static unsigned int tee_net_id __read_mostly; | ||
4915 | static const union nf_inet_addr tee_zero_address; | ||
4916 | |||
4917 | +struct tee_net { | ||
4918 | + struct list_head priv_list; | ||
4919 | + /* lock protects the priv_list */ | ||
4920 | + struct mutex lock; | ||
4921 | +}; | ||
4922 | + | ||
4923 | static unsigned int | ||
4924 | tee_tg4(struct sk_buff *skb, const struct xt_action_param *par) | ||
4925 | { | ||
4926 | @@ -51,17 +60,16 @@ tee_tg6(struct sk_buff *skb, const struct xt_action_param *par) | ||
4927 | } | ||
4928 | #endif | ||
4929 | |||
4930 | -static DEFINE_MUTEX(priv_list_mutex); | ||
4931 | -static LIST_HEAD(priv_list); | ||
4932 | - | ||
4933 | static int tee_netdev_event(struct notifier_block *this, unsigned long event, | ||
4934 | void *ptr) | ||
4935 | { | ||
4936 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | ||
4937 | + struct net *net = dev_net(dev); | ||
4938 | + struct tee_net *tn = net_generic(net, tee_net_id); | ||
4939 | struct xt_tee_priv *priv; | ||
4940 | |||
4941 | - mutex_lock(&priv_list_mutex); | ||
4942 | - list_for_each_entry(priv, &priv_list, list) { | ||
4943 | + mutex_lock(&tn->lock); | ||
4944 | + list_for_each_entry(priv, &tn->priv_list, list) { | ||
4945 | switch (event) { | ||
4946 | case NETDEV_REGISTER: | ||
4947 | if (!strcmp(dev->name, priv->tginfo->oif)) | ||
4948 | @@ -79,13 +87,14 @@ static int tee_netdev_event(struct notifier_block *this, unsigned long event, | ||
4949 | break; | ||
4950 | } | ||
4951 | } | ||
4952 | - mutex_unlock(&priv_list_mutex); | ||
4953 | + mutex_unlock(&tn->lock); | ||
4954 | |||
4955 | return NOTIFY_DONE; | ||
4956 | } | ||
4957 | |||
4958 | static int tee_tg_check(const struct xt_tgchk_param *par) | ||
4959 | { | ||
4960 | + struct tee_net *tn = net_generic(par->net, tee_net_id); | ||
4961 | struct xt_tee_tginfo *info = par->targinfo; | ||
4962 | struct xt_tee_priv *priv; | ||
4963 | |||
4964 | @@ -95,6 +104,8 @@ static int tee_tg_check(const struct xt_tgchk_param *par) | ||
4965 | return -EINVAL; | ||
4966 | |||
4967 | if (info->oif[0]) { | ||
4968 | + struct net_device *dev; | ||
4969 | + | ||
4970 | if (info->oif[sizeof(info->oif)-1] != '\0') | ||
4971 | return -EINVAL; | ||
4972 | |||
4973 | @@ -106,9 +117,14 @@ static int tee_tg_check(const struct xt_tgchk_param *par) | ||
4974 | priv->oif = -1; | ||
4975 | info->priv = priv; | ||
4976 | |||
4977 | - mutex_lock(&priv_list_mutex); | ||
4978 | - list_add(&priv->list, &priv_list); | ||
4979 | - mutex_unlock(&priv_list_mutex); | ||
4980 | + dev = dev_get_by_name(par->net, info->oif); | ||
4981 | + if (dev) { | ||
4982 | + priv->oif = dev->ifindex; | ||
4983 | + dev_put(dev); | ||
4984 | + } | ||
4985 | + mutex_lock(&tn->lock); | ||
4986 | + list_add(&priv->list, &tn->priv_list); | ||
4987 | + mutex_unlock(&tn->lock); | ||
4988 | } else | ||
4989 | info->priv = NULL; | ||
4990 | |||
4991 | @@ -118,12 +134,13 @@ static int tee_tg_check(const struct xt_tgchk_param *par) | ||
4992 | |||
4993 | static void tee_tg_destroy(const struct xt_tgdtor_param *par) | ||
4994 | { | ||
4995 | + struct tee_net *tn = net_generic(par->net, tee_net_id); | ||
4996 | struct xt_tee_tginfo *info = par->targinfo; | ||
4997 | |||
4998 | if (info->priv) { | ||
4999 | - mutex_lock(&priv_list_mutex); | ||
5000 | + mutex_lock(&tn->lock); | ||
5001 | list_del(&info->priv->list); | ||
5002 | - mutex_unlock(&priv_list_mutex); | ||
5003 | + mutex_unlock(&tn->lock); | ||
5004 | kfree(info->priv); | ||
5005 | } | ||
5006 | static_key_slow_dec(&xt_tee_enabled); | ||
5007 | @@ -156,6 +173,21 @@ static struct xt_target tee_tg_reg[] __read_mostly = { | ||
5008 | #endif | ||
5009 | }; | ||
5010 | |||
5011 | +static int __net_init tee_net_init(struct net *net) | ||
5012 | +{ | ||
5013 | + struct tee_net *tn = net_generic(net, tee_net_id); | ||
5014 | + | ||
5015 | + INIT_LIST_HEAD(&tn->priv_list); | ||
5016 | + mutex_init(&tn->lock); | ||
5017 | + return 0; | ||
5018 | +} | ||
5019 | + | ||
5020 | +static struct pernet_operations tee_net_ops = { | ||
5021 | + .init = tee_net_init, | ||
5022 | + .id = &tee_net_id, | ||
5023 | + .size = sizeof(struct tee_net), | ||
5024 | +}; | ||
5025 | + | ||
5026 | static struct notifier_block tee_netdev_notifier = { | ||
5027 | .notifier_call = tee_netdev_event, | ||
5028 | }; | ||
5029 | @@ -164,22 +196,32 @@ static int __init tee_tg_init(void) | ||
5030 | { | ||
5031 | int ret; | ||
5032 | |||
5033 | - ret = xt_register_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg)); | ||
5034 | - if (ret) | ||
5035 | + ret = register_pernet_subsys(&tee_net_ops); | ||
5036 | + if (ret < 0) | ||
5037 | return ret; | ||
5038 | + | ||
5039 | + ret = xt_register_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg)); | ||
5040 | + if (ret < 0) | ||
5041 | + goto cleanup_subsys; | ||
5042 | + | ||
5043 | ret = register_netdevice_notifier(&tee_netdev_notifier); | ||
5044 | - if (ret) { | ||
5045 | - xt_unregister_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg)); | ||
5046 | - return ret; | ||
5047 | - } | ||
5048 | + if (ret < 0) | ||
5049 | + goto unregister_targets; | ||
5050 | |||
5051 | return 0; | ||
5052 | + | ||
5053 | +unregister_targets: | ||
5054 | + xt_unregister_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg)); | ||
5055 | +cleanup_subsys: | ||
5056 | + unregister_pernet_subsys(&tee_net_ops); | ||
5057 | + return ret; | ||
5058 | } | ||
5059 | |||
5060 | static void __exit tee_tg_exit(void) | ||
5061 | { | ||
5062 | unregister_netdevice_notifier(&tee_netdev_notifier); | ||
5063 | xt_unregister_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg)); | ||
5064 | + unregister_pernet_subsys(&tee_net_ops); | ||
5065 | } | ||
5066 | |||
5067 | module_init(tee_tg_init); | ||
5068 | diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c | ||
5069 | index 5d3cce9e8744..15eb5d3d4750 100644 | ||
5070 | --- a/net/vmw_vsock/virtio_transport.c | ||
5071 | +++ b/net/vmw_vsock/virtio_transport.c | ||
5072 | @@ -75,6 +75,9 @@ static u32 virtio_transport_get_local_cid(void) | ||
5073 | { | ||
5074 | struct virtio_vsock *vsock = virtio_vsock_get(); | ||
5075 | |||
5076 | + if (!vsock) | ||
5077 | + return VMADDR_CID_ANY; | ||
5078 | + | ||
5079 | return vsock->guest_cid; | ||
5080 | } | ||
5081 | |||
5082 | @@ -584,10 +587,6 @@ static int virtio_vsock_probe(struct virtio_device *vdev) | ||
5083 | |||
5084 | virtio_vsock_update_guest_cid(vsock); | ||
5085 | |||
5086 | - ret = vsock_core_init(&virtio_transport.transport); | ||
5087 | - if (ret < 0) | ||
5088 | - goto out_vqs; | ||
5089 | - | ||
5090 | vsock->rx_buf_nr = 0; | ||
5091 | vsock->rx_buf_max_nr = 0; | ||
5092 | atomic_set(&vsock->queued_replies, 0); | ||
5093 | @@ -618,8 +617,6 @@ static int virtio_vsock_probe(struct virtio_device *vdev) | ||
5094 | mutex_unlock(&the_virtio_vsock_mutex); | ||
5095 | return 0; | ||
5096 | |||
5097 | -out_vqs: | ||
5098 | - vsock->vdev->config->del_vqs(vsock->vdev); | ||
5099 | out: | ||
5100 | kfree(vsock); | ||
5101 | mutex_unlock(&the_virtio_vsock_mutex); | ||
5102 | @@ -637,6 +634,9 @@ static void virtio_vsock_remove(struct virtio_device *vdev) | ||
5103 | flush_work(&vsock->event_work); | ||
5104 | flush_work(&vsock->send_pkt_work); | ||
5105 | |||
5106 | + /* Reset all connected sockets when the device disappear */ | ||
5107 | + vsock_for_each_connected_socket(virtio_vsock_reset_sock); | ||
5108 | + | ||
5109 | vdev->config->reset(vdev); | ||
5110 | |||
5111 | mutex_lock(&vsock->rx_lock); | ||
5112 | @@ -669,7 +669,6 @@ static void virtio_vsock_remove(struct virtio_device *vdev) | ||
5113 | |||
5114 | mutex_lock(&the_virtio_vsock_mutex); | ||
5115 | the_virtio_vsock = NULL; | ||
5116 | - vsock_core_exit(); | ||
5117 | mutex_unlock(&the_virtio_vsock_mutex); | ||
5118 | |||
5119 | vdev->config->del_vqs(vdev); | ||
5120 | @@ -702,14 +701,28 @@ static int __init virtio_vsock_init(void) | ||
5121 | virtio_vsock_workqueue = alloc_workqueue("virtio_vsock", 0, 0); | ||
5122 | if (!virtio_vsock_workqueue) | ||
5123 | return -ENOMEM; | ||
5124 | + | ||
5125 | ret = register_virtio_driver(&virtio_vsock_driver); | ||
5126 | if (ret) | ||
5127 | - destroy_workqueue(virtio_vsock_workqueue); | ||
5128 | + goto out_wq; | ||
5129 | + | ||
5130 | + ret = vsock_core_init(&virtio_transport.transport); | ||
5131 | + if (ret) | ||
5132 | + goto out_vdr; | ||
5133 | + | ||
5134 | + return 0; | ||
5135 | + | ||
5136 | +out_vdr: | ||
5137 | + unregister_virtio_driver(&virtio_vsock_driver); | ||
5138 | +out_wq: | ||
5139 | + destroy_workqueue(virtio_vsock_workqueue); | ||
5140 | return ret; | ||
5141 | + | ||
5142 | } | ||
5143 | |||
5144 | static void __exit virtio_vsock_exit(void) | ||
5145 | { | ||
5146 | + vsock_core_exit(); | ||
5147 | unregister_virtio_driver(&virtio_vsock_driver); | ||
5148 | destroy_workqueue(virtio_vsock_workqueue); | ||
5149 | } | ||
5150 | diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c | ||
5151 | index 08c88de0ffda..11975ec8d566 100644 | ||
5152 | --- a/security/apparmor/domain.c | ||
5153 | +++ b/security/apparmor/domain.c | ||
5154 | @@ -1444,7 +1444,10 @@ check: | ||
5155 | new = aa_label_merge(label, target, GFP_KERNEL); | ||
5156 | if (IS_ERR_OR_NULL(new)) { | ||
5157 | info = "failed to build target label"; | ||
5158 | - error = PTR_ERR(new); | ||
5159 | + if (!new) | ||
5160 | + error = -ENOMEM; | ||
5161 | + else | ||
5162 | + error = PTR_ERR(new); | ||
5163 | new = NULL; | ||
5164 | perms.allow = 0; | ||
5165 | goto audit; | ||
5166 | diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c | ||
5167 | index b455930a3eaf..ec73d83d0d31 100644 | ||
5168 | --- a/tools/bpf/bpftool/map.c | ||
5169 | +++ b/tools/bpf/bpftool/map.c | ||
5170 | @@ -370,6 +370,20 @@ static char **parse_bytes(char **argv, const char *name, unsigned char *val, | ||
5171 | return argv + i; | ||
5172 | } | ||
5173 | |||
5174 | +/* on per cpu maps we must copy the provided value on all value instances */ | ||
5175 | +static void fill_per_cpu_value(struct bpf_map_info *info, void *value) | ||
5176 | +{ | ||
5177 | + unsigned int i, n, step; | ||
5178 | + | ||
5179 | + if (!map_is_per_cpu(info->type)) | ||
5180 | + return; | ||
5181 | + | ||
5182 | + n = get_possible_cpus(); | ||
5183 | + step = round_up(info->value_size, 8); | ||
5184 | + for (i = 1; i < n; i++) | ||
5185 | + memcpy(value + i * step, value, info->value_size); | ||
5186 | +} | ||
5187 | + | ||
5188 | static int parse_elem(char **argv, struct bpf_map_info *info, | ||
5189 | void *key, void *value, __u32 key_size, __u32 value_size, | ||
5190 | __u32 *flags, __u32 **value_fd) | ||
5191 | @@ -449,6 +463,8 @@ static int parse_elem(char **argv, struct bpf_map_info *info, | ||
5192 | argv = parse_bytes(argv, "value", value, value_size); | ||
5193 | if (!argv) | ||
5194 | return -1; | ||
5195 | + | ||
5196 | + fill_per_cpu_value(info, value); | ||
5197 | } | ||
5198 | |||
5199 | return parse_elem(argv, info, key, NULL, key_size, value_size, | ||
5200 | diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c | ||
5201 | index 0de024a6cc2b..bbba0d61570f 100644 | ||
5202 | --- a/tools/bpf/bpftool/prog.c | ||
5203 | +++ b/tools/bpf/bpftool/prog.c | ||
5204 | @@ -109,13 +109,14 @@ static void print_boot_time(__u64 nsecs, char *buf, unsigned int size) | ||
5205 | |||
5206 | static int prog_fd_by_tag(unsigned char *tag) | ||
5207 | { | ||
5208 | - struct bpf_prog_info info = {}; | ||
5209 | - __u32 len = sizeof(info); | ||
5210 | unsigned int id = 0; | ||
5211 | int err; | ||
5212 | int fd; | ||
5213 | |||
5214 | while (true) { | ||
5215 | + struct bpf_prog_info info = {}; | ||
5216 | + __u32 len = sizeof(info); | ||
5217 | + | ||
5218 | err = bpf_prog_get_next_id(id, &id); | ||
5219 | if (err) { | ||
5220 | p_err("%s", strerror(errno)); | ||
5221 | diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c | ||
5222 | index 6c1e7ceedcf3..53c11fc0855e 100644 | ||
5223 | --- a/tools/perf/builtin-script.c | ||
5224 | +++ b/tools/perf/builtin-script.c | ||
5225 | @@ -1589,13 +1589,8 @@ static void perf_sample__fprint_metric(struct perf_script *script, | ||
5226 | .force_header = false, | ||
5227 | }; | ||
5228 | struct perf_evsel *ev2; | ||
5229 | - static bool init; | ||
5230 | u64 val; | ||
5231 | |||
5232 | - if (!init) { | ||
5233 | - perf_stat__init_shadow_stats(); | ||
5234 | - init = true; | ||
5235 | - } | ||
5236 | if (!evsel->stats) | ||
5237 | perf_evlist__alloc_stats(script->session->evlist, false); | ||
5238 | if (evsel_script(evsel->leader)->gnum++ == 0) | ||
5239 | @@ -1658,7 +1653,7 @@ static void process_event(struct perf_script *script, | ||
5240 | return; | ||
5241 | } | ||
5242 | |||
5243 | - if (PRINT_FIELD(TRACE)) { | ||
5244 | + if (PRINT_FIELD(TRACE) && sample->raw_data) { | ||
5245 | event_format__fprintf(evsel->tp_format, sample->cpu, | ||
5246 | sample->raw_data, sample->raw_size, fp); | ||
5247 | } | ||
5248 | @@ -2214,6 +2209,8 @@ static int __cmd_script(struct perf_script *script) | ||
5249 | |||
5250 | signal(SIGINT, sig_handler); | ||
5251 | |||
5252 | + perf_stat__init_shadow_stats(); | ||
5253 | + | ||
5254 | /* override event processing functions */ | ||
5255 | if (script->show_task_events) { | ||
5256 | script->tool.comm = process_comm_event; | ||
5257 | diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c | ||
5258 | index 22ab8e67c760..3f43aedb384d 100644 | ||
5259 | --- a/tools/perf/builtin-trace.c | ||
5260 | +++ b/tools/perf/builtin-trace.c | ||
5261 | @@ -2263,19 +2263,30 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp); | ||
5262 | |||
5263 | static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist) | ||
5264 | { | ||
5265 | - struct perf_evsel *evsel = perf_evsel__newtp("probe", "vfs_getname"); | ||
5266 | + bool found = false; | ||
5267 | + struct perf_evsel *evsel, *tmp; | ||
5268 | + struct parse_events_error err = { .idx = 0, }; | ||
5269 | + int ret = parse_events(evlist, "probe:vfs_getname*", &err); | ||
5270 | |||
5271 | - if (IS_ERR(evsel)) | ||
5272 | + if (ret) | ||
5273 | return false; | ||
5274 | |||
5275 | - if (perf_evsel__field(evsel, "pathname") == NULL) { | ||
5276 | + evlist__for_each_entry_safe(evlist, evsel, tmp) { | ||
5277 | + if (!strstarts(perf_evsel__name(evsel), "probe:vfs_getname")) | ||
5278 | + continue; | ||
5279 | + | ||
5280 | + if (perf_evsel__field(evsel, "pathname")) { | ||
5281 | + evsel->handler = trace__vfs_getname; | ||
5282 | + found = true; | ||
5283 | + continue; | ||
5284 | + } | ||
5285 | + | ||
5286 | + list_del_init(&evsel->node); | ||
5287 | + evsel->evlist = NULL; | ||
5288 | perf_evsel__delete(evsel); | ||
5289 | - return false; | ||
5290 | } | ||
5291 | |||
5292 | - evsel->handler = trace__vfs_getname; | ||
5293 | - perf_evlist__add(evlist, evsel); | ||
5294 | - return true; | ||
5295 | + return found; | ||
5296 | } | ||
5297 | |||
5298 | static struct perf_evsel *perf_evsel__new_pgfault(u64 config) | ||
5299 | diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c | ||
5300 | index 1ccbd3342069..383674f448fc 100644 | ||
5301 | --- a/tools/perf/util/cpumap.c | ||
5302 | +++ b/tools/perf/util/cpumap.c | ||
5303 | @@ -134,7 +134,12 @@ struct cpu_map *cpu_map__new(const char *cpu_list) | ||
5304 | if (!cpu_list) | ||
5305 | return cpu_map__read_all_cpu_map(); | ||
5306 | |||
5307 | - if (!isdigit(*cpu_list)) | ||
5308 | + /* | ||
5309 | + * must handle the case of empty cpumap to cover | ||
5310 | + * TOPOLOGY header for NUMA nodes with no CPU | ||
5311 | + * ( e.g., because of CPU hotplug) | ||
5312 | + */ | ||
5313 | + if (!isdigit(*cpu_list) && *cpu_list != '\0') | ||
5314 | goto out; | ||
5315 | |||
5316 | while (isdigit(*cpu_list)) { | ||
5317 | @@ -181,8 +186,10 @@ struct cpu_map *cpu_map__new(const char *cpu_list) | ||
5318 | |||
5319 | if (nr_cpus > 0) | ||
5320 | cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); | ||
5321 | - else | ||
5322 | + else if (*cpu_list != '\0') | ||
5323 | cpus = cpu_map__default_new(); | ||
5324 | + else | ||
5325 | + cpus = cpu_map__dummy_new(); | ||
5326 | invalid: | ||
5327 | free(tmp_cpus); | ||
5328 | out: | ||
5329 | diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c | ||
5330 | index 6e70cc00c161..a701a8a48f00 100644 | ||
5331 | --- a/tools/perf/util/symbol-elf.c | ||
5332 | +++ b/tools/perf/util/symbol-elf.c | ||
5333 | @@ -87,6 +87,11 @@ static inline uint8_t elf_sym__type(const GElf_Sym *sym) | ||
5334 | return GELF_ST_TYPE(sym->st_info); | ||
5335 | } | ||
5336 | |||
5337 | +static inline uint8_t elf_sym__visibility(const GElf_Sym *sym) | ||
5338 | +{ | ||
5339 | + return GELF_ST_VISIBILITY(sym->st_other); | ||
5340 | +} | ||
5341 | + | ||
5342 | #ifndef STT_GNU_IFUNC | ||
5343 | #define STT_GNU_IFUNC 10 | ||
5344 | #endif | ||
5345 | @@ -111,7 +116,9 @@ static inline int elf_sym__is_label(const GElf_Sym *sym) | ||
5346 | return elf_sym__type(sym) == STT_NOTYPE && | ||
5347 | sym->st_name != 0 && | ||
5348 | sym->st_shndx != SHN_UNDEF && | ||
5349 | - sym->st_shndx != SHN_ABS; | ||
5350 | + sym->st_shndx != SHN_ABS && | ||
5351 | + elf_sym__visibility(sym) != STV_HIDDEN && | ||
5352 | + elf_sym__visibility(sym) != STV_INTERNAL; | ||
5353 | } | ||
5354 | |||
5355 | static bool elf_sym__filter(GElf_Sym *sym) | ||
5356 | diff --git a/tools/testing/selftests/bpf/bpf_util.h b/tools/testing/selftests/bpf/bpf_util.h | ||
5357 | index 315a44fa32af..84fd6f1bf33e 100644 | ||
5358 | --- a/tools/testing/selftests/bpf/bpf_util.h | ||
5359 | +++ b/tools/testing/selftests/bpf/bpf_util.h | ||
5360 | @@ -13,7 +13,7 @@ static inline unsigned int bpf_num_possible_cpus(void) | ||
5361 | unsigned int start, end, possible_cpus = 0; | ||
5362 | char buff[128]; | ||
5363 | FILE *fp; | ||
5364 | - int n; | ||
5365 | + int len, n, i, j = 0; | ||
5366 | |||
5367 | fp = fopen(fcpu, "r"); | ||
5368 | if (!fp) { | ||
5369 | @@ -21,17 +21,27 @@ static inline unsigned int bpf_num_possible_cpus(void) | ||
5370 | exit(1); | ||
5371 | } | ||
5372 | |||
5373 | - while (fgets(buff, sizeof(buff), fp)) { | ||
5374 | - n = sscanf(buff, "%u-%u", &start, &end); | ||
5375 | - if (n == 0) { | ||
5376 | - printf("Failed to retrieve # possible CPUs!\n"); | ||
5377 | - exit(1); | ||
5378 | - } else if (n == 1) { | ||
5379 | - end = start; | ||
5380 | + if (!fgets(buff, sizeof(buff), fp)) { | ||
5381 | + printf("Failed to read %s!\n", fcpu); | ||
5382 | + exit(1); | ||
5383 | + } | ||
5384 | + | ||
5385 | + len = strlen(buff); | ||
5386 | + for (i = 0; i <= len; i++) { | ||
5387 | + if (buff[i] == ',' || buff[i] == '\0') { | ||
5388 | + buff[i] = '\0'; | ||
5389 | + n = sscanf(&buff[j], "%u-%u", &start, &end); | ||
5390 | + if (n <= 0) { | ||
5391 | + printf("Failed to retrieve # possible CPUs!\n"); | ||
5392 | + exit(1); | ||
5393 | + } else if (n == 1) { | ||
5394 | + end = start; | ||
5395 | + } | ||
5396 | + possible_cpus += end - start + 1; | ||
5397 | + j = i + 1; | ||
5398 | } | ||
5399 | - possible_cpus = start == 0 ? end + 1 : 0; | ||
5400 | - break; | ||
5401 | } | ||
5402 | + | ||
5403 | fclose(fp); | ||
5404 | |||
5405 | return possible_cpus; | ||
5406 | diff --git a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh | ||
5407 | index bab13dd025a6..0d26b5e3f966 100755 | ||
5408 | --- a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh | ||
5409 | +++ b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh | ||
5410 | @@ -37,6 +37,10 @@ prerequisite() | ||
5411 | exit $ksft_skip | ||
5412 | fi | ||
5413 | |||
5414 | + present_cpus=`cat $SYSFS/devices/system/cpu/present` | ||
5415 | + present_max=${present_cpus##*-} | ||
5416 | + echo "present_cpus = $present_cpus present_max = $present_max" | ||
5417 | + | ||
5418 | echo -e "\t Cpus in online state: $online_cpus" | ||
5419 | |||
5420 | offline_cpus=`cat $SYSFS/devices/system/cpu/offline` | ||
5421 | @@ -151,6 +155,8 @@ online_cpus=0 | ||
5422 | online_max=0 | ||
5423 | offline_cpus=0 | ||
5424 | offline_max=0 | ||
5425 | +present_cpus=0 | ||
5426 | +present_max=0 | ||
5427 | |||
5428 | while getopts e:ahp: opt; do | ||
5429 | case $opt in | ||
5430 | @@ -190,9 +196,10 @@ if [ $allcpus -eq 0 ]; then | ||
5431 | online_cpu_expect_success $online_max | ||
5432 | |||
5433 | if [[ $offline_cpus -gt 0 ]]; then | ||
5434 | - echo -e "\t offline to online to offline: cpu $offline_max" | ||
5435 | - online_cpu_expect_success $offline_max | ||
5436 | - offline_cpu_expect_success $offline_max | ||
5437 | + echo -e "\t offline to online to offline: cpu $present_max" | ||
5438 | + online_cpu_expect_success $present_max | ||
5439 | + offline_cpu_expect_success $present_max | ||
5440 | + online_cpu $present_max | ||
5441 | fi | ||
5442 | exit 0 | ||
5443 | else | ||
5444 | diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile | ||
5445 | index 919aa2ac00af..9a3764a1084e 100644 | ||
5446 | --- a/tools/testing/selftests/net/Makefile | ||
5447 | +++ b/tools/testing/selftests/net/Makefile | ||
5448 | @@ -18,6 +18,6 @@ TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict tls | ||
5449 | KSFT_KHDR_INSTALL := 1 | ||
5450 | include ../lib.mk | ||
5451 | |||
5452 | -$(OUTPUT)/reuseport_bpf_numa: LDFLAGS += -lnuma | ||
5453 | +$(OUTPUT)/reuseport_bpf_numa: LDLIBS += -lnuma | ||
5454 | $(OUTPUT)/tcp_mmap: LDFLAGS += -lpthread | ||
5455 | $(OUTPUT)/tcp_inq: LDFLAGS += -lpthread | ||
5456 | diff --git a/tools/testing/selftests/netfilter/Makefile b/tools/testing/selftests/netfilter/Makefile | ||
5457 | index 47ed6cef93fb..c9ff2b47bd1c 100644 | ||
5458 | --- a/tools/testing/selftests/netfilter/Makefile | ||
5459 | +++ b/tools/testing/selftests/netfilter/Makefile | ||
5460 | @@ -1,6 +1,6 @@ | ||
5461 | # SPDX-License-Identifier: GPL-2.0 | ||
5462 | # Makefile for netfilter selftests | ||
5463 | |||
5464 | -TEST_PROGS := nft_trans_stress.sh | ||
5465 | +TEST_PROGS := nft_trans_stress.sh nft_nat.sh | ||
5466 | |||
5467 | include ../lib.mk | ||
5468 | diff --git a/tools/testing/selftests/netfilter/config b/tools/testing/selftests/netfilter/config | ||
5469 | index 1017313e41a8..59caa8f71cd8 100644 | ||
5470 | --- a/tools/testing/selftests/netfilter/config | ||
5471 | +++ b/tools/testing/selftests/netfilter/config | ||
5472 | @@ -1,2 +1,2 @@ | ||
5473 | CONFIG_NET_NS=y | ||
5474 | -NF_TABLES_INET=y | ||
5475 | +CONFIG_NF_TABLES_INET=y | ||
5476 | diff --git a/tools/testing/selftests/netfilter/nft_nat.sh b/tools/testing/selftests/netfilter/nft_nat.sh | ||
5477 | new file mode 100755 | ||
5478 | index 000000000000..8ec76681605c | ||
5479 | --- /dev/null | ||
5480 | +++ b/tools/testing/selftests/netfilter/nft_nat.sh | ||
5481 | @@ -0,0 +1,762 @@ | ||
5482 | +#!/bin/bash | ||
5483 | +# | ||
5484 | +# This test is for basic NAT functionality: snat, dnat, redirect, masquerade. | ||
5485 | +# | ||
5486 | + | ||
5487 | +# Kselftest framework requirement - SKIP code is 4. | ||
5488 | +ksft_skip=4 | ||
5489 | +ret=0 | ||
5490 | + | ||
5491 | +nft --version > /dev/null 2>&1 | ||
5492 | +if [ $? -ne 0 ];then | ||
5493 | + echo "SKIP: Could not run test without nft tool" | ||
5494 | + exit $ksft_skip | ||
5495 | +fi | ||
5496 | + | ||
5497 | +ip -Version > /dev/null 2>&1 | ||
5498 | +if [ $? -ne 0 ];then | ||
5499 | + echo "SKIP: Could not run test without ip tool" | ||
5500 | + exit $ksft_skip | ||
5501 | +fi | ||
5502 | + | ||
5503 | +ip netns add ns0 | ||
5504 | +ip netns add ns1 | ||
5505 | +ip netns add ns2 | ||
5506 | + | ||
5507 | +ip link add veth0 netns ns0 type veth peer name eth0 netns ns1 | ||
5508 | +ip link add veth1 netns ns0 type veth peer name eth0 netns ns2 | ||
5509 | + | ||
5510 | +ip -net ns0 link set lo up | ||
5511 | +ip -net ns0 link set veth0 up | ||
5512 | +ip -net ns0 addr add 10.0.1.1/24 dev veth0 | ||
5513 | +ip -net ns0 addr add dead:1::1/64 dev veth0 | ||
5514 | + | ||
5515 | +ip -net ns0 link set veth1 up | ||
5516 | +ip -net ns0 addr add 10.0.2.1/24 dev veth1 | ||
5517 | +ip -net ns0 addr add dead:2::1/64 dev veth1 | ||
5518 | + | ||
5519 | +for i in 1 2; do | ||
5520 | + ip -net ns$i link set lo up | ||
5521 | + ip -net ns$i link set eth0 up | ||
5522 | + ip -net ns$i addr add 10.0.$i.99/24 dev eth0 | ||
5523 | + ip -net ns$i route add default via 10.0.$i.1 | ||
5524 | + ip -net ns$i addr add dead:$i::99/64 dev eth0 | ||
5525 | + ip -net ns$i route add default via dead:$i::1 | ||
5526 | +done | ||
5527 | + | ||
5528 | +bad_counter() | ||
5529 | +{ | ||
5530 | + local ns=$1 | ||
5531 | + local counter=$2 | ||
5532 | + local expect=$3 | ||
5533 | + | ||
5534 | + echo "ERROR: $counter counter in $ns has unexpected value (expected $expect)" 1>&2 | ||
5535 | + ip netns exec $ns nft list counter inet filter $counter 1>&2 | ||
5536 | +} | ||
5537 | + | ||
5538 | +check_counters() | ||
5539 | +{ | ||
5540 | + ns=$1 | ||
5541 | + local lret=0 | ||
5542 | + | ||
5543 | + cnt=$(ip netns exec $ns nft list counter inet filter ns0in | grep -q "packets 1 bytes 84") | ||
5544 | + if [ $? -ne 0 ]; then | ||
5545 | + bad_counter $ns ns0in "packets 1 bytes 84" | ||
5546 | + lret=1 | ||
5547 | + fi | ||
5548 | + cnt=$(ip netns exec $ns nft list counter inet filter ns0out | grep -q "packets 1 bytes 84") | ||
5549 | + if [ $? -ne 0 ]; then | ||
5550 | + bad_counter $ns ns0out "packets 1 bytes 84" | ||
5551 | + lret=1 | ||
5552 | + fi | ||
5553 | + | ||
5554 | + expect="packets 1 bytes 104" | ||
5555 | + cnt=$(ip netns exec $ns nft list counter inet filter ns0in6 | grep -q "$expect") | ||
5556 | + if [ $? -ne 0 ]; then | ||
5557 | + bad_counter $ns ns0in6 "$expect" | ||
5558 | + lret=1 | ||
5559 | + fi | ||
5560 | + cnt=$(ip netns exec $ns nft list counter inet filter ns0out6 | grep -q "$expect") | ||
5561 | + if [ $? -ne 0 ]; then | ||
5562 | + bad_counter $ns ns0out6 "$expect" | ||
5563 | + lret=1 | ||
5564 | + fi | ||
5565 | + | ||
5566 | + return $lret | ||
5567 | +} | ||
5568 | + | ||
5569 | +check_ns0_counters() | ||
5570 | +{ | ||
5571 | + local ns=$1 | ||
5572 | + local lret=0 | ||
5573 | + | ||
5574 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns0in | grep -q "packets 0 bytes 0") | ||
5575 | + if [ $? -ne 0 ]; then | ||
5576 | + bad_counter ns0 ns0in "packets 0 bytes 0" | ||
5577 | + lret=1 | ||
5578 | + fi | ||
5579 | + | ||
5580 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns0in6 | grep -q "packets 0 bytes 0") | ||
5581 | + if [ $? -ne 0 ]; then | ||
5582 | + bad_counter ns0 ns0in6 "packets 0 bytes 0" | ||
5583 | + lret=1 | ||
5584 | + fi | ||
5585 | + | ||
5586 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns0out | grep -q "packets 0 bytes 0") | ||
5587 | + if [ $? -ne 0 ]; then | ||
5588 | + bad_counter ns0 ns0out "packets 0 bytes 0" | ||
5589 | + lret=1 | ||
5590 | + fi | ||
5591 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns0out6 | grep -q "packets 0 bytes 0") | ||
5592 | + if [ $? -ne 0 ]; then | ||
5593 | + bad_counter ns0 ns0out6 "packets 0 bytes 0" | ||
5594 | + lret=1 | ||
5595 | + fi | ||
5596 | + | ||
5597 | + for dir in "in" "out" ; do | ||
5598 | + expect="packets 1 bytes 84" | ||
5599 | + cnt=$(ip netns exec ns0 nft list counter inet filter ${ns}${dir} | grep -q "$expect") | ||
5600 | + if [ $? -ne 0 ]; then | ||
5601 | + bad_counter ns0 $ns$dir "$expect" | ||
5602 | + lret=1 | ||
5603 | + fi | ||
5604 | + | ||
5605 | + expect="packets 1 bytes 104" | ||
5606 | + cnt=$(ip netns exec ns0 nft list counter inet filter ${ns}${dir}6 | grep -q "$expect") | ||
5607 | + if [ $? -ne 0 ]; then | ||
5608 | + bad_counter ns0 $ns$dir6 "$expect" | ||
5609 | + lret=1 | ||
5610 | + fi | ||
5611 | + done | ||
5612 | + | ||
5613 | + return $lret | ||
5614 | +} | ||
5615 | + | ||
5616 | +reset_counters() | ||
5617 | +{ | ||
5618 | + for i in 0 1 2;do | ||
5619 | + ip netns exec ns$i nft reset counters inet > /dev/null | ||
5620 | + done | ||
5621 | +} | ||
5622 | + | ||
5623 | +test_local_dnat6() | ||
5624 | +{ | ||
5625 | + local lret=0 | ||
5626 | +ip netns exec ns0 nft -f - <<EOF | ||
5627 | +table ip6 nat { | ||
5628 | + chain output { | ||
5629 | + type nat hook output priority 0; policy accept; | ||
5630 | + ip6 daddr dead:1::99 dnat to dead:2::99 | ||
5631 | + } | ||
5632 | +} | ||
5633 | +EOF | ||
5634 | + if [ $? -ne 0 ]; then | ||
5635 | + echo "SKIP: Could not add add ip6 dnat hook" | ||
5636 | + return $ksft_skip | ||
5637 | + fi | ||
5638 | + | ||
5639 | + # ping netns1, expect rewrite to netns2 | ||
5640 | + ip netns exec ns0 ping -q -c 1 dead:1::99 > /dev/null | ||
5641 | + if [ $? -ne 0 ]; then | ||
5642 | + lret=1 | ||
5643 | + echo "ERROR: ping6 failed" | ||
5644 | + return $lret | ||
5645 | + fi | ||
5646 | + | ||
5647 | + expect="packets 0 bytes 0" | ||
5648 | + for dir in "in6" "out6" ; do | ||
5649 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns1${dir} | grep -q "$expect") | ||
5650 | + if [ $? -ne 0 ]; then | ||
5651 | + bad_counter ns0 ns1$dir "$expect" | ||
5652 | + lret=1 | ||
5653 | + fi | ||
5654 | + done | ||
5655 | + | ||
5656 | + expect="packets 1 bytes 104" | ||
5657 | + for dir in "in6" "out6" ; do | ||
5658 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
5659 | + if [ $? -ne 0 ]; then | ||
5660 | + bad_counter ns0 ns2$dir "$expect" | ||
5661 | + lret=1 | ||
5662 | + fi | ||
5663 | + done | ||
5664 | + | ||
5665 | + # expect 0 count in ns1 | ||
5666 | + expect="packets 0 bytes 0" | ||
5667 | + for dir in "in6" "out6" ; do | ||
5668 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns0${dir} | grep -q "$expect") | ||
5669 | + if [ $? -ne 0 ]; then | ||
5670 | + bad_counter ns1 ns0$dir "$expect" | ||
5671 | + lret=1 | ||
5672 | + fi | ||
5673 | + done | ||
5674 | + | ||
5675 | + # expect 1 packet in ns2 | ||
5676 | + expect="packets 1 bytes 104" | ||
5677 | + for dir in "in6" "out6" ; do | ||
5678 | + cnt=$(ip netns exec ns2 nft list counter inet filter ns0${dir} | grep -q "$expect") | ||
5679 | + if [ $? -ne 0 ]; then | ||
5680 | + bad_counter ns2 ns0$dir "$expect" | ||
5681 | + lret=1 | ||
5682 | + fi | ||
5683 | + done | ||
5684 | + | ||
5685 | + test $lret -eq 0 && echo "PASS: ipv6 ping to ns1 was NATted to ns2" | ||
5686 | + ip netns exec ns0 nft flush chain ip6 nat output | ||
5687 | + | ||
5688 | + return $lret | ||
5689 | +} | ||
5690 | + | ||
5691 | +test_local_dnat() | ||
5692 | +{ | ||
5693 | + local lret=0 | ||
5694 | +ip netns exec ns0 nft -f - <<EOF | ||
5695 | +table ip nat { | ||
5696 | + chain output { | ||
5697 | + type nat hook output priority 0; policy accept; | ||
5698 | + ip daddr 10.0.1.99 dnat to 10.0.2.99 | ||
5699 | + } | ||
5700 | +} | ||
5701 | +EOF | ||
5702 | + # ping netns1, expect rewrite to netns2 | ||
5703 | + ip netns exec ns0 ping -q -c 1 10.0.1.99 > /dev/null | ||
5704 | + if [ $? -ne 0 ]; then | ||
5705 | + lret=1 | ||
5706 | + echo "ERROR: ping failed" | ||
5707 | + return $lret | ||
5708 | + fi | ||
5709 | + | ||
5710 | + expect="packets 0 bytes 0" | ||
5711 | + for dir in "in" "out" ; do | ||
5712 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns1${dir} | grep -q "$expect") | ||
5713 | + if [ $? -ne 0 ]; then | ||
5714 | + bad_counter ns0 ns1$dir "$expect" | ||
5715 | + lret=1 | ||
5716 | + fi | ||
5717 | + done | ||
5718 | + | ||
5719 | + expect="packets 1 bytes 84" | ||
5720 | + for dir in "in" "out" ; do | ||
5721 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
5722 | + if [ $? -ne 0 ]; then | ||
5723 | + bad_counter ns0 ns2$dir "$expect" | ||
5724 | + lret=1 | ||
5725 | + fi | ||
5726 | + done | ||
5727 | + | ||
5728 | + # expect 0 count in ns1 | ||
5729 | + expect="packets 0 bytes 0" | ||
5730 | + for dir in "in" "out" ; do | ||
5731 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns0${dir} | grep -q "$expect") | ||
5732 | + if [ $? -ne 0 ]; then | ||
5733 | + bad_counter ns1 ns0$dir "$expect" | ||
5734 | + lret=1 | ||
5735 | + fi | ||
5736 | + done | ||
5737 | + | ||
5738 | + # expect 1 packet in ns2 | ||
5739 | + expect="packets 1 bytes 84" | ||
5740 | + for dir in "in" "out" ; do | ||
5741 | + cnt=$(ip netns exec ns2 nft list counter inet filter ns0${dir} | grep -q "$expect") | ||
5742 | + if [ $? -ne 0 ]; then | ||
5743 | + bad_counter ns2 ns0$dir "$expect" | ||
5744 | + lret=1 | ||
5745 | + fi | ||
5746 | + done | ||
5747 | + | ||
5748 | + test $lret -eq 0 && echo "PASS: ping to ns1 was NATted to ns2" | ||
5749 | + | ||
5750 | + ip netns exec ns0 nft flush chain ip nat output | ||
5751 | + | ||
5752 | + reset_counters | ||
5753 | + ip netns exec ns0 ping -q -c 1 10.0.1.99 > /dev/null | ||
5754 | + if [ $? -ne 0 ]; then | ||
5755 | + lret=1 | ||
5756 | + echo "ERROR: ping failed" | ||
5757 | + return $lret | ||
5758 | + fi | ||
5759 | + | ||
5760 | + expect="packets 1 bytes 84" | ||
5761 | + for dir in "in" "out" ; do | ||
5762 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns1${dir} | grep -q "$expect") | ||
5763 | + if [ $? -ne 0 ]; then | ||
5764 | + bad_counter ns1 ns1$dir "$expect" | ||
5765 | + lret=1 | ||
5766 | + fi | ||
5767 | + done | ||
5768 | + expect="packets 0 bytes 0" | ||
5769 | + for dir in "in" "out" ; do | ||
5770 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
5771 | + if [ $? -ne 0 ]; then | ||
5772 | + bad_counter ns0 ns2$dir "$expect" | ||
5773 | + lret=1 | ||
5774 | + fi | ||
5775 | + done | ||
5776 | + | ||
5777 | + # expect 1 count in ns1 | ||
5778 | + expect="packets 1 bytes 84" | ||
5779 | + for dir in "in" "out" ; do | ||
5780 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns0${dir} | grep -q "$expect") | ||
5781 | + if [ $? -ne 0 ]; then | ||
5782 | + bad_counter ns0 ns0$dir "$expect" | ||
5783 | + lret=1 | ||
5784 | + fi | ||
5785 | + done | ||
5786 | + | ||
5787 | + # expect 0 packet in ns2 | ||
5788 | + expect="packets 0 bytes 0" | ||
5789 | + for dir in "in" "out" ; do | ||
5790 | + cnt=$(ip netns exec ns2 nft list counter inet filter ns0${dir} | grep -q "$expect") | ||
5791 | + if [ $? -ne 0 ]; then | ||
5792 | + bad_counter ns2 ns2$dir "$expect" | ||
5793 | + lret=1 | ||
5794 | + fi | ||
5795 | + done | ||
5796 | + | ||
5797 | + test $lret -eq 0 && echo "PASS: ping to ns1 OK after nat output chain flush" | ||
5798 | + | ||
5799 | + return $lret | ||
5800 | +} | ||
5801 | + | ||
5802 | + | ||
5803 | +test_masquerade6() | ||
5804 | +{ | ||
5805 | + local lret=0 | ||
5806 | + | ||
5807 | + ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null | ||
5808 | + | ||
5809 | + ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 | ||
5810 | + if [ $? -ne 0 ] ; then | ||
5811 | + echo "ERROR: cannot ping ns1 from ns2 via ipv6" | ||
5812 | + return 1 | ||
5813 | + lret=1 | ||
5814 | + fi | ||
5815 | + | ||
5816 | + expect="packets 1 bytes 104" | ||
5817 | + for dir in "in6" "out6" ; do | ||
5818 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
5819 | + if [ $? -ne 0 ]; then | ||
5820 | + bad_counter ns1 ns2$dir "$expect" | ||
5821 | + lret=1 | ||
5822 | + fi | ||
5823 | + | ||
5824 | + cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") | ||
5825 | + if [ $? -ne 0 ]; then | ||
5826 | + bad_counter ns2 ns1$dir "$expect" | ||
5827 | + lret=1 | ||
5828 | + fi | ||
5829 | + done | ||
5830 | + | ||
5831 | + reset_counters | ||
5832 | + | ||
5833 | +# add masquerading rule | ||
5834 | +ip netns exec ns0 nft -f - <<EOF | ||
5835 | +table ip6 nat { | ||
5836 | + chain postrouting { | ||
5837 | + type nat hook postrouting priority 0; policy accept; | ||
5838 | + meta oif veth0 masquerade | ||
5839 | + } | ||
5840 | +} | ||
5841 | +EOF | ||
5842 | + ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 | ||
5843 | + if [ $? -ne 0 ] ; then | ||
5844 | + echo "ERROR: cannot ping ns1 from ns2 with active ipv6 masquerading" | ||
5845 | + lret=1 | ||
5846 | + fi | ||
5847 | + | ||
5848 | + # ns1 should have seen packets from ns0, due to masquerade | ||
5849 | + expect="packets 1 bytes 104" | ||
5850 | + for dir in "in6" "out6" ; do | ||
5851 | + | ||
5852 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns0${dir} | grep -q "$expect") | ||
5853 | + if [ $? -ne 0 ]; then | ||
5854 | + bad_counter ns1 ns0$dir "$expect" | ||
5855 | + lret=1 | ||
5856 | + fi | ||
5857 | + | ||
5858 | + cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") | ||
5859 | + if [ $? -ne 0 ]; then | ||
5860 | + bad_counter ns2 ns1$dir "$expect" | ||
5861 | + lret=1 | ||
5862 | + fi | ||
5863 | + done | ||
5864 | + | ||
5865 | + # ns1 should not have seen packets from ns2, due to masquerade | ||
5866 | + expect="packets 0 bytes 0" | ||
5867 | + for dir in "in6" "out6" ; do | ||
5868 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
5869 | + if [ $? -ne 0 ]; then | ||
5870 | + bad_counter ns1 ns0$dir "$expect" | ||
5871 | + lret=1 | ||
5872 | + fi | ||
5873 | + | ||
5874 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
5875 | + if [ $? -ne 0 ]; then | ||
5876 | + bad_counter ns2 ns1$dir "$expect" | ||
5877 | + lret=1 | ||
5878 | + fi | ||
5879 | + done | ||
5880 | + | ||
5881 | + ip netns exec ns0 nft flush chain ip6 nat postrouting | ||
5882 | + if [ $? -ne 0 ]; then | ||
5883 | + echo "ERROR: Could not flush ip6 nat postrouting" 1>&2 | ||
5884 | + lret=1 | ||
5885 | + fi | ||
5886 | + | ||
5887 | + test $lret -eq 0 && echo "PASS: IPv6 masquerade for ns2" | ||
5888 | + | ||
5889 | + return $lret | ||
5890 | +} | ||
5891 | + | ||
5892 | +test_masquerade() | ||
5893 | +{ | ||
5894 | + local lret=0 | ||
5895 | + | ||
5896 | + ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null | ||
5897 | + ip netns exec ns0 sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null | ||
5898 | + | ||
5899 | + ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 | ||
5900 | + if [ $? -ne 0 ] ; then | ||
5901 | + echo "ERROR: canot ping ns1 from ns2" | ||
5902 | + lret=1 | ||
5903 | + fi | ||
5904 | + | ||
5905 | + expect="packets 1 bytes 84" | ||
5906 | + for dir in "in" "out" ; do | ||
5907 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
5908 | + if [ $? -ne 0 ]; then | ||
5909 | + bad_counter ns1 ns2$dir "$expect" | ||
5910 | + lret=1 | ||
5911 | + fi | ||
5912 | + | ||
5913 | + cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") | ||
5914 | + if [ $? -ne 0 ]; then | ||
5915 | + bad_counter ns2 ns1$dir "$expect" | ||
5916 | + lret=1 | ||
5917 | + fi | ||
5918 | + done | ||
5919 | + | ||
5920 | + reset_counters | ||
5921 | + | ||
5922 | +# add masquerading rule | ||
5923 | +ip netns exec ns0 nft -f - <<EOF | ||
5924 | +table ip nat { | ||
5925 | + chain postrouting { | ||
5926 | + type nat hook postrouting priority 0; policy accept; | ||
5927 | + meta oif veth0 masquerade | ||
5928 | + } | ||
5929 | +} | ||
5930 | +EOF | ||
5931 | + ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 | ||
5932 | + if [ $? -ne 0 ] ; then | ||
5933 | + echo "ERROR: cannot ping ns1 from ns2 with active ip masquerading" | ||
5934 | + lret=1 | ||
5935 | + fi | ||
5936 | + | ||
5937 | + # ns1 should have seen packets from ns0, due to masquerade | ||
5938 | + expect="packets 1 bytes 84" | ||
5939 | + for dir in "in" "out" ; do | ||
5940 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns0${dir} | grep -q "$expect") | ||
5941 | + if [ $? -ne 0 ]; then | ||
5942 | + bad_counter ns1 ns0$dir "$expect" | ||
5943 | + lret=1 | ||
5944 | + fi | ||
5945 | + | ||
5946 | + cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") | ||
5947 | + if [ $? -ne 0 ]; then | ||
5948 | + bad_counter ns2 ns1$dir "$expect" | ||
5949 | + lret=1 | ||
5950 | + fi | ||
5951 | + done | ||
5952 | + | ||
5953 | + # ns1 should not have seen packets from ns2, due to masquerade | ||
5954 | + expect="packets 0 bytes 0" | ||
5955 | + for dir in "in" "out" ; do | ||
5956 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
5957 | + if [ $? -ne 0 ]; then | ||
5958 | + bad_counter ns1 ns0$dir "$expect" | ||
5959 | + lret=1 | ||
5960 | + fi | ||
5961 | + | ||
5962 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
5963 | + if [ $? -ne 0 ]; then | ||
5964 | + bad_counter ns2 ns1$dir "$expect" | ||
5965 | + lret=1 | ||
5966 | + fi | ||
5967 | + done | ||
5968 | + | ||
5969 | + ip netns exec ns0 nft flush chain ip nat postrouting | ||
5970 | + if [ $? -ne 0 ]; then | ||
5971 | + echo "ERROR: Could not flush nat postrouting" 1>&2 | ||
5972 | + lret=1 | ||
5973 | + fi | ||
5974 | + | ||
5975 | + test $lret -eq 0 && echo "PASS: IP masquerade for ns2" | ||
5976 | + | ||
5977 | + return $lret | ||
5978 | +} | ||
5979 | + | ||
5980 | +test_redirect6() | ||
5981 | +{ | ||
5982 | + local lret=0 | ||
5983 | + | ||
5984 | + ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null | ||
5985 | + | ||
5986 | + ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 | ||
5987 | + if [ $? -ne 0 ] ; then | ||
5988 | + echo "ERROR: cannnot ping ns1 from ns2 via ipv6" | ||
5989 | + lret=1 | ||
5990 | + fi | ||
5991 | + | ||
5992 | + expect="packets 1 bytes 104" | ||
5993 | + for dir in "in6" "out6" ; do | ||
5994 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
5995 | + if [ $? -ne 0 ]; then | ||
5996 | + bad_counter ns1 ns2$dir "$expect" | ||
5997 | + lret=1 | ||
5998 | + fi | ||
5999 | + | ||
6000 | + cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") | ||
6001 | + if [ $? -ne 0 ]; then | ||
6002 | + bad_counter ns2 ns1$dir "$expect" | ||
6003 | + lret=1 | ||
6004 | + fi | ||
6005 | + done | ||
6006 | + | ||
6007 | + reset_counters | ||
6008 | + | ||
6009 | +# add redirect rule | ||
6010 | +ip netns exec ns0 nft -f - <<EOF | ||
6011 | +table ip6 nat { | ||
6012 | + chain prerouting { | ||
6013 | + type nat hook prerouting priority 0; policy accept; | ||
6014 | + meta iif veth1 meta l4proto icmpv6 ip6 saddr dead:2::99 ip6 daddr dead:1::99 redirect | ||
6015 | + } | ||
6016 | +} | ||
6017 | +EOF | ||
6018 | + ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 | ||
6019 | + if [ $? -ne 0 ] ; then | ||
6020 | + echo "ERROR: cannot ping ns1 from ns2 with active ip6 redirect" | ||
6021 | + lret=1 | ||
6022 | + fi | ||
6023 | + | ||
6024 | + # ns1 should have seen no packets from ns2, due to redirection | ||
6025 | + expect="packets 0 bytes 0" | ||
6026 | + for dir in "in6" "out6" ; do | ||
6027 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
6028 | + if [ $? -ne 0 ]; then | ||
6029 | + bad_counter ns1 ns0$dir "$expect" | ||
6030 | + lret=1 | ||
6031 | + fi | ||
6032 | + done | ||
6033 | + | ||
6034 | + # ns0 should have seen packets from ns2, due to masquerade | ||
6035 | + expect="packets 1 bytes 104" | ||
6036 | + for dir in "in6" "out6" ; do | ||
6037 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
6038 | + if [ $? -ne 0 ]; then | ||
6039 | + bad_counter ns1 ns0$dir "$expect" | ||
6040 | + lret=1 | ||
6041 | + fi | ||
6042 | + done | ||
6043 | + | ||
6044 | + ip netns exec ns0 nft delete table ip6 nat | ||
6045 | + if [ $? -ne 0 ]; then | ||
6046 | + echo "ERROR: Could not delete ip6 nat table" 1>&2 | ||
6047 | + lret=1 | ||
6048 | + fi | ||
6049 | + | ||
6050 | + test $lret -eq 0 && echo "PASS: IPv6 redirection for ns2" | ||
6051 | + | ||
6052 | + return $lret | ||
6053 | +} | ||
6054 | + | ||
6055 | +test_redirect() | ||
6056 | +{ | ||
6057 | + local lret=0 | ||
6058 | + | ||
6059 | + ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null | ||
6060 | + ip netns exec ns0 sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null | ||
6061 | + | ||
6062 | + ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 | ||
6063 | + if [ $? -ne 0 ] ; then | ||
6064 | + echo "ERROR: cannot ping ns1 from ns2" | ||
6065 | + lret=1 | ||
6066 | + fi | ||
6067 | + | ||
6068 | + expect="packets 1 bytes 84" | ||
6069 | + for dir in "in" "out" ; do | ||
6070 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
6071 | + if [ $? -ne 0 ]; then | ||
6072 | + bad_counter ns1 ns2$dir "$expect" | ||
6073 | + lret=1 | ||
6074 | + fi | ||
6075 | + | ||
6076 | + cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") | ||
6077 | + if [ $? -ne 0 ]; then | ||
6078 | + bad_counter ns2 ns1$dir "$expect" | ||
6079 | + lret=1 | ||
6080 | + fi | ||
6081 | + done | ||
6082 | + | ||
6083 | + reset_counters | ||
6084 | + | ||
6085 | +# add redirect rule | ||
6086 | +ip netns exec ns0 nft -f - <<EOF | ||
6087 | +table ip nat { | ||
6088 | + chain prerouting { | ||
6089 | + type nat hook prerouting priority 0; policy accept; | ||
6090 | + meta iif veth1 ip protocol icmp ip saddr 10.0.2.99 ip daddr 10.0.1.99 redirect | ||
6091 | + } | ||
6092 | +} | ||
6093 | +EOF | ||
6094 | + ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 | ||
6095 | + if [ $? -ne 0 ] ; then | ||
6096 | + echo "ERROR: cannot ping ns1 from ns2 with active ip redirect" | ||
6097 | + lret=1 | ||
6098 | + fi | ||
6099 | + | ||
6100 | + # ns1 should have seen no packets from ns2, due to redirection | ||
6101 | + expect="packets 0 bytes 0" | ||
6102 | + for dir in "in" "out" ; do | ||
6103 | + | ||
6104 | + cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
6105 | + if [ $? -ne 0 ]; then | ||
6106 | + bad_counter ns1 ns0$dir "$expect" | ||
6107 | + lret=1 | ||
6108 | + fi | ||
6109 | + done | ||
6110 | + | ||
6111 | + # ns0 should have seen packets from ns2, due to masquerade | ||
6112 | + expect="packets 1 bytes 84" | ||
6113 | + for dir in "in" "out" ; do | ||
6114 | + cnt=$(ip netns exec ns0 nft list counter inet filter ns2${dir} | grep -q "$expect") | ||
6115 | + if [ $? -ne 0 ]; then | ||
6116 | + bad_counter ns1 ns0$dir "$expect" | ||
6117 | + lret=1 | ||
6118 | + fi | ||
6119 | + done | ||
6120 | + | ||
6121 | + ip netns exec ns0 nft delete table ip nat | ||
6122 | + if [ $? -ne 0 ]; then | ||
6123 | + echo "ERROR: Could not delete nat table" 1>&2 | ||
6124 | + lret=1 | ||
6125 | + fi | ||
6126 | + | ||
6127 | + test $lret -eq 0 && echo "PASS: IP redirection for ns2" | ||
6128 | + | ||
6129 | + return $lret | ||
6130 | +} | ||
6131 | + | ||
6132 | + | ||
6133 | +# ip netns exec ns0 ping -c 1 -q 10.0.$i.99 | ||
6134 | +for i in 0 1 2; do | ||
6135 | +ip netns exec ns$i nft -f - <<EOF | ||
6136 | +table inet filter { | ||
6137 | + counter ns0in {} | ||
6138 | + counter ns1in {} | ||
6139 | + counter ns2in {} | ||
6140 | + | ||
6141 | + counter ns0out {} | ||
6142 | + counter ns1out {} | ||
6143 | + counter ns2out {} | ||
6144 | + | ||
6145 | + counter ns0in6 {} | ||
6146 | + counter ns1in6 {} | ||
6147 | + counter ns2in6 {} | ||
6148 | + | ||
6149 | + counter ns0out6 {} | ||
6150 | + counter ns1out6 {} | ||
6151 | + counter ns2out6 {} | ||
6152 | + | ||
6153 | + map nsincounter { | ||
6154 | + type ipv4_addr : counter | ||
6155 | + elements = { 10.0.1.1 : "ns0in", | ||
6156 | + 10.0.2.1 : "ns0in", | ||
6157 | + 10.0.1.99 : "ns1in", | ||
6158 | + 10.0.2.99 : "ns2in" } | ||
6159 | + } | ||
6160 | + | ||
6161 | + map nsincounter6 { | ||
6162 | + type ipv6_addr : counter | ||
6163 | + elements = { dead:1::1 : "ns0in6", | ||
6164 | + dead:2::1 : "ns0in6", | ||
6165 | + dead:1::99 : "ns1in6", | ||
6166 | + dead:2::99 : "ns2in6" } | ||
6167 | + } | ||
6168 | + | ||
6169 | + map nsoutcounter { | ||
6170 | + type ipv4_addr : counter | ||
6171 | + elements = { 10.0.1.1 : "ns0out", | ||
6172 | + 10.0.2.1 : "ns0out", | ||
6173 | + 10.0.1.99: "ns1out", | ||
6174 | + 10.0.2.99: "ns2out" } | ||
6175 | + } | ||
6176 | + | ||
6177 | + map nsoutcounter6 { | ||
6178 | + type ipv6_addr : counter | ||
6179 | + elements = { dead:1::1 : "ns0out6", | ||
6180 | + dead:2::1 : "ns0out6", | ||
6181 | + dead:1::99 : "ns1out6", | ||
6182 | + dead:2::99 : "ns2out6" } | ||
6183 | + } | ||
6184 | + | ||
6185 | + chain input { | ||
6186 | + type filter hook input priority 0; policy accept; | ||
6187 | + counter name ip saddr map @nsincounter | ||
6188 | + icmpv6 type { "echo-request", "echo-reply" } counter name ip6 saddr map @nsincounter6 | ||
6189 | + } | ||
6190 | + chain output { | ||
6191 | + type filter hook output priority 0; policy accept; | ||
6192 | + counter name ip daddr map @nsoutcounter | ||
6193 | + icmpv6 type { "echo-request", "echo-reply" } counter name ip6 daddr map @nsoutcounter6 | ||
6194 | + } | ||
6195 | +} | ||
6196 | +EOF | ||
6197 | +done | ||
6198 | + | ||
6199 | +sleep 3 | ||
6200 | +# test basic connectivity | ||
6201 | +for i in 1 2; do | ||
6202 | + ip netns exec ns0 ping -c 1 -q 10.0.$i.99 > /dev/null | ||
6203 | + if [ $? -ne 0 ];then | ||
6204 | + echo "ERROR: Could not reach other namespace(s)" 1>&2 | ||
6205 | + ret=1 | ||
6206 | + fi | ||
6207 | + | ||
6208 | + ip netns exec ns0 ping -c 1 -q dead:$i::99 > /dev/null | ||
6209 | + if [ $? -ne 0 ];then | ||
6210 | + echo "ERROR: Could not reach other namespace(s) via ipv6" 1>&2 | ||
6211 | + ret=1 | ||
6212 | + fi | ||
6213 | + check_counters ns$i | ||
6214 | + if [ $? -ne 0 ]; then | ||
6215 | + ret=1 | ||
6216 | + fi | ||
6217 | + | ||
6218 | + check_ns0_counters ns$i | ||
6219 | + if [ $? -ne 0 ]; then | ||
6220 | + ret=1 | ||
6221 | + fi | ||
6222 | + reset_counters | ||
6223 | +done | ||
6224 | + | ||
6225 | +if [ $ret -eq 0 ];then | ||
6226 | + echo "PASS: netns routing/connectivity: ns0 can reach ns1 and ns2" | ||
6227 | +fi | ||
6228 | + | ||
6229 | +reset_counters | ||
6230 | +test_local_dnat | ||
6231 | +test_local_dnat6 | ||
6232 | + | ||
6233 | +reset_counters | ||
6234 | +test_masquerade | ||
6235 | +test_masquerade6 | ||
6236 | + | ||
6237 | +reset_counters | ||
6238 | +test_redirect | ||
6239 | +test_redirect6 | ||
6240 | + | ||
6241 | +for i in 0 1 2; do ip netns del ns$i;done | ||
6242 | + | ||
6243 | +exit $ret | ||
6244 | diff --git a/tools/testing/selftests/proc/.gitignore b/tools/testing/selftests/proc/.gitignore | ||
6245 | index 82121a81681f..29bac5ef9a93 100644 | ||
6246 | --- a/tools/testing/selftests/proc/.gitignore | ||
6247 | +++ b/tools/testing/selftests/proc/.gitignore | ||
6248 | @@ -10,4 +10,5 @@ | ||
6249 | /proc-uptime-002 | ||
6250 | /read | ||
6251 | /self | ||
6252 | +/setns-dcache | ||
6253 | /thread-self | ||
6254 | diff --git a/tools/testing/selftests/proc/Makefile b/tools/testing/selftests/proc/Makefile | ||
6255 | index 1c12c34cf85d..434d033ee067 100644 | ||
6256 | --- a/tools/testing/selftests/proc/Makefile | ||
6257 | +++ b/tools/testing/selftests/proc/Makefile | ||
6258 | @@ -14,6 +14,7 @@ TEST_GEN_PROGS += proc-uptime-001 | ||
6259 | TEST_GEN_PROGS += proc-uptime-002 | ||
6260 | TEST_GEN_PROGS += read | ||
6261 | TEST_GEN_PROGS += self | ||
6262 | +TEST_GEN_PROGS += setns-dcache | ||
6263 | TEST_GEN_PROGS += thread-self | ||
6264 | |||
6265 | include ../lib.mk | ||
6266 | diff --git a/tools/testing/selftests/proc/setns-dcache.c b/tools/testing/selftests/proc/setns-dcache.c | ||
6267 | new file mode 100644 | ||
6268 | index 000000000000..60ab197a73fc | ||
6269 | --- /dev/null | ||
6270 | +++ b/tools/testing/selftests/proc/setns-dcache.c | ||
6271 | @@ -0,0 +1,129 @@ | ||
6272 | +/* | ||
6273 | + * Copyright © 2019 Alexey Dobriyan <adobriyan@gmail.com> | ||
6274 | + * | ||
6275 | + * Permission to use, copy, modify, and distribute this software for any | ||
6276 | + * purpose with or without fee is hereby granted, provided that the above | ||
6277 | + * copyright notice and this permission notice appear in all copies. | ||
6278 | + * | ||
6279 | + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
6280 | + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
6281 | + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
6282 | + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
6283 | + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
6284 | + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
6285 | + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
6286 | + */ | ||
6287 | +/* | ||
6288 | + * Test that setns(CLONE_NEWNET) points to new /proc/net content even | ||
6289 | + * if old one is in dcache. | ||
6290 | + * | ||
6291 | + * FIXME /proc/net/unix is under CONFIG_UNIX which can be disabled. | ||
6292 | + */ | ||
6293 | +#undef NDEBUG | ||
6294 | +#include <assert.h> | ||
6295 | +#include <errno.h> | ||
6296 | +#include <sched.h> | ||
6297 | +#include <signal.h> | ||
6298 | +#include <stdio.h> | ||
6299 | +#include <stdlib.h> | ||
6300 | +#include <string.h> | ||
6301 | +#include <unistd.h> | ||
6302 | +#include <sys/types.h> | ||
6303 | +#include <sys/stat.h> | ||
6304 | +#include <fcntl.h> | ||
6305 | +#include <sys/socket.h> | ||
6306 | + | ||
6307 | +static pid_t pid = -1; | ||
6308 | + | ||
6309 | +static void f(void) | ||
6310 | +{ | ||
6311 | + if (pid > 0) { | ||
6312 | + kill(pid, SIGTERM); | ||
6313 | + } | ||
6314 | +} | ||
6315 | + | ||
6316 | +int main(void) | ||
6317 | +{ | ||
6318 | + int fd[2]; | ||
6319 | + char _ = 0; | ||
6320 | + int nsfd; | ||
6321 | + | ||
6322 | + atexit(f); | ||
6323 | + | ||
6324 | + /* Check for priviledges and syscall availability straight away. */ | ||
6325 | + if (unshare(CLONE_NEWNET) == -1) { | ||
6326 | + if (errno == ENOSYS || errno == EPERM) { | ||
6327 | + return 4; | ||
6328 | + } | ||
6329 | + return 1; | ||
6330 | + } | ||
6331 | + /* Distinguisher between two otherwise empty net namespaces. */ | ||
6332 | + if (socket(AF_UNIX, SOCK_STREAM, 0) == -1) { | ||
6333 | + return 1; | ||
6334 | + } | ||
6335 | + | ||
6336 | + if (pipe(fd) == -1) { | ||
6337 | + return 1; | ||
6338 | + } | ||
6339 | + | ||
6340 | + pid = fork(); | ||
6341 | + if (pid == -1) { | ||
6342 | + return 1; | ||
6343 | + } | ||
6344 | + | ||
6345 | + if (pid == 0) { | ||
6346 | + if (unshare(CLONE_NEWNET) == -1) { | ||
6347 | + return 1; | ||
6348 | + } | ||
6349 | + | ||
6350 | + if (write(fd[1], &_, 1) != 1) { | ||
6351 | + return 1; | ||
6352 | + } | ||
6353 | + | ||
6354 | + pause(); | ||
6355 | + | ||
6356 | + return 0; | ||
6357 | + } | ||
6358 | + | ||
6359 | + if (read(fd[0], &_, 1) != 1) { | ||
6360 | + return 1; | ||
6361 | + } | ||
6362 | + | ||
6363 | + { | ||
6364 | + char buf[64]; | ||
6365 | + snprintf(buf, sizeof(buf), "/proc/%u/ns/net", pid); | ||
6366 | + nsfd = open(buf, O_RDONLY); | ||
6367 | + if (nsfd == -1) { | ||
6368 | + return 1; | ||
6369 | + } | ||
6370 | + } | ||
6371 | + | ||
6372 | + /* Reliably pin dentry into dcache. */ | ||
6373 | + (void)open("/proc/net/unix", O_RDONLY); | ||
6374 | + | ||
6375 | + if (setns(nsfd, CLONE_NEWNET) == -1) { | ||
6376 | + return 1; | ||
6377 | + } | ||
6378 | + | ||
6379 | + kill(pid, SIGTERM); | ||
6380 | + pid = 0; | ||
6381 | + | ||
6382 | + { | ||
6383 | + char buf[4096]; | ||
6384 | + ssize_t rv; | ||
6385 | + int fd; | ||
6386 | + | ||
6387 | + fd = open("/proc/net/unix", O_RDONLY); | ||
6388 | + if (fd == -1) { | ||
6389 | + return 1; | ||
6390 | + } | ||
6391 | + | ||
6392 | +#define S "Num RefCount Protocol Flags Type St Inode Path\n" | ||
6393 | + rv = read(fd, buf, sizeof(buf)); | ||
6394 | + | ||
6395 | + assert(rv == strlen(S)); | ||
6396 | + assert(memcmp(buf, S, strlen(S)) == 0); | ||
6397 | + } | ||
6398 | + | ||
6399 | + return 0; | ||
6400 | +} | ||
6401 | diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile | ||
6402 | index c02683cfb6c9..7656c7ce79d9 100644 | ||
6403 | --- a/tools/testing/selftests/timers/Makefile | ||
6404 | +++ b/tools/testing/selftests/timers/Makefile | ||
6405 | @@ -1,6 +1,6 @@ | ||
6406 | # SPDX-License-Identifier: GPL-2.0 | ||
6407 | CFLAGS += -O3 -Wl,-no-as-needed -Wall | ||
6408 | -LDFLAGS += -lrt -lpthread -lm | ||
6409 | +LDLIBS += -lrt -lpthread -lm | ||
6410 | |||
6411 | # these are all "safe" tests that don't modify | ||
6412 | # system time or require escalated privileges |