From e612895fed92c7c72de7857839034e5d433c7df2 Mon Sep 17 00:00:00 2001 From: Julian Sikorski Date: Wed, 27 Dec 2023 12:41:08 +0000 Subject: [PATCH] Update odroidxu4-current to 6.1.69 --- .../odroidxu4-current/patch-6.1.67-68.patch | 9166 +++++++++++++++++ .../odroidxu4-current/patch-6.1.68-69.patch | 4110 ++++++++ 2 files changed, 13276 insertions(+) create mode 100644 patch/kernel/odroidxu4-current/patch-6.1.67-68.patch create mode 100644 patch/kernel/odroidxu4-current/patch-6.1.68-69.patch diff --git a/patch/kernel/odroidxu4-current/patch-6.1.67-68.patch b/patch/kernel/odroidxu4-current/patch-6.1.67-68.patch new file mode 100644 index 0000000000..78edec2836 --- /dev/null +++ b/patch/kernel/odroidxu4-current/patch-6.1.67-68.patch @@ -0,0 +1,9166 @@ +diff --git a/Documentation/ABI/testing/sysfs-bus-optee-devices b/Documentation/ABI/testing/sysfs-bus-optee-devices +index 0f58701367b66..af31e5a22d89f 100644 +--- a/Documentation/ABI/testing/sysfs-bus-optee-devices ++++ b/Documentation/ABI/testing/sysfs-bus-optee-devices +@@ -6,3 +6,12 @@ Description: + OP-TEE bus provides reference to registered drivers under this directory. The + matches Trusted Application (TA) driver and corresponding TA in secure OS. Drivers + are free to create needed API under optee-ta- directory. ++ ++What: /sys/bus/tee/devices/optee-ta-/need_supplicant ++Date: November 2023 ++KernelVersion: 6.7 ++Contact: op-tee@lists.trustedfirmware.org ++Description: ++ Allows to distinguish whether an OP-TEE based TA/device requires user-space ++ tee-supplicant to function properly or not. This attribute will be present for ++ devices which depend on tee-supplicant to be running. +diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml +index 509d20c091af8..6a206111d4e0f 100644 +--- a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml ++++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml +@@ -62,6 +62,9 @@ properties: + - description: MPM pin number + - description: GIC SPI number for the MPM pin + ++ '#power-domain-cells': ++ const: 0 ++ + required: + - compatible + - reg +@@ -93,4 +96,5 @@ examples: + <86 183>, + <90 260>, + <91 260>; ++ #power-domain-cells = <0>; + }; +diff --git a/Makefile b/Makefile +index c27600b90cad2..2a8ad0cec2f1c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 1 +-SUBLEVEL = 67 ++SUBLEVEL = 68 + EXTRAVERSION = + NAME = Curry Ramen + +diff --git a/arch/arm/boot/dts/imx28-xea.dts b/arch/arm/boot/dts/imx28-xea.dts +index a400c108f66a2..6c5e6856648af 100644 +--- a/arch/arm/boot/dts/imx28-xea.dts ++++ b/arch/arm/boot/dts/imx28-xea.dts +@@ -8,6 +8,7 @@ + #include "imx28-lwe.dtsi" + + / { ++ model = "Liebherr XEA board"; + compatible = "lwn,imx28-xea", "fsl,imx28"; + }; + +diff --git a/arch/arm/boot/dts/imx6ul-pico.dtsi b/arch/arm/boot/dts/imx6ul-pico.dtsi +index 357ffb2f5ad61..dd6790852b0d6 100644 +--- a/arch/arm/boot/dts/imx6ul-pico.dtsi ++++ b/arch/arm/boot/dts/imx6ul-pico.dtsi +@@ -121,6 +121,8 @@ + max-speed = <100>; + interrupt-parent = <&gpio5>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&clks IMX6UL_CLK_ENET_REF>; ++ clock-names = "rmii-ref"; + }; + }; + }; +diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi +index 667568aa4326a..45947707134b8 100644 +--- a/arch/arm/boot/dts/imx7s.dtsi ++++ b/arch/arm/boot/dts/imx7s.dtsi +@@ -454,7 +454,7 @@ + }; + + gpt1: timer@302d0000 { +- compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; ++ compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; + reg = <0x302d0000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_GPT1_ROOT_CLK>, +@@ -463,7 +463,7 @@ + }; + + gpt2: timer@302e0000 { +- compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; ++ compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; + reg = <0x302e0000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_GPT2_ROOT_CLK>, +@@ -473,7 +473,7 @@ + }; + + gpt3: timer@302f0000 { +- compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; ++ compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; + reg = <0x302f0000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_GPT3_ROOT_CLK>, +@@ -483,7 +483,7 @@ + }; + + gpt4: timer@30300000 { +- compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; ++ compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; + reg = <0x30300000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_GPT4_ROOT_CLK>, +diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c +index b9efe9da06e0b..3d76e8c28c51d 100644 +--- a/arch/arm/mach-imx/mmdc.c ++++ b/arch/arm/mach-imx/mmdc.c +@@ -502,6 +502,10 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b + + name = devm_kasprintf(&pdev->dev, + GFP_KERNEL, "mmdc%d", ret); ++ if (!name) { ++ ret = -ENOMEM; ++ goto pmu_release_id; ++ } + + pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk; + pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data; +@@ -524,9 +528,10 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b + + pmu_register_err: + pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret); +- ida_simple_remove(&mmdc_ida, pmu_mmdc->id); + cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); + hrtimer_cancel(&pmu_mmdc->hrtimer); ++pmu_release_id: ++ ida_simple_remove(&mmdc_ida, pmu_mmdc->id); + pmu_free: + kfree(pmu_mmdc); + return ret; +diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +index 25630a395db56..8c34b3e12a66a 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +@@ -1301,6 +1301,7 @@ + phys = <&usb3_phy0>, <&usb3_phy0>; + phy-names = "usb2-phy", "usb3-phy"; + snps,gfladj-refclk-lpm-sel-quirk; ++ snps,parkmode-disable-ss-quirk; + }; + + }; +@@ -1343,6 +1344,7 @@ + phys = <&usb3_phy1>, <&usb3_phy1>; + phy-names = "usb2-phy", "usb3-phy"; + snps,gfladj-refclk-lpm-sel-quirk; ++ snps,parkmode-disable-ss-quirk; + }; + }; + +diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi +index bf8f02c1535c1..e642cb7d54d77 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi +@@ -1431,7 +1431,7 @@ + phys = <&usb3_phy0>, <&usb3_phy0>; + phy-names = "usb2-phy", "usb3-phy"; + power-domains = <&pgc_otg1>; +- usb3-resume-missing-cas; ++ snps,parkmode-disable-ss-quirk; + status = "disabled"; + }; + +@@ -1463,7 +1463,7 @@ + phys = <&usb3_phy1>, <&usb3_phy1>; + phy-names = "usb2-phy", "usb3-phy"; + power-domains = <&pgc_otg2>; +- usb3-resume-missing-cas; ++ snps,parkmode-disable-ss-quirk; + status = "disabled"; + }; + +diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +index d3f9eab2b7844..2c35ed0734a47 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -72,7 +72,7 @@ + }; + }; + +- memory { ++ memory@40000000 { + reg = <0 0x40000000 0 0x40000000>; + }; + +diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +index 36722cabe626e..f9313b697ac12 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +@@ -54,7 +54,7 @@ + }; + }; + +- memory { ++ memory@40000000 { + reg = <0 0x40000000 0 0x20000000>; + }; + +diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +index 0b5f154007be8..49c7185243cc1 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +@@ -43,7 +43,7 @@ + id-gpio = <&pio 16 GPIO_ACTIVE_HIGH>; + }; + +- usb_p1_vbus: regulator@0 { ++ usb_p1_vbus: regulator-usb-p1 { + compatible = "regulator-fixed"; + regulator-name = "usb_vbus"; + regulator-min-microvolt = <5000000>; +@@ -52,7 +52,7 @@ + enable-active-high; + }; + +- usb_p0_vbus: regulator@1 { ++ usb_p0_vbus: regulator-usb-p0 { + compatible = "regulator-fixed"; + regulator-name = "vbus"; + regulator-min-microvolt = <5000000>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts +index 52dc4a50e34d3..2ca0da51efaa0 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts +@@ -30,14 +30,14 @@ + #address-cells = <2>; + #size-cells = <2>; + ranges; +- scp_mem_reserved: scp_mem_region { ++ scp_mem_reserved: memory@50000000 { + compatible = "shared-dma-pool"; + reg = <0 0x50000000 0 0x2900000>; + no-map; + }; + }; + +- ntc@0 { ++ thermal-sensor { + compatible = "murata,ncp03wf104"; + pullup-uv = <1800000>; + pullup-ohm = <390000>; +@@ -139,8 +139,8 @@ + }; + + &pio { +- i2c_pins_0: i2c0{ +- pins_i2c{ ++ i2c_pins_0: i2c0 { ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -148,8 +148,8 @@ + }; + }; + +- i2c_pins_1: i2c1{ +- pins_i2c{ ++ i2c_pins_1: i2c1 { ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -157,8 +157,8 @@ + }; + }; + +- i2c_pins_2: i2c2{ +- pins_i2c{ ++ i2c_pins_2: i2c2 { ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -166,8 +166,8 @@ + }; + }; + +- i2c_pins_3: i2c3{ +- pins_i2c{ ++ i2c_pins_3: i2c3 { ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -175,8 +175,8 @@ + }; + }; + +- i2c_pins_4: i2c4{ +- pins_i2c{ ++ i2c_pins_4: i2c4 { ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -184,8 +184,8 @@ + }; + }; + +- i2c_pins_5: i2c5{ +- pins_i2c{ ++ i2c_pins_5: i2c5 { ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -193,8 +193,8 @@ + }; + }; + +- spi_pins_0: spi0{ +- pins_spi{ ++ spi_pins_0: spi0 { ++ pins_spi { + pinmux = , + , + , +@@ -308,8 +308,8 @@ + }; + }; + +- spi_pins_1: spi1{ +- pins_spi{ ++ spi_pins_1: spi1 { ++ pins_spi { + pinmux = , + , + , +@@ -318,8 +318,8 @@ + }; + }; + +- spi_pins_2: spi2{ +- pins_spi{ ++ spi_pins_2: spi2 { ++ pins_spi { + pinmux = , + , + , +@@ -328,8 +328,8 @@ + }; + }; + +- spi_pins_3: spi3{ +- pins_spi{ ++ spi_pins_3: spi3 { ++ pins_spi { + pinmux = , + , + , +@@ -338,8 +338,8 @@ + }; + }; + +- spi_pins_4: spi4{ +- pins_spi{ ++ spi_pins_4: spi4 { ++ pins_spi { + pinmux = , + , + , +@@ -348,8 +348,8 @@ + }; + }; + +- spi_pins_5: spi5{ +- pins_spi{ ++ spi_pins_5: spi5 { ++ pins_spi { + pinmux = , + , + , +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi +index 3ac83be536274..dccf367c7ec6c 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi +@@ -101,6 +101,8 @@ + + &dsi0 { + status = "okay"; ++ /delete-property/#size-cells; ++ /delete-property/#address-cells; + /delete-node/panel@0; + ports { + port { +@@ -437,20 +439,20 @@ + }; + + touchscreen_pins: touchscreen-pins { +- touch_int_odl { ++ touch-int-odl { + pinmux = ; + input-enable; + bias-pull-up; + }; + +- touch_rst_l { ++ touch-rst-l { + pinmux = ; + output-high; + }; + }; + + trackpad_pins: trackpad-pins { +- trackpad_int { ++ trackpad-int { + pinmux = ; + input-enable; + bias-disable; /* pulled externally */ +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +index 632fd89e75969..a428a581c93a8 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +@@ -108,7 +108,7 @@ + #size-cells = <2>; + ranges; + +- scp_mem_reserved: scp_mem_region { ++ scp_mem_reserved: memory@50000000 { + compatible = "shared-dma-pool"; + reg = <0 0x50000000 0 0x2900000>; + no-map; +@@ -423,7 +423,7 @@ + + &pio { + aud_pins_default: audiopins { +- pins_bus { ++ pins-bus { + pinmux = , + , + , +@@ -445,7 +445,7 @@ + }; + + aud_pins_tdm_out_on: audiotdmouton { +- pins_bus { ++ pins-bus { + pinmux = , + , + , +@@ -457,7 +457,7 @@ + }; + + aud_pins_tdm_out_off: audiotdmoutoff { +- pins_bus { ++ pins-bus { + pinmux = , + , + , +@@ -471,13 +471,13 @@ + }; + + bt_pins: bt-pins { +- pins_bt_en { ++ pins-bt-en { + pinmux = ; + output-low; + }; + }; + +- ec_ap_int_odl: ec_ap_int_odl { ++ ec_ap_int_odl: ec-ap-int-odl { + pins1 { + pinmux = ; + input-enable; +@@ -485,7 +485,7 @@ + }; + }; + +- h1_int_od_l: h1_int_od_l { ++ h1_int_od_l: h1-int-od-l { + pins1 { + pinmux = ; + input-enable; +@@ -493,7 +493,7 @@ + }; + + i2c0_pins: i2c0 { +- pins_bus { ++ pins-bus { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -502,7 +502,7 @@ + }; + + i2c1_pins: i2c1 { +- pins_bus { ++ pins-bus { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -511,7 +511,7 @@ + }; + + i2c2_pins: i2c2 { +- pins_bus { ++ pins-bus { + pinmux = , + ; + bias-disable; +@@ -520,7 +520,7 @@ + }; + + i2c3_pins: i2c3 { +- pins_bus { ++ pins-bus { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -529,7 +529,7 @@ + }; + + i2c4_pins: i2c4 { +- pins_bus { ++ pins-bus { + pinmux = , + ; + bias-disable; +@@ -538,7 +538,7 @@ + }; + + i2c5_pins: i2c5 { +- pins_bus { ++ pins-bus { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -547,7 +547,7 @@ + }; + + i2c6_pins: i2c6 { +- pins_bus { ++ pins-bus { + pinmux = , + ; + bias-disable; +@@ -555,7 +555,7 @@ + }; + + mmc0_pins_default: mmc0-pins-default { +- pins_cmd_dat { ++ pins-cmd-dat { + pinmux = , + , + , +@@ -570,13 +570,13 @@ + mediatek,pull-up-adv = <01>; + }; + +- pins_clk { ++ pins-clk { + pinmux = ; + drive-strength = ; + mediatek,pull-down-adv = <10>; + }; + +- pins_rst { ++ pins-rst { + pinmux = ; + drive-strength = ; + mediatek,pull-down-adv = <01>; +@@ -584,7 +584,7 @@ + }; + + mmc0_pins_uhs: mmc0-pins-uhs { +- pins_cmd_dat { ++ pins-cmd-dat { + pinmux = , + , + , +@@ -599,19 +599,19 @@ + mediatek,pull-up-adv = <01>; + }; + +- pins_clk { ++ pins-clk { + pinmux = ; + drive-strength = ; + mediatek,pull-down-adv = <10>; + }; + +- pins_ds { ++ pins-ds { + pinmux = ; + drive-strength = ; + mediatek,pull-down-adv = <10>; + }; + +- pins_rst { ++ pins-rst { + pinmux = ; + drive-strength = ; + mediatek,pull-up-adv = <01>; +@@ -619,7 +619,7 @@ + }; + + mmc1_pins_default: mmc1-pins-default { +- pins_cmd_dat { ++ pins-cmd-dat { + pinmux = , + , + , +@@ -629,7 +629,7 @@ + mediatek,pull-up-adv = <10>; + }; + +- pins_clk { ++ pins-clk { + pinmux = ; + input-enable; + mediatek,pull-down-adv = <10>; +@@ -637,7 +637,7 @@ + }; + + mmc1_pins_uhs: mmc1-pins-uhs { +- pins_cmd_dat { ++ pins-cmd-dat { + pinmux = , + , + , +@@ -648,7 +648,7 @@ + mediatek,pull-up-adv = <10>; + }; + +- pins_clk { ++ pins-clk { + pinmux = ; + drive-strength = ; + mediatek,pull-down-adv = <10>; +@@ -656,15 +656,15 @@ + }; + }; + +- panel_pins_default: panel_pins_default { +- panel_reset { ++ panel_pins_default: panel-pins-default { ++ panel-reset { + pinmux = ; + output-low; + bias-pull-up; + }; + }; + +- pwm0_pin_default: pwm0_pin_default { ++ pwm0_pin_default: pwm0-pin-default { + pins1 { + pinmux = ; + output-high; +@@ -676,14 +676,14 @@ + }; + + scp_pins: scp { +- pins_scp_uart { ++ pins-scp-uart { + pinmux = , + ; + }; + }; + + spi0_pins: spi0 { +- pins_spi{ ++ pins-spi { + pinmux = , + , + , +@@ -693,7 +693,7 @@ + }; + + spi1_pins: spi1 { +- pins_spi{ ++ pins-spi { + pinmux = , + , + , +@@ -703,20 +703,20 @@ + }; + + spi2_pins: spi2 { +- pins_spi{ ++ pins-spi { + pinmux = , + , + ; + bias-disable; + }; +- pins_spi_mi { ++ pins-spi-mi { + pinmux = ; + mediatek,pull-down-adv = <00>; + }; + }; + + spi3_pins: spi3 { +- pins_spi{ ++ pins-spi { + pinmux = , + , + , +@@ -726,7 +726,7 @@ + }; + + spi4_pins: spi4 { +- pins_spi{ ++ pins-spi { + pinmux = , + , + , +@@ -736,7 +736,7 @@ + }; + + spi5_pins: spi5 { +- pins_spi{ ++ pins-spi { + pinmux = , + , + , +@@ -746,63 +746,63 @@ + }; + + uart0_pins_default: uart0-pins-default { +- pins_rx { ++ pins-rx { + pinmux = ; + input-enable; + bias-pull-up; + }; +- pins_tx { ++ pins-tx { + pinmux = ; + }; + }; + + uart1_pins_default: uart1-pins-default { +- pins_rx { ++ pins-rx { + pinmux = ; + input-enable; + bias-pull-up; + }; +- pins_tx { ++ pins-tx { + pinmux = ; + }; +- pins_rts { ++ pins-rts { + pinmux = ; + output-enable; + }; +- pins_cts { ++ pins-cts { + pinmux = ; + input-enable; + }; + }; + + uart1_pins_sleep: uart1-pins-sleep { +- pins_rx { ++ pins-rx { + pinmux = ; + input-enable; + bias-pull-up; + }; +- pins_tx { ++ pins-tx { + pinmux = ; + }; +- pins_rts { ++ pins-rts { + pinmux = ; + output-enable; + }; +- pins_cts { ++ pins-cts { + pinmux = ; + input-enable; + }; + }; + + wifi_pins_pwrseq: wifi-pins-pwrseq { +- pins_wifi_enable { ++ pins-wifi-enable { + pinmux = ; + output-low; + }; + }; + + wifi_pins_wakeup: wifi-pins-wakeup { +- pins_wifi_wakeup { ++ pins-wifi-wakeup { + pinmux = ; + input-enable; + }; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts +index a1d01639df30a..dd8d39861d9ca 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts +@@ -178,7 +178,7 @@ + + &pio { + i2c_pins_0: i2c0 { +- pins_i2c{ ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -187,7 +187,7 @@ + }; + + i2c_pins_1: i2c1 { +- pins_i2c{ ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -196,7 +196,7 @@ + }; + + i2c_pins_2: i2c2 { +- pins_i2c{ ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -205,7 +205,7 @@ + }; + + i2c_pins_3: i2c3 { +- pins_i2c{ ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -214,7 +214,7 @@ + }; + + i2c_pins_4: i2c4 { +- pins_i2c{ ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +@@ -223,7 +223,7 @@ + }; + + i2c_pins_5: i2c5 { +- pins_i2c{ ++ pins_i2c { + pinmux = , + ; + mediatek,pull-up-adv = <3>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +index 268a1f28af8ce..10779a9947fe2 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +@@ -1136,127 +1136,6 @@ + nvmem-cell-names = "calibration-data"; + }; + +- thermal_zones: thermal-zones { +- cpu_thermal: cpu-thermal { +- polling-delay-passive = <100>; +- polling-delay = <500>; +- thermal-sensors = <&thermal 0>; +- sustainable-power = <5000>; +- +- trips { +- threshold: trip-point0 { +- temperature = <68000>; +- hysteresis = <2000>; +- type = "passive"; +- }; +- +- target: trip-point1 { +- temperature = <80000>; +- hysteresis = <2000>; +- type = "passive"; +- }; +- +- cpu_crit: cpu-crit { +- temperature = <115000>; +- hysteresis = <2000>; +- type = "critical"; +- }; +- }; +- +- cooling-maps { +- map0 { +- trip = <&target>; +- cooling-device = <&cpu0 +- THERMAL_NO_LIMIT +- THERMAL_NO_LIMIT>, +- <&cpu1 +- THERMAL_NO_LIMIT +- THERMAL_NO_LIMIT>, +- <&cpu2 +- THERMAL_NO_LIMIT +- THERMAL_NO_LIMIT>, +- <&cpu3 +- THERMAL_NO_LIMIT +- THERMAL_NO_LIMIT>; +- contribution = <3072>; +- }; +- map1 { +- trip = <&target>; +- cooling-device = <&cpu4 +- THERMAL_NO_LIMIT +- THERMAL_NO_LIMIT>, +- <&cpu5 +- THERMAL_NO_LIMIT +- THERMAL_NO_LIMIT>, +- <&cpu6 +- THERMAL_NO_LIMIT +- THERMAL_NO_LIMIT>, +- <&cpu7 +- THERMAL_NO_LIMIT +- THERMAL_NO_LIMIT>; +- contribution = <1024>; +- }; +- }; +- }; +- +- /* The tzts1 ~ tzts6 don't need to polling */ +- /* The tzts1 ~ tzts6 don't need to thermal throttle */ +- +- tzts1: tzts1 { +- polling-delay-passive = <0>; +- polling-delay = <0>; +- thermal-sensors = <&thermal 1>; +- sustainable-power = <5000>; +- trips {}; +- cooling-maps {}; +- }; +- +- tzts2: tzts2 { +- polling-delay-passive = <0>; +- polling-delay = <0>; +- thermal-sensors = <&thermal 2>; +- sustainable-power = <5000>; +- trips {}; +- cooling-maps {}; +- }; +- +- tzts3: tzts3 { +- polling-delay-passive = <0>; +- polling-delay = <0>; +- thermal-sensors = <&thermal 3>; +- sustainable-power = <5000>; +- trips {}; +- cooling-maps {}; +- }; +- +- tzts4: tzts4 { +- polling-delay-passive = <0>; +- polling-delay = <0>; +- thermal-sensors = <&thermal 4>; +- sustainable-power = <5000>; +- trips {}; +- cooling-maps {}; +- }; +- +- tzts5: tzts5 { +- polling-delay-passive = <0>; +- polling-delay = <0>; +- thermal-sensors = <&thermal 5>; +- sustainable-power = <5000>; +- trips {}; +- cooling-maps {}; +- }; +- +- tztsABB: tztsABB { +- polling-delay-passive = <0>; +- polling-delay = <0>; +- thermal-sensors = <&thermal 6>; +- sustainable-power = <5000>; +- trips {}; +- cooling-maps {}; +- }; +- }; +- + pwm0: pwm@1100e000 { + compatible = "mediatek,mt8183-disp-pwm"; + reg = <0 0x1100e000 0 0x1000>; +@@ -2031,4 +1910,125 @@ + power-domains = <&spm MT8183_POWER_DOMAIN_CAM>; + }; + }; ++ ++ thermal_zones: thermal-zones { ++ cpu_thermal: cpu-thermal { ++ polling-delay-passive = <100>; ++ polling-delay = <500>; ++ thermal-sensors = <&thermal 0>; ++ sustainable-power = <5000>; ++ ++ trips { ++ threshold: trip-point0 { ++ temperature = <68000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ target: trip-point1 { ++ temperature = <80000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cpu_crit: cpu-crit { ++ temperature = <115000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&target>; ++ cooling-device = <&cpu0 ++ THERMAL_NO_LIMIT ++ THERMAL_NO_LIMIT>, ++ <&cpu1 ++ THERMAL_NO_LIMIT ++ THERMAL_NO_LIMIT>, ++ <&cpu2 ++ THERMAL_NO_LIMIT ++ THERMAL_NO_LIMIT>, ++ <&cpu3 ++ THERMAL_NO_LIMIT ++ THERMAL_NO_LIMIT>; ++ contribution = <3072>; ++ }; ++ map1 { ++ trip = <&target>; ++ cooling-device = <&cpu4 ++ THERMAL_NO_LIMIT ++ THERMAL_NO_LIMIT>, ++ <&cpu5 ++ THERMAL_NO_LIMIT ++ THERMAL_NO_LIMIT>, ++ <&cpu6 ++ THERMAL_NO_LIMIT ++ THERMAL_NO_LIMIT>, ++ <&cpu7 ++ THERMAL_NO_LIMIT ++ THERMAL_NO_LIMIT>; ++ contribution = <1024>; ++ }; ++ }; ++ }; ++ ++ /* The tzts1 ~ tzts6 don't need to polling */ ++ /* The tzts1 ~ tzts6 don't need to thermal throttle */ ++ ++ tzts1: tzts1 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&thermal 1>; ++ sustainable-power = <5000>; ++ trips {}; ++ cooling-maps {}; ++ }; ++ ++ tzts2: tzts2 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&thermal 2>; ++ sustainable-power = <5000>; ++ trips {}; ++ cooling-maps {}; ++ }; ++ ++ tzts3: tzts3 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&thermal 3>; ++ sustainable-power = <5000>; ++ trips {}; ++ cooling-maps {}; ++ }; ++ ++ tzts4: tzts4 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&thermal 4>; ++ sustainable-power = <5000>; ++ trips {}; ++ cooling-maps {}; ++ }; ++ ++ tzts5: tzts5 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&thermal 5>; ++ sustainable-power = <5000>; ++ trips {}; ++ cooling-maps {}; ++ }; ++ ++ tztsABB: tztsABB { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&thermal 6>; ++ sustainable-power = <5000>; ++ trips {}; ++ cooling-maps {}; ++ }; ++ }; + }; +diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi +index 9b62e161db261..4b8a1c462906e 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi +@@ -207,7 +207,7 @@ + pinctrl-0 = <&i2c7_pins>; + + pmic@34 { +- #interrupt-cells = <1>; ++ #interrupt-cells = <2>; + compatible = "mediatek,mt6360"; + reg = <0x34>; + interrupt-controller; +diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +index ef2764a595eda..414cbe3451270 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +@@ -471,6 +471,8 @@ + + power-domain@MT8195_POWER_DOMAIN_VENC_CORE1 { + reg = ; ++ clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>; ++ clock-names = "venc1-larb"; + mediatek,infracfg = <&infracfg_ao>; + #power-domain-cells = <0>; + }; +@@ -533,6 +535,8 @@ + + power-domain@MT8195_POWER_DOMAIN_VENC { + reg = ; ++ clocks = <&vencsys CLK_VENC_LARB>; ++ clock-names = "venc0-larb"; + mediatek,infracfg = <&infracfg_ao>; + #power-domain-cells = <0>; + }; +@@ -1985,7 +1989,7 @@ + reg = <0 0x1b010000 0 0x1000>; + mediatek,larb-id = <20>; + mediatek,smi = <&smi_common_vpp>; +- clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>, ++ clocks = <&vencsys_core1 CLK_VENC_CORE1_VENC>, + <&vencsys_core1 CLK_VENC_CORE1_GALS>, + <&vppsys0 CLK_VPP0_GALS_VDO0_VDO1_VENCSYS_CORE1>; + clock-names = "apb", "smi", "gals"; +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 49ae15708a0b6..905a50aa5dc38 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -666,7 +666,7 @@ + + vdec: video-codec@ff360000 { + compatible = "rockchip,rk3328-vdec", "rockchip,rk3399-vdec"; +- reg = <0x0 0xff360000 0x0 0x400>; ++ reg = <0x0 0xff360000 0x0 0x480>; + interrupts = ; + clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>, + <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +index 5f3caf01badeb..a7e6eccb14cc6 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -1062,7 +1062,9 @@ + power-domain@RK3399_PD_VDU { + reg = ; + clocks = <&cru ACLK_VDU>, +- <&cru HCLK_VDU>; ++ <&cru HCLK_VDU>, ++ <&cru SCLK_VDU_CA>, ++ <&cru SCLK_VDU_CORE>; + pm_qos = <&qos_video_m1_r>, + <&qos_video_m1_w>; + #power-domain-cells = <0>; +@@ -1338,7 +1340,7 @@ + + vdec: video-codec@ff660000 { + compatible = "rockchip,rk3399-vdec"; +- reg = <0x0 0xff660000 0x0 0x400>; ++ reg = <0x0 0xff660000 0x0 0x480>; + interrupts = ; + clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>, + <&cru SCLK_VDU_CA>, <&cru SCLK_VDU_CORE>; +diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c +index 82b4402810da0..40ed49d9adff5 100644 +--- a/arch/loongarch/net/bpf_jit.c ++++ b/arch/loongarch/net/bpf_jit.c +@@ -796,8 +796,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext + + /* function return */ + case BPF_JMP | BPF_EXIT: +- emit_sext_32(ctx, regmap[BPF_REG_0], true); +- + if (i == ctx->prog->len - 1) + break; + +@@ -844,14 +842,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext + } + break; + case BPF_DW: +- if (is_signed_imm12(off)) { +- emit_insn(ctx, ldd, dst, src, off); +- } else if (is_signed_imm14(off)) { +- emit_insn(ctx, ldptrd, dst, src, off); +- } else { +- move_imm(ctx, t1, off, is32); +- emit_insn(ctx, ldxd, dst, src, t1); +- } ++ move_imm(ctx, t1, off, is32); ++ emit_insn(ctx, ldxd, dst, src, t1); + break; + } + break; +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index 0e62f5edaee2e..585783c9907ef 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -483,6 +483,7 @@ config MACH_LOONGSON2EF + + config MACH_LOONGSON64 + bool "Loongson 64-bit family of machines" ++ select ARCH_DMA_DEFAULT_COHERENT + select ARCH_SPARSEMEM_ENABLE + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_MIGHT_HAVE_PC_SERIO +@@ -1304,6 +1305,7 @@ config CPU_LOONGSON64 + select CPU_SUPPORTS_MSA + select CPU_DIEI_BROKEN if !LOONGSON3_ENHANCEMENT + select CPU_MIPSR2_IRQ_VI ++ select DMA_NONCOHERENT + select WEAK_ORDERING + select WEAK_REORDERING_BEYOND_LLSC + select MIPS_ASID_BITS_VARIABLE +diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h +index 035b1a69e2d00..e007edd6b60a7 100644 +--- a/arch/mips/include/asm/mach-loongson64/boot_param.h ++++ b/arch/mips/include/asm/mach-loongson64/boot_param.h +@@ -14,7 +14,11 @@ + #define ADAPTER_ROM 8 + #define ACPI_TABLE 9 + #define SMBIOS_TABLE 10 +-#define MAX_MEMORY_TYPE 11 ++#define UMA_VIDEO_RAM 11 ++#define VUMA_VIDEO_RAM 12 ++#define MAX_MEMORY_TYPE 13 ++ ++#define MEM_SIZE_IS_IN_BYTES (1 << 31) + + #define LOONGSON3_BOOT_MEM_MAP_MAX 128 + struct efi_memory_map_loongson { +@@ -117,7 +121,8 @@ struct irq_source_routing_table { + u64 pci_io_start_addr; + u64 pci_io_end_addr; + u64 pci_config_addr; +- u32 dma_mask_bits; ++ u16 dma_mask_bits; ++ u16 dma_noncoherent; + } __packed; + + struct interface_info { +diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c +index bbe9ce471791e..17d80e2f2e4cb 100644 +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -121,6 +121,19 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) + /* Put the stack after the struct pt_regs. */ + childksp = (unsigned long) childregs; + p->thread.cp0_status = (read_c0_status() & ~(ST0_CU2|ST0_CU1)) | ST0_KERNEL_CUMASK; ++ ++ /* ++ * New tasks lose permission to use the fpu. This accelerates context ++ * switching for most programs since they don't use the fpu. ++ */ ++ clear_tsk_thread_flag(p, TIF_USEDFPU); ++ clear_tsk_thread_flag(p, TIF_USEDMSA); ++ clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE); ++ ++#ifdef CONFIG_MIPS_MT_FPAFF ++ clear_tsk_thread_flag(p, TIF_FPUBOUND); ++#endif /* CONFIG_MIPS_MT_FPAFF */ ++ + if (unlikely(args->fn)) { + /* kernel thread */ + unsigned long status = p->thread.cp0_status; +@@ -149,20 +162,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) + p->thread.reg29 = (unsigned long) childregs; + p->thread.reg31 = (unsigned long) ret_from_fork; + +- /* +- * New tasks lose permission to use the fpu. This accelerates context +- * switching for most programs since they don't use the fpu. +- */ + childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); + +- clear_tsk_thread_flag(p, TIF_USEDFPU); +- clear_tsk_thread_flag(p, TIF_USEDMSA); +- clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE); +- +-#ifdef CONFIG_MIPS_MT_FPAFF +- clear_tsk_thread_flag(p, TIF_FPUBOUND); +-#endif /* CONFIG_MIPS_MT_FPAFF */ +- + #ifdef CONFIG_MIPS_FP_SUPPORT + atomic_set(&p->thread.bd_emu_frame, BD_EMUFRAME_NONE); + #endif +diff --git a/arch/mips/loongson64/env.c b/arch/mips/loongson64/env.c +index c961e2999f15a..ef3750a6ffacf 100644 +--- a/arch/mips/loongson64/env.c ++++ b/arch/mips/loongson64/env.c +@@ -13,6 +13,8 @@ + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + */ ++ ++#include + #include + #include + #include +@@ -147,8 +149,14 @@ void __init prom_lefi_init_env(void) + + loongson_sysconf.dma_mask_bits = eirq_source->dma_mask_bits; + if (loongson_sysconf.dma_mask_bits < 32 || +- loongson_sysconf.dma_mask_bits > 64) ++ loongson_sysconf.dma_mask_bits > 64) { + loongson_sysconf.dma_mask_bits = 32; ++ dma_default_coherent = true; ++ } else { ++ dma_default_coherent = !eirq_source->dma_noncoherent; ++ } ++ ++ pr_info("Firmware: Coherent DMA: %s\n", dma_default_coherent ? "on" : "off"); + + loongson_sysconf.restart_addr = boot_p->reset_system.ResetWarm; + loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown; +diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c +index ee8de1735b7c0..f25caa6aa9d30 100644 +--- a/arch/mips/loongson64/init.c ++++ b/arch/mips/loongson64/init.c +@@ -49,8 +49,7 @@ void virtual_early_config(void) + void __init szmem(unsigned int node) + { + u32 i, mem_type; +- static unsigned long num_physpages; +- u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size; ++ phys_addr_t node_id, mem_start, mem_size; + + /* Otherwise come from DTB */ + if (loongson_sysconf.fw_interface != LOONGSON_LEFI) +@@ -64,30 +63,46 @@ void __init szmem(unsigned int node) + + mem_type = loongson_memmap->map[i].mem_type; + mem_size = loongson_memmap->map[i].mem_size; +- mem_start = loongson_memmap->map[i].mem_start; ++ ++ /* Memory size comes in MB if MEM_SIZE_IS_IN_BYTES not set */ ++ if (mem_size & MEM_SIZE_IS_IN_BYTES) ++ mem_size &= ~MEM_SIZE_IS_IN_BYTES; ++ else ++ mem_size = mem_size << 20; ++ ++ mem_start = (node_id << 44) | loongson_memmap->map[i].mem_start; + + switch (mem_type) { + case SYSTEM_RAM_LOW: + case SYSTEM_RAM_HIGH: +- start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; +- node_psize = (mem_size << 20) >> PAGE_SHIFT; +- end_pfn = start_pfn + node_psize; +- num_physpages += node_psize; +- pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", +- (u32)node_id, mem_type, mem_start, mem_size); +- pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", +- start_pfn, end_pfn, num_physpages); +- memblock_add_node(PFN_PHYS(start_pfn), +- PFN_PHYS(node_psize), node, ++ case UMA_VIDEO_RAM: ++ pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes usable\n", ++ (u32)node_id, mem_type, &mem_start, &mem_size); ++ memblock_add_node(mem_start, mem_size, node, + MEMBLOCK_NONE); + break; + case SYSTEM_RAM_RESERVED: +- pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", +- (u32)node_id, mem_type, mem_start, mem_size); +- memblock_reserve(((node_id << 44) + mem_start), mem_size << 20); ++ case VIDEO_ROM: ++ case ADAPTER_ROM: ++ case ACPI_TABLE: ++ case SMBIOS_TABLE: ++ pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes reserved\n", ++ (u32)node_id, mem_type, &mem_start, &mem_size); ++ memblock_reserve(mem_start, mem_size); ++ break; ++ /* We should not reserve VUMA_VIDEO_RAM as it overlaps with MMIO */ ++ case VUMA_VIDEO_RAM: ++ default: ++ pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes unhandled\n", ++ (u32)node_id, mem_type, &mem_start, &mem_size); + break; + } + } ++ ++ /* Reserve vgabios if it comes from firmware */ ++ if (loongson_sysconf.vgabios_addr) ++ memblock_reserve(virt_to_phys((void *)loongson_sysconf.vgabios_addr), ++ SZ_256K); + } + + #ifndef CONFIG_NUMA +diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig +index 67c26e81e2150..345d5e021484c 100644 +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -105,9 +105,12 @@ config ARCH_HAS_ILOG2_U64 + default n + + config GENERIC_BUG +- bool +- default y ++ def_bool y + depends on BUG ++ select GENERIC_BUG_RELATIVE_POINTERS if 64BIT ++ ++config GENERIC_BUG_RELATIVE_POINTERS ++ bool + + config GENERIC_HWEIGHT + bool +diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h +index b9cad0bb4461b..833555f74ffa7 100644 +--- a/arch/parisc/include/asm/bug.h ++++ b/arch/parisc/include/asm/bug.h +@@ -17,26 +17,27 @@ + #define PARISC_BUG_BREAK_ASM "break 0x1f, 0x1fff" + #define PARISC_BUG_BREAK_INSN 0x03ffe01f /* PARISC_BUG_BREAK_ASM */ + +-#if defined(CONFIG_64BIT) +-#define ASM_WORD_INSN ".dword\t" ++#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS ++# define __BUG_REL(val) ".word " __stringify(val) " - ." + #else +-#define ASM_WORD_INSN ".word\t" ++# define __BUG_REL(val) ".word " __stringify(val) + #endif + ++ + #ifdef CONFIG_DEBUG_BUGVERBOSE + #define BUG() \ + do { \ + asm volatile("\n" \ + "1:\t" PARISC_BUG_BREAK_ASM "\n" \ + "\t.pushsection __bug_table,\"a\"\n" \ +- "\t.align %4\n" \ +- "2:\t" ASM_WORD_INSN "1b, %c0\n" \ ++ "\t.align 4\n" \ ++ "2:\t" __BUG_REL(1b) "\n" \ ++ "\t" __BUG_REL(%c0) "\n" \ + "\t.short %1, %2\n" \ +- "\t.blockz %3-2*%4-2*2\n" \ ++ "\t.blockz %3-2*4-2*2\n" \ + "\t.popsection" \ + : : "i" (__FILE__), "i" (__LINE__), \ +- "i" (0), "i" (sizeof(struct bug_entry)), \ +- "i" (sizeof(long)) ); \ ++ "i" (0), "i" (sizeof(struct bug_entry)) ); \ + unreachable(); \ + } while(0) + +@@ -54,15 +55,15 @@ + asm volatile("\n" \ + "1:\t" PARISC_BUG_BREAK_ASM "\n" \ + "\t.pushsection __bug_table,\"a\"\n" \ +- "\t.align %4\n" \ +- "2:\t" ASM_WORD_INSN "1b, %c0\n" \ ++ "\t.align 4\n" \ ++ "2:\t" __BUG_REL(1b) "\n" \ ++ "\t" __BUG_REL(%c0) "\n" \ + "\t.short %1, %2\n" \ +- "\t.blockz %3-2*%4-2*2\n" \ ++ "\t.blockz %3-2*4-2*2\n" \ + "\t.popsection" \ + : : "i" (__FILE__), "i" (__LINE__), \ + "i" (BUGFLAG_WARNING|(flags)), \ +- "i" (sizeof(struct bug_entry)), \ +- "i" (sizeof(long)) ); \ ++ "i" (sizeof(struct bug_entry)) ); \ + } while(0) + #else + #define __WARN_FLAGS(flags) \ +@@ -70,14 +71,13 @@ + asm volatile("\n" \ + "1:\t" PARISC_BUG_BREAK_ASM "\n" \ + "\t.pushsection __bug_table,\"a\"\n" \ +- "\t.align %2\n" \ +- "2:\t" ASM_WORD_INSN "1b\n" \ ++ "\t.align 4\n" \ ++ "2:\t" __BUG_REL(1b) "\n" \ + "\t.short %0\n" \ +- "\t.blockz %1-%2-2\n" \ ++ "\t.blockz %1-4-2\n" \ + "\t.popsection" \ + : : "i" (BUGFLAG_WARNING|(flags)), \ +- "i" (sizeof(struct bug_entry)), \ +- "i" (sizeof(long)) ); \ ++ "i" (sizeof(struct bug_entry)) ); \ + } while(0) + #endif + +diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs +index 69774bb362d6a..29d78eefc8894 100644 +--- a/arch/riscv/Kconfig.socs ++++ b/arch/riscv/Kconfig.socs +@@ -23,6 +23,7 @@ config SOC_STARFIVE + select PINCTRL + select RESET_CONTROLLER + select SIFIVE_PLIC ++ select ARM_AMBA + help + This enables support for StarFive SoC platform hardware. + +diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c +index 378f5b1514435..5348d842c7453 100644 +--- a/arch/riscv/kernel/traps_misaligned.c ++++ b/arch/riscv/kernel/traps_misaligned.c +@@ -342,16 +342,14 @@ int handle_misaligned_store(struct pt_regs *regs) + } else if ((insn & INSN_MASK_C_SD) == INSN_MATCH_C_SD) { + len = 8; + val.data_ulong = GET_RS2S(insn, regs); +- } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP && +- ((insn >> SH_RD) & 0x1f)) { ++ } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP) { + len = 8; + val.data_ulong = GET_RS2C(insn, regs); + #endif + } else if ((insn & INSN_MASK_C_SW) == INSN_MATCH_C_SW) { + len = 4; + val.data_ulong = GET_RS2S(insn, regs); +- } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP && +- ((insn >> SH_RD) & 0x1f)) { ++ } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP) { + len = 4; + val.data_ulong = GET_RS2C(insn, regs); + } else { +diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c +index 4909dcd762e8c..9977d637f836d 100644 +--- a/arch/s390/mm/pgtable.c ++++ b/arch/s390/mm/pgtable.c +@@ -731,7 +731,7 @@ void ptep_zap_unused(struct mm_struct *mm, unsigned long addr, + pte_clear(mm, addr, ptep); + } + if (reset) +- pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK; ++ pgste_val(pgste) &= ~(_PGSTE_GPS_USAGE_MASK | _PGSTE_GPS_NODAT); + pgste_set_unlock(ptep, pgste); + preempt_enable(); + } +diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c +index 8a1d48b8c2a3e..d0565a9e7d8c9 100644 +--- a/arch/x86/coco/tdx/tdx.c ++++ b/arch/x86/coco/tdx/tdx.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include +diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c +index 93c60c0c9d4a7..9c0b26ae51069 100644 +--- a/arch/x86/entry/common.c ++++ b/arch/x86/entry/common.c +@@ -25,6 +25,7 @@ + #include + #endif + ++#include + #include + #include + #include +@@ -96,6 +97,10 @@ static __always_inline int syscall_32_enter(struct pt_regs *regs) + return (int)regs->orig_ax; + } + ++#ifdef CONFIG_IA32_EMULATION ++bool __ia32_enabled __ro_after_init = true; ++#endif ++ + /* + * Invoke a 32-bit syscall. Called with IRQs on in CONTEXT_KERNEL. + */ +@@ -115,7 +120,96 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr) + } + } + +-/* Handles int $0x80 */ ++#ifdef CONFIG_IA32_EMULATION ++static __always_inline bool int80_is_external(void) ++{ ++ const unsigned int offs = (0x80 / 32) * 0x10; ++ const u32 bit = BIT(0x80 % 32); ++ ++ /* The local APIC on XENPV guests is fake */ ++ if (cpu_feature_enabled(X86_FEATURE_XENPV)) ++ return false; ++ ++ /* ++ * If vector 0x80 is set in the APIC ISR then this is an external ++ * interrupt. Either from broken hardware or injected by a VMM. ++ * ++ * Note: In guest mode this is only valid for secure guests where ++ * the secure module fully controls the vAPIC exposed to the guest. ++ */ ++ return apic_read(APIC_ISR + offs) & bit; ++} ++ ++/** ++ * int80_emulation - 32-bit legacy syscall entry ++ * ++ * This entry point can be used by 32-bit and 64-bit programs to perform ++ * 32-bit system calls. Instances of INT $0x80 can be found inline in ++ * various programs and libraries. It is also used by the vDSO's ++ * __kernel_vsyscall fallback for hardware that doesn't support a faster ++ * entry method. Restarted 32-bit system calls also fall back to INT ++ * $0x80 regardless of what instruction was originally used to do the ++ * system call. ++ * ++ * This is considered a slow path. It is not used by most libc ++ * implementations on modern hardware except during process startup. ++ * ++ * The arguments for the INT $0x80 based syscall are on stack in the ++ * pt_regs structure: ++ * eax: system call number ++ * ebx, ecx, edx, esi, edi, ebp: arg1 - arg 6 ++ */ ++DEFINE_IDTENTRY_RAW(int80_emulation) ++{ ++ int nr; ++ ++ /* Kernel does not use INT $0x80! */ ++ if (unlikely(!user_mode(regs))) { ++ irqentry_enter(regs); ++ instrumentation_begin(); ++ panic("Unexpected external interrupt 0x80\n"); ++ } ++ ++ /* ++ * Establish kernel context for instrumentation, including for ++ * int80_is_external() below which calls into the APIC driver. ++ * Identical for soft and external interrupts. ++ */ ++ enter_from_user_mode(regs); ++ ++ instrumentation_begin(); ++ add_random_kstack_offset(); ++ ++ /* Validate that this is a soft interrupt to the extent possible */ ++ if (unlikely(int80_is_external())) ++ panic("Unexpected external interrupt 0x80\n"); ++ ++ /* ++ * The low level idtentry code pushed -1 into regs::orig_ax ++ * and regs::ax contains the syscall number. ++ * ++ * User tracing code (ptrace or signal handlers) might assume ++ * that the regs::orig_ax contains a 32-bit number on invoking ++ * a 32-bit syscall. ++ * ++ * Establish the syscall convention by saving the 32bit truncated ++ * syscall number in regs::orig_ax and by invalidating regs::ax. ++ */ ++ regs->orig_ax = regs->ax & GENMASK(31, 0); ++ regs->ax = -ENOSYS; ++ ++ nr = syscall_32_enter(regs); ++ ++ local_irq_enable(); ++ nr = syscall_enter_from_user_mode_work(regs, nr); ++ do_syscall_32_irqs_on(regs, nr); ++ ++ instrumentation_end(); ++ syscall_exit_to_user_mode(regs); ++} ++#else /* CONFIG_IA32_EMULATION */ ++ ++/* Handles int $0x80 on a 32bit kernel */ + __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) + { + int nr = syscall_32_enter(regs); +@@ -134,6 +228,7 @@ __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) + instrumentation_end(); + syscall_exit_to_user_mode(regs); + } ++#endif /* !CONFIG_IA32_EMULATION */ + + static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) + { +diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S +index 4dd19819053a5..d6c08d8986b17 100644 +--- a/arch/x86/entry/entry_64_compat.S ++++ b/arch/x86/entry/entry_64_compat.S +@@ -277,80 +277,3 @@ SYM_INNER_LABEL(entry_SYSRETL_compat_end, SYM_L_GLOBAL) + ANNOTATE_NOENDBR + int3 + SYM_CODE_END(entry_SYSCALL_compat) +- +-/* +- * 32-bit legacy system call entry. +- * +- * 32-bit x86 Linux system calls traditionally used the INT $0x80 +- * instruction. INT $0x80 lands here. +- * +- * This entry point can be used by 32-bit and 64-bit programs to perform +- * 32-bit system calls. Instances of INT $0x80 can be found inline in +- * various programs and libraries. It is also used by the vDSO's +- * __kernel_vsyscall fallback for hardware that doesn't support a faster +- * entry method. Restarted 32-bit system calls also fall back to INT +- * $0x80 regardless of what instruction was originally used to do the +- * system call. +- * +- * This is considered a slow path. It is not used by most libc +- * implementations on modern hardware except during process startup. +- * +- * Arguments: +- * eax system call number +- * ebx arg1 +- * ecx arg2 +- * edx arg3 +- * esi arg4 +- * edi arg5 +- * ebp arg6 +- */ +-SYM_CODE_START(entry_INT80_compat) +- UNWIND_HINT_ENTRY +- ENDBR +- /* +- * Interrupts are off on entry. +- */ +- ASM_CLAC /* Do this early to minimize exposure */ +- ALTERNATIVE "swapgs", "", X86_FEATURE_XENPV +- +- /* +- * User tracing code (ptrace or signal handlers) might assume that +- * the saved RAX contains a 32-bit number when we're invoking a 32-bit +- * syscall. Just in case the high bits are nonzero, zero-extend +- * the syscall number. (This could almost certainly be deleted +- * with no ill effects.) +- */ +- movl %eax, %eax +- +- /* switch to thread stack expects orig_ax and rdi to be pushed */ +- pushq %rax /* pt_regs->orig_ax */ +- +- /* Need to switch before accessing the thread stack. */ +- SWITCH_TO_KERNEL_CR3 scratch_reg=%rax +- +- /* In the Xen PV case we already run on the thread stack. */ +- ALTERNATIVE "", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV +- +- movq %rsp, %rax +- movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp +- +- pushq 5*8(%rax) /* regs->ss */ +- pushq 4*8(%rax) /* regs->rsp */ +- pushq 3*8(%rax) /* regs->eflags */ +- pushq 2*8(%rax) /* regs->cs */ +- pushq 1*8(%rax) /* regs->ip */ +- pushq 0*8(%rax) /* regs->orig_ax */ +-.Lint80_keep_stack: +- +- PUSH_AND_CLEAR_REGS rax=$-ENOSYS +- UNWIND_HINT_REGS +- +- cld +- +- IBRS_ENTER +- UNTRAIN_RET +- +- movq %rsp, %rdi +- call do_int80_syscall_32 +- jmp swapgs_restore_regs_and_return_to_usermode +-SYM_CODE_END(entry_INT80_compat) +diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h +index fada857f0a1ed..9805629479d96 100644 +--- a/arch/x86/include/asm/ia32.h ++++ b/arch/x86/include/asm/ia32.h +@@ -68,6 +68,27 @@ extern void ia32_pick_mmap_layout(struct mm_struct *mm); + + #endif + +-#endif /* CONFIG_IA32_EMULATION */ ++extern bool __ia32_enabled; ++ ++static inline bool ia32_enabled(void) ++{ ++ return __ia32_enabled; ++} ++ ++static inline void ia32_disable(void) ++{ ++ __ia32_enabled = false; ++} ++ ++#else /* !CONFIG_IA32_EMULATION */ ++ ++static inline bool ia32_enabled(void) ++{ ++ return IS_ENABLED(CONFIG_X86_32); ++} ++ ++static inline void ia32_disable(void) {} ++ ++#endif + + #endif /* _ASM_X86_IA32_H */ +diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h +index 72184b0b2219e..fca710a93eb9c 100644 +--- a/arch/x86/include/asm/idtentry.h ++++ b/arch/x86/include/asm/idtentry.h +@@ -569,6 +569,10 @@ DECLARE_IDTENTRY_RAW(X86_TRAP_UD, exc_invalid_op); + DECLARE_IDTENTRY_RAW(X86_TRAP_BP, exc_int3); + DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_PF, exc_page_fault); + ++#if defined(CONFIG_IA32_EMULATION) ++DECLARE_IDTENTRY_RAW(IA32_SYSCALL_VECTOR, int80_emulation); ++#endif ++ + #ifdef CONFIG_X86_MCE + #ifdef CONFIG_X86_64 + DECLARE_IDTENTRY_MCE(X86_TRAP_MC, exc_machine_check); +diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h +index 12ef86b19910d..84294b66b9162 100644 +--- a/arch/x86/include/asm/proto.h ++++ b/arch/x86/include/asm/proto.h +@@ -32,10 +32,6 @@ void entry_SYSCALL_compat(void); + void entry_SYSCALL_compat_safe_stack(void); + void entry_SYSRETL_compat_unsafe_stack(void); + void entry_SYSRETL_compat_end(void); +-void entry_INT80_compat(void); +-#ifdef CONFIG_XEN_PV +-void xen_entry_INT80_compat(void); +-#endif + #endif + + void x86_configure_nx(void); +diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c +index b66960358381b..c1d09c8844d67 100644 +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -1291,6 +1291,9 @@ static void zenbleed_check_cpu(void *unused) + + void amd_check_microcode(void) + { ++ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) ++ return; ++ + on_each_cpu(zenbleed_check_cpu, NULL, 1); + } + +diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c +index a58c6bc1cd68c..f5a3374e62cb1 100644 +--- a/arch/x86/kernel/idt.c ++++ b/arch/x86/kernel/idt.c +@@ -117,7 +117,7 @@ static const __initconst struct idt_data def_idts[] = { + + SYSG(X86_TRAP_OF, asm_exc_overflow), + #if defined(CONFIG_IA32_EMULATION) +- SYSG(IA32_SYSCALL_VECTOR, entry_INT80_compat), ++ SYSG(IA32_SYSCALL_VECTOR, asm_int80_emulation), + #elif defined(CONFIG_X86_32) + SYSG(IA32_SYSCALL_VECTOR, entry_INT80_32), + #endif +diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c +index 68b2a9d3dbc6b..c8dfb0fdde7f9 100644 +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -1279,10 +1279,6 @@ void setup_ghcb(void) + if (!cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT)) + return; + +- /* First make sure the hypervisor talks a supported protocol. */ +- if (!sev_es_negotiate_protocol()) +- sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); +- + /* + * Check whether the runtime #VC exception handler is active. It uses + * the per-CPU GHCB page which is set up by sev_es_init_vc_handling(). +@@ -1297,6 +1293,13 @@ void setup_ghcb(void) + return; + } + ++ /* ++ * Make sure the hypervisor talks a supported protocol. ++ * This gets called only in the BSP boot phase. ++ */ ++ if (!sev_es_negotiate_protocol()) ++ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); ++ + /* + * Clear the boot_ghcb. The first exception comes in before the bss + * section is cleared. +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index 4194aa4c5f0e0..4a663812562db 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -1786,15 +1786,17 @@ void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) + bool old_paging = is_paging(vcpu); + + #ifdef CONFIG_X86_64 +- if (vcpu->arch.efer & EFER_LME && !vcpu->arch.guest_state_protected) { ++ if (vcpu->arch.efer & EFER_LME) { + if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) { + vcpu->arch.efer |= EFER_LMA; +- svm->vmcb->save.efer |= EFER_LMA | EFER_LME; ++ if (!vcpu->arch.guest_state_protected) ++ svm->vmcb->save.efer |= EFER_LMA | EFER_LME; + } + + if (is_paging(vcpu) && !(cr0 & X86_CR0_PG)) { + vcpu->arch.efer &= ~EFER_LMA; +- svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME); ++ if (!vcpu->arch.guest_state_protected) ++ svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME); + } + } + #endif +diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c +index 3ea0f763540a4..3e93af083e037 100644 +--- a/arch/x86/mm/mem_encrypt_amd.c ++++ b/arch/x86/mm/mem_encrypt_amd.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + #include "mm_internal.h" + +@@ -502,6 +503,16 @@ void __init sme_early_init(void) + x86_platform.guest.enc_status_change_finish = amd_enc_status_change_finish; + x86_platform.guest.enc_tlb_flush_required = amd_enc_tlb_flush_required; + x86_platform.guest.enc_cache_flush_required = amd_enc_cache_flush_required; ++ ++ /* ++ * The VMM is capable of injecting interrupt 0x80 and triggering the ++ * compatibility syscall path. ++ * ++ * By default, the 32-bit emulation is disabled in order to ensure ++ * the safety of the VM. ++ */ ++ if (sev_status & MSR_AMD64_SEV_ENABLED) ++ ia32_disable(); + } + + void __init mem_encrypt_free_decrypted_mem(void) +diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c +index 333539bdbdaae..9280e15de3af5 100644 +--- a/arch/x86/xen/enlighten_pv.c ++++ b/arch/x86/xen/enlighten_pv.c +@@ -623,7 +623,7 @@ static struct trap_array_entry trap_array[] = { + TRAP_ENTRY(exc_int3, false ), + TRAP_ENTRY(exc_overflow, false ), + #ifdef CONFIG_IA32_EMULATION +- { entry_INT80_compat, xen_entry_INT80_compat, false }, ++ TRAP_ENTRY(int80_emulation, false ), + #endif + TRAP_ENTRY(exc_page_fault, false ), + TRAP_ENTRY(exc_divide_error, false ), +diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S +index 6b4fdf6b95422..dec5e03e7a2cf 100644 +--- a/arch/x86/xen/xen-asm.S ++++ b/arch/x86/xen/xen-asm.S +@@ -156,7 +156,7 @@ xen_pv_trap asm_xenpv_exc_machine_check + #endif /* CONFIG_X86_MCE */ + xen_pv_trap asm_exc_simd_coprocessor_error + #ifdef CONFIG_IA32_EMULATION +-xen_pv_trap entry_INT80_compat ++xen_pv_trap asm_int80_emulation + #endif + xen_pv_trap asm_exc_xen_unknown_trap + xen_pv_trap asm_exc_xen_hypervisor_callback +diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c +index a0e347f6f97eb..94154a849a3ea 100644 +--- a/drivers/acpi/scan.c ++++ b/drivers/acpi/scan.c +@@ -1563,17 +1563,22 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev, + int err; + const struct iommu_ops *ops; + ++ /* Serialise to make dev->iommu stable under our potential fwspec */ ++ mutex_lock(&iommu_probe_device_lock); + /* + * If we already translated the fwspec there is nothing left to do, + * return the iommu_ops. + */ + ops = acpi_iommu_fwspec_ops(dev); +- if (ops) ++ if (ops) { ++ mutex_unlock(&iommu_probe_device_lock); + return ops; ++ } + + err = iort_iommu_configure_id(dev, id_in); + if (err && err != -EPROBE_DEFER) + err = viot_iommu_configure(dev); ++ mutex_unlock(&iommu_probe_device_lock); + + /* + * If we have reason to believe the IOMMU driver missed the initial +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index e4a6da81cd4b3..9cc3a2b1b4fc1 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -4788,6 +4788,7 @@ static void binder_release_work(struct binder_proc *proc, + "undelivered TRANSACTION_ERROR: %u\n", + e->cmd); + } break; ++ case BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT: + case BINDER_WORK_TRANSACTION_COMPLETE: { + binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, + "undelivered TRANSACTION_COMPLETE\n"); +diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c +index 1c06781f71148..f3bd9f104bd12 100644 +--- a/drivers/base/devcoredump.c ++++ b/drivers/base/devcoredump.c +@@ -363,6 +363,7 @@ void dev_coredumpm(struct device *dev, struct module *owner, + devcd->devcd_dev.class = &devcd_class; + + mutex_lock(&devcd->mutex); ++ dev_set_uevent_suppress(&devcd->devcd_dev, true); + if (device_add(&devcd->devcd_dev)) + goto put_device; + +@@ -377,6 +378,8 @@ void dev_coredumpm(struct device *dev, struct module *owner, + "devcoredump")) + dev_warn(dev, "devcoredump create_link failed\n"); + ++ dev_set_uevent_suppress(&devcd->devcd_dev, false); ++ kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD); + INIT_DELAYED_WORK(&devcd->del_wk, devcd_del); + schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT); + mutex_unlock(&devcd->mutex); +diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c +index cf3fa998093de..4f3dd9316fb2f 100644 +--- a/drivers/base/regmap/regcache.c ++++ b/drivers/base/regmap/regcache.c +@@ -410,8 +410,7 @@ out: + rb_entry(node, struct regmap_range_node, node); + + /* If there's nothing in the cache there's nothing to sync */ +- ret = regcache_read(map, this->selector_reg, &i); +- if (ret != 0) ++ if (regcache_read(map, this->selector_reg, &i) != 0) + continue; + + ret = _regmap_write(map, this->selector_reg, i); +diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c +index cd27bf173dec8..a64648682c72c 100644 +--- a/drivers/gpio/gpiolib-sysfs.c ++++ b/drivers/gpio/gpiolib-sysfs.c +@@ -463,14 +463,17 @@ static ssize_t export_store(struct class *class, + goto done; + + status = gpiod_set_transitory(desc, false); +- if (!status) { +- status = gpiod_export(desc, true); +- if (status < 0) +- gpiod_free(desc); +- else +- set_bit(FLAG_SYSFS, &desc->flags); ++ if (status) { ++ gpiod_free(desc); ++ goto done; + } + ++ status = gpiod_export(desc, true); ++ if (status < 0) ++ gpiod_free(desc); ++ else ++ set_bit(FLAG_SYSFS, &desc->flags); ++ + done: + if (status) + pr_debug("%s: status %d\n", __func__, status); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +index ced4e7e8f98b5..133e4e03c143c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -201,7 +201,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, + } + + for (i = 0; i < p->nchunks; i++) { +- struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL; ++ struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL; + struct drm_amdgpu_cs_chunk user_chunk; + uint32_t __user *cdata; + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +index 2fced451f0aea..aabde6ebb190e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +@@ -90,7 +90,7 @@ static void amdgpu_display_flip_work_func(struct work_struct *__work) + + struct drm_crtc *crtc = &amdgpu_crtc->base; + unsigned long flags; +- unsigned i; ++ unsigned int i; + int vpos, hpos; + + for (i = 0; i < work->shared_count; ++i) +@@ -167,7 +167,7 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc, + u64 tiling_flags; + int i, r; + +- work = kzalloc(sizeof *work, GFP_KERNEL); ++ work = kzalloc(sizeof(*work), GFP_KERNEL); + if (work == NULL) + return -ENOMEM; + +@@ -298,18 +298,17 @@ int amdgpu_display_crtc_set_config(struct drm_mode_set *set, + + adev = drm_to_adev(dev); + /* if we have active crtcs and we don't have a power ref, +- take the current one */ ++ * take the current one ++ */ + if (active && !adev->have_disp_power_ref) { + adev->have_disp_power_ref = true; + return ret; + } +- /* if we have no active crtcs, then drop the power ref +- we got before */ +- if (!active && adev->have_disp_power_ref) { +- pm_runtime_put_autosuspend(dev->dev); ++ /* if we have no active crtcs, then go to ++ * drop the power ref we got before ++ */ ++ if (!active && adev->have_disp_power_ref) + adev->have_disp_power_ref = false; +- } +- + out: + /* drop the power reference we got coming in here */ + pm_runtime_put_autosuspend(dev->dev); +@@ -473,11 +472,10 @@ bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector, + if (amdgpu_connector->router.ddc_valid) + amdgpu_i2c_router_select_ddc_port(amdgpu_connector); + +- if (use_aux) { ++ if (use_aux) + ret = i2c_transfer(&amdgpu_connector->ddc_bus->aux.ddc, msgs, 2); +- } else { ++ else + ret = i2c_transfer(&amdgpu_connector->ddc_bus->adapter, msgs, 2); +- } + + if (ret != 2) + /* Couldn't find an accessible DDC on this connector */ +@@ -486,10 +484,12 @@ bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector, + * EDID header starts with: + * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. + * Only the first 6 bytes must be valid as +- * drm_edid_block_valid() can fix the last 2 bytes */ ++ * drm_edid_block_valid() can fix the last 2 bytes ++ */ + if (drm_edid_header_is_valid(buf) < 6) { + /* Couldn't find an accessible EDID on this +- * connector */ ++ * connector ++ */ + return false; + } + return true; +@@ -1204,8 +1204,10 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev, + + obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); + if (obj == NULL) { +- drm_dbg_kms(dev, "No GEM object associated to handle 0x%08X, " +- "can't create framebuffer\n", mode_cmd->handles[0]); ++ drm_dbg_kms(dev, ++ "No GEM object associated to handle 0x%08X, can't create framebuffer\n", ++ mode_cmd->handles[0]); ++ + return ERR_PTR(-ENOENT); + } + +@@ -1398,6 +1400,7 @@ bool amdgpu_display_crtc_scaling_mode_fixup(struct drm_crtc *crtc, + } + if (amdgpu_crtc->rmx_type != RMX_OFF) { + fixed20_12 a, b; ++ + a.full = dfixed_const(src_v); + b.full = dfixed_const(dst_v); + amdgpu_crtc->vsc.full = dfixed_div(a, b); +@@ -1417,7 +1420,7 @@ bool amdgpu_display_crtc_scaling_mode_fixup(struct drm_crtc *crtc, + * + * \param dev Device to query. + * \param pipe Crtc to query. +- * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). ++ * \param flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). + * For driver internal use only also supports these flags: + * + * USE_REAL_VBLANKSTART to use the real start of vblank instead +@@ -1493,8 +1496,8 @@ int amdgpu_display_get_crtc_scanoutpos(struct drm_device *dev, + + /* Called from driver internal vblank counter query code? */ + if (flags & GET_DISTANCE_TO_VBLANKSTART) { +- /* Caller wants distance from real vbl_start in *hpos */ +- *hpos = *vpos - vbl_start; ++ /* Caller wants distance from real vbl_start in *hpos */ ++ *hpos = *vpos - vbl_start; + } + + /* Fudge vblank to start a few scanlines earlier to handle the +@@ -1516,7 +1519,7 @@ int amdgpu_display_get_crtc_scanoutpos(struct drm_device *dev, + + /* In vblank? */ + if (in_vbl) +- ret |= DRM_SCANOUTPOS_IN_VBLANK; ++ ret |= DRM_SCANOUTPOS_IN_VBLANK; + + /* Called from driver internal vblank counter query code? */ + if (flags & GET_DISTANCE_TO_VBLANKSTART) { +@@ -1622,6 +1625,7 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev) + + if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) { + struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); ++ + r = amdgpu_bo_reserve(aobj, true); + if (r == 0) { + amdgpu_bo_unpin(aobj); +@@ -1629,9 +1633,9 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev) + } + } + +- if (fb == NULL || fb->obj[0] == NULL) { ++ if (!fb || !fb->obj[0]) + continue; +- } ++ + robj = gem_to_amdgpu_bo(fb->obj[0]); + if (!amdgpu_display_robj_is_fb(adev, robj)) { + r = amdgpu_bo_reserve(robj, true); +@@ -1658,6 +1662,7 @@ int amdgpu_display_resume_helper(struct amdgpu_device *adev) + + if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) { + struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); ++ + r = amdgpu_bo_reserve(aobj, true); + if (r == 0) { + r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c +index 4d9eb0137f8c4..d6c4293829aab 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c +@@ -79,6 +79,8 @@ + * That is, for an I2C EEPROM driver everything is controlled by + * the "eeprom_addr". + * ++ * See also top of amdgpu_ras_eeprom.c. ++ * + * P.S. If you need to write, lock and read the Identification Page, + * (M24M02-DR device only, which we do not use), change the "7" to + * "0xF" in the macro below, and let the client set bit 20 to 1 in +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +index 84c241b9a2a13..f5f747cfe90a1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +@@ -33,12 +33,29 @@ + + #include "amdgpu_reset.h" + +-#define EEPROM_I2C_MADDR_VEGA20 0x0 +-#define EEPROM_I2C_MADDR_ARCTURUS 0x40000 +-#define EEPROM_I2C_MADDR_ARCTURUS_D342 0x0 +-#define EEPROM_I2C_MADDR_SIENNA_CICHLID 0x0 +-#define EEPROM_I2C_MADDR_ALDEBARAN 0x0 +-#define EEPROM_I2C_MADDR_SMU_13_0_0 (0x54UL << 16) ++/* These are memory addresses as would be seen by one or more EEPROM ++ * chips strung on the I2C bus, usually by manipulating pins 1-3 of a ++ * set of EEPROM devices. They form a continuous memory space. ++ * ++ * The I2C device address includes the device type identifier, 1010b, ++ * which is a reserved value and indicates that this is an I2C EEPROM ++ * device. It also includes the top 3 bits of the 19 bit EEPROM memory ++ * address, namely bits 18, 17, and 16. This makes up the 7 bit ++ * address sent on the I2C bus with bit 0 being the direction bit, ++ * which is not represented here, and sent by the hardware directly. ++ * ++ * For instance, ++ * 50h = 1010000b => device type identifier 1010b, bits 18:16 = 000b, address 0. ++ * 54h = 1010100b => --"--, bits 18:16 = 100b, address 40000h. ++ * 56h = 1010110b => --"--, bits 18:16 = 110b, address 60000h. ++ * Depending on the size of the I2C EEPROM device(s), bits 18:16 may ++ * address memory in a device or a device on the I2C bus, depending on ++ * the status of pins 1-3. See top of amdgpu_eeprom.c. ++ * ++ * The RAS table lives either at address 0 or address 40000h of EEPROM. ++ */ ++#define EEPROM_I2C_MADDR_0 0x0 ++#define EEPROM_I2C_MADDR_4 0x40000 + + /* + * The 2 macros bellow represent the actual size in bytes that +@@ -90,33 +107,23 @@ + + static bool __is_ras_eeprom_supported(struct amdgpu_device *adev) + { +- return adev->asic_type == CHIP_VEGA20 || +- adev->asic_type == CHIP_ARCTURUS || +- adev->asic_type == CHIP_SIENNA_CICHLID || +- adev->asic_type == CHIP_ALDEBARAN; +-} +- +-static bool __get_eeprom_i2c_addr_arct(struct amdgpu_device *adev, +- struct amdgpu_ras_eeprom_control *control) +-{ +- struct atom_context *atom_ctx = adev->mode_info.atom_context; +- +- if (!control || !atom_ctx) ++ switch (adev->ip_versions[MP1_HWIP][0]) { ++ case IP_VERSION(11, 0, 2): /* VEGA20 and ARCTURUS */ ++ case IP_VERSION(11, 0, 7): /* Sienna cichlid */ ++ case IP_VERSION(13, 0, 0): ++ case IP_VERSION(13, 0, 2): /* Aldebaran */ ++ case IP_VERSION(13, 0, 6): ++ case IP_VERSION(13, 0, 10): ++ return true; ++ default: + return false; +- +- if (strnstr(atom_ctx->vbios_version, +- "D342", +- sizeof(atom_ctx->vbios_version))) +- control->i2c_address = EEPROM_I2C_MADDR_ARCTURUS_D342; +- else +- control->i2c_address = EEPROM_I2C_MADDR_ARCTURUS; +- +- return true; ++ } + } + + static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev, + struct amdgpu_ras_eeprom_control *control) + { ++ struct atom_context *atom_ctx = adev->mode_info.atom_context; + u8 i2c_addr; + + if (!control) +@@ -137,36 +144,42 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev, + return true; + } + +- switch (adev->asic_type) { +- case CHIP_VEGA20: +- control->i2c_address = EEPROM_I2C_MADDR_VEGA20; +- break; +- +- case CHIP_ARCTURUS: +- return __get_eeprom_i2c_addr_arct(adev, control); +- +- case CHIP_SIENNA_CICHLID: +- control->i2c_address = EEPROM_I2C_MADDR_SIENNA_CICHLID; +- break; +- +- case CHIP_ALDEBARAN: +- control->i2c_address = EEPROM_I2C_MADDR_ALDEBARAN; +- break; +- +- default: +- return false; +- } +- + switch (adev->ip_versions[MP1_HWIP][0]) { ++ case IP_VERSION(11, 0, 2): ++ /* VEGA20 and ARCTURUS */ ++ if (adev->asic_type == CHIP_VEGA20) ++ control->i2c_address = EEPROM_I2C_MADDR_0; ++ else if (strnstr(atom_ctx->vbios_version, ++ "D342", ++ sizeof(atom_ctx->vbios_version))) ++ control->i2c_address = EEPROM_I2C_MADDR_0; ++ else ++ control->i2c_address = EEPROM_I2C_MADDR_4; ++ return true; ++ case IP_VERSION(11, 0, 7): ++ control->i2c_address = EEPROM_I2C_MADDR_0; ++ return true; ++ case IP_VERSION(13, 0, 2): ++ if (strnstr(atom_ctx->vbios_version, "D673", ++ sizeof(atom_ctx->vbios_version))) ++ control->i2c_address = EEPROM_I2C_MADDR_4; ++ else ++ control->i2c_address = EEPROM_I2C_MADDR_0; ++ return true; + case IP_VERSION(13, 0, 0): +- control->i2c_address = EEPROM_I2C_MADDR_SMU_13_0_0; +- break; +- ++ if (strnstr(atom_ctx->vbios_pn, "D707", ++ sizeof(atom_ctx->vbios_pn))) ++ control->i2c_address = EEPROM_I2C_MADDR_0; ++ else ++ control->i2c_address = EEPROM_I2C_MADDR_4; ++ return true; ++ case IP_VERSION(13, 0, 6): ++ case IP_VERSION(13, 0, 10): ++ control->i2c_address = EEPROM_I2C_MADDR_4; ++ return true; + default: +- break; ++ return false; + } +- +- return true; + } + + static void +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +index 23e7e5126eae6..66a6f7a37ebcf 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +@@ -397,7 +397,7 @@ static int gfx_v11_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) + adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); + cpu_ptr = &adev->wb.wb[index]; + +- r = amdgpu_ib_get(adev, NULL, 16, AMDGPU_IB_POOL_DIRECT, &ib); ++ r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib); + if (r) { + DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); + goto err1; +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +index 7f0b18b0d4c48..71ef25425c7f6 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +@@ -883,8 +883,8 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) + gpu_addr = adev->wb.gpu_addr + (index * 4); + adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); + memset(&ib, 0, sizeof(ib)); +- r = amdgpu_ib_get(adev, NULL, 16, +- AMDGPU_IB_POOL_DIRECT, &ib); ++ ++ r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib); + if (r) + goto err1; + +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +index fe371022e5104..84ca601f7d5f3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +@@ -1034,8 +1034,8 @@ static int gfx_v9_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) + gpu_addr = adev->wb.gpu_addr + (index * 4); + adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); + memset(&ib, 0, sizeof(ib)); +- r = amdgpu_ib_get(adev, NULL, 16, +- AMDGPU_IB_POOL_DIRECT, &ib); ++ ++ r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib); + if (r) + goto err1; + +diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig +index 57946d80b02db..12baf9ba03c96 100644 +--- a/drivers/gpu/drm/bridge/Kconfig ++++ b/drivers/gpu/drm/bridge/Kconfig +@@ -309,6 +309,7 @@ config DRM_TOSHIBA_TC358768 + select REGMAP_I2C + select DRM_PANEL + select DRM_MIPI_DSI ++ select VIDEOMODE_HELPERS + help + Toshiba TC358768AXBG/TC358778XBG DSI bridge chip driver. + +diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c +index 8219310025de5..f7422f0cf579d 100644 +--- a/drivers/gpu/drm/i915/display/icl_dsi.c ++++ b/drivers/gpu/drm/i915/display/icl_dsi.c +@@ -1500,6 +1500,13 @@ static void gen11_dsi_post_disable(struct intel_atomic_state *state, + static enum drm_mode_status gen11_dsi_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) + { ++ struct drm_i915_private *i915 = to_i915(connector->dev); ++ enum drm_mode_status status; ++ ++ status = intel_cpu_transcoder_mode_valid(i915, mode); ++ if (status != MODE_OK) ++ return status; ++ + /* FIXME: DSC? */ + return intel_dsi_mode_valid(connector, mode); + } +diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c +index 4a8ff2f976085..e60b2cf84b851 100644 +--- a/drivers/gpu/drm/i915/display/intel_crt.c ++++ b/drivers/gpu/drm/i915/display/intel_crt.c +@@ -343,8 +343,13 @@ intel_crt_mode_valid(struct drm_connector *connector, + struct drm_device *dev = connector->dev; + struct drm_i915_private *dev_priv = to_i915(dev); + int max_dotclk = dev_priv->max_dotclk_freq; ++ enum drm_mode_status status; + int max_clock; + ++ status = intel_cpu_transcoder_mode_valid(dev_priv, mode); ++ if (status != MODE_OK) ++ return status; ++ + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + +diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c +index 96e679a176e94..1777a12f2f421 100644 +--- a/drivers/gpu/drm/i915/display/intel_display.c ++++ b/drivers/gpu/drm/i915/display/intel_display.c +@@ -8229,6 +8229,16 @@ intel_mode_valid(struct drm_device *dev, + mode->vtotal > vtotal_max) + return MODE_V_ILLEGAL; + ++ return MODE_OK; ++} ++ ++enum drm_mode_status intel_cpu_transcoder_mode_valid(struct drm_i915_private *dev_priv, ++ const struct drm_display_mode *mode) ++{ ++ /* ++ * Additional transcoder timing limits, ++ * excluding BXT/GLK DSI transcoders. ++ */ + if (DISPLAY_VER(dev_priv) >= 5) { + if (mode->hdisplay < 64 || + mode->htotal - mode->hdisplay < 32) +diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h +index 884e8e67b17c7..b4f941674357b 100644 +--- a/drivers/gpu/drm/i915/display/intel_display.h ++++ b/drivers/gpu/drm/i915/display/intel_display.h +@@ -554,6 +554,9 @@ enum drm_mode_status + intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, + const struct drm_display_mode *mode, + bool bigjoiner); ++enum drm_mode_status ++intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915, ++ const struct drm_display_mode *mode); + enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port); + bool is_trans_port_sync_mode(const struct intel_crtc_state *state); + bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state); +diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c +index 594ea037050a9..5970f4149090f 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -973,8 +973,9 @@ intel_dp_mode_valid(struct drm_connector *_connector, + enum drm_mode_status status; + bool dsc = false, bigjoiner = false; + +- if (mode->flags & DRM_MODE_FLAG_DBLSCAN) +- return MODE_NO_DBLESCAN; ++ status = intel_cpu_transcoder_mode_valid(dev_priv, mode); ++ if (status != MODE_OK) ++ return status; + + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + return MODE_H_ILLEGAL; +diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c +index 9a6822256ddf6..eec32f682012c 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c +@@ -703,6 +703,10 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, + return 0; + } + ++ *status = intel_cpu_transcoder_mode_valid(dev_priv, mode); ++ if (*status != MODE_OK) ++ return 0; ++ + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { + *status = MODE_NO_DBLESCAN; + return 0; +diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c +index 5572e43026e4d..511c589070087 100644 +--- a/drivers/gpu/drm/i915/display/intel_dvo.c ++++ b/drivers/gpu/drm/i915/display/intel_dvo.c +@@ -225,10 +225,16 @@ intel_dvo_mode_valid(struct drm_connector *connector, + { + struct intel_connector *intel_connector = to_intel_connector(connector); + struct intel_dvo *intel_dvo = intel_attached_dvo(intel_connector); ++ struct drm_i915_private *i915 = to_i915(intel_connector->base.dev); + const struct drm_display_mode *fixed_mode = + intel_panel_fixed_mode(intel_connector, mode); + int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; + int target_clock = mode->clock; ++ enum drm_mode_status status; ++ ++ status = intel_cpu_transcoder_mode_valid(i915, mode); ++ if (status != MODE_OK) ++ return status; + + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; +diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c +index 7816b2a33feeb..2600019fc8b96 100644 +--- a/drivers/gpu/drm/i915/display/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/display/intel_hdmi.c +@@ -1987,8 +1987,9 @@ intel_hdmi_mode_valid(struct drm_connector *connector, + bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->state); + bool ycbcr_420_only; + +- if (mode->flags & DRM_MODE_FLAG_DBLSCAN) +- return MODE_NO_DBLESCAN; ++ status = intel_cpu_transcoder_mode_valid(dev_priv, mode); ++ if (status != MODE_OK) ++ return status; + + if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING) + clock *= 2; +diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c +index a749a5a66d624..40b5d3d3c7e14 100644 +--- a/drivers/gpu/drm/i915/display/intel_lvds.c ++++ b/drivers/gpu/drm/i915/display/intel_lvds.c +@@ -92,9 +92,9 @@ bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv, + + /* asserts want to know the pipe even if the port is disabled */ + if (HAS_PCH_CPT(dev_priv)) +- *pipe = (val & LVDS_PIPE_SEL_MASK_CPT) >> LVDS_PIPE_SEL_SHIFT_CPT; ++ *pipe = REG_FIELD_GET(LVDS_PIPE_SEL_MASK_CPT, val); + else +- *pipe = (val & LVDS_PIPE_SEL_MASK) >> LVDS_PIPE_SEL_SHIFT; ++ *pipe = REG_FIELD_GET(LVDS_PIPE_SEL_MASK, val); + + return val & LVDS_PORT_EN; + } +@@ -389,11 +389,16 @@ intel_lvds_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) + { + struct intel_connector *intel_connector = to_intel_connector(connector); ++ struct drm_i915_private *i915 = to_i915(intel_connector->base.dev); + const struct drm_display_mode *fixed_mode = + intel_panel_fixed_mode(intel_connector, mode); + int max_pixclk = to_i915(connector->dev)->max_dotclk_freq; + enum drm_mode_status status; + ++ status = intel_cpu_transcoder_mode_valid(i915, mode); ++ if (status != MODE_OK) ++ return status; ++ + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + +diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c +index 2c2e0f041f869..8294dddfd9de8 100644 +--- a/drivers/gpu/drm/i915/display/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/display/intel_sdvo.c +@@ -115,7 +115,6 @@ struct intel_sdvo { + + enum port port; + +- bool has_hdmi_monitor; + bool has_hdmi_audio; + + /* DDC bus used by this SDVO encoder */ +@@ -1278,10 +1277,13 @@ static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config) + pipe_config->clock_set = true; + } + +-static bool intel_has_hdmi_sink(struct intel_sdvo *sdvo, ++static bool intel_has_hdmi_sink(struct intel_sdvo_connector *intel_sdvo_connector, + const struct drm_connector_state *conn_state) + { +- return sdvo->has_hdmi_monitor && ++ struct drm_connector *connector = conn_state->connector; ++ ++ return intel_sdvo_connector->is_hdmi && ++ connector->display_info.is_hdmi && + READ_ONCE(to_intel_digital_connector_state(conn_state)->force_audio) != HDMI_AUDIO_OFF_DVI; + } + +@@ -1360,7 +1362,7 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder, + pipe_config->pixel_multiplier = + intel_sdvo_get_pixel_multiplier(adjusted_mode); + +- pipe_config->has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo, conn_state); ++ pipe_config->has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo_connector, conn_state); + + if (pipe_config->has_hdmi_sink) { + if (intel_sdvo_state->base.force_audio == HDMI_AUDIO_AUTO) +@@ -1871,13 +1873,19 @@ static enum drm_mode_status + intel_sdvo_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) + { ++ struct drm_i915_private *i915 = to_i915(connector->dev); + struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector)); + struct intel_sdvo_connector *intel_sdvo_connector = + to_intel_sdvo_connector(connector); +- int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; +- bool has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo, connector->state); ++ bool has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo_connector, connector->state); ++ int max_dotclk = i915->max_dotclk_freq; ++ enum drm_mode_status status; + int clock = mode->clock; + ++ status = intel_cpu_transcoder_mode_valid(i915, mode); ++ if (status != MODE_OK) ++ return status; ++ + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + +@@ -2064,7 +2072,6 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector) + if (edid->input & DRM_EDID_INPUT_DIGITAL) { + status = connector_status_connected; + if (intel_sdvo_connector->is_hdmi) { +- intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); + intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); + } + } else +@@ -2116,7 +2123,6 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) + + intel_sdvo->attached_output = response; + +- intel_sdvo->has_hdmi_monitor = false; + intel_sdvo->has_hdmi_audio = false; + + if ((intel_sdvo_connector->output_flag & response) == 0) +diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c +index dcf89d701f0f6..fb25be800e753 100644 +--- a/drivers/gpu/drm/i915/display/intel_tv.c ++++ b/drivers/gpu/drm/i915/display/intel_tv.c +@@ -956,8 +956,14 @@ static enum drm_mode_status + intel_tv_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) + { ++ struct drm_i915_private *i915 = to_i915(connector->dev); + const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state); +- int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; ++ int max_dotclk = i915->max_dotclk_freq; ++ enum drm_mode_status status; ++ ++ status = intel_cpu_transcoder_mode_valid(i915, mode); ++ if (status != MODE_OK) ++ return status; + + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; +diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c +index 00c80f29ad999..114088ca59ed4 100644 +--- a/drivers/gpu/drm/i915/display/vlv_dsi.c ++++ b/drivers/gpu/drm/i915/display/vlv_dsi.c +@@ -1627,9 +1627,25 @@ static const struct drm_encoder_funcs intel_dsi_funcs = { + .destroy = intel_dsi_encoder_destroy, + }; + ++static enum drm_mode_status vlv_dsi_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) ++{ ++ struct drm_i915_private *i915 = to_i915(connector->dev); ++ ++ if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { ++ enum drm_mode_status status; ++ ++ status = intel_cpu_transcoder_mode_valid(i915, mode); ++ if (status != MODE_OK) ++ return status; ++ } ++ ++ return intel_dsi_mode_valid(connector, mode); ++} ++ + static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs = { + .get_modes = intel_dsi_get_modes, +- .mode_valid = intel_dsi_mode_valid, ++ .mode_valid = vlv_dsi_mode_valid, + .atomic_check = intel_digital_connector_atomic_check, + }; + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 25015996f627a..c6766704340eb 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -2681,52 +2681,50 @@ + * Enables the LVDS port. This bit must be set before DPLLs are enabled, as + * the DPLL semantics change when the LVDS is assigned to that pipe. + */ +-#define LVDS_PORT_EN (1 << 31) ++#define LVDS_PORT_EN REG_BIT(31) + /* Selects pipe B for LVDS data. Must be set on pre-965. */ +-#define LVDS_PIPE_SEL_SHIFT 30 +-#define LVDS_PIPE_SEL_MASK (1 << 30) +-#define LVDS_PIPE_SEL(pipe) ((pipe) << 30) +-#define LVDS_PIPE_SEL_SHIFT_CPT 29 +-#define LVDS_PIPE_SEL_MASK_CPT (3 << 29) +-#define LVDS_PIPE_SEL_CPT(pipe) ((pipe) << 29) ++#define LVDS_PIPE_SEL_MASK REG_BIT(30) ++#define LVDS_PIPE_SEL(pipe) REG_FIELD_PREP(LVDS_PIPE_SEL_MASK, (pipe)) ++#define LVDS_PIPE_SEL_MASK_CPT REG_GENMASK(30, 29) ++#define LVDS_PIPE_SEL_CPT(pipe) REG_FIELD_PREP(LVDS_PIPE_SEL_MASK_CPT, (pipe)) + /* LVDS dithering flag on 965/g4x platform */ +-#define LVDS_ENABLE_DITHER (1 << 25) ++#define LVDS_ENABLE_DITHER REG_BIT(25) + /* LVDS sync polarity flags. Set to invert (i.e. negative) */ +-#define LVDS_VSYNC_POLARITY (1 << 21) +-#define LVDS_HSYNC_POLARITY (1 << 20) ++#define LVDS_VSYNC_POLARITY REG_BIT(21) ++#define LVDS_HSYNC_POLARITY REG_BIT(20) + + /* Enable border for unscaled (or aspect-scaled) display */ +-#define LVDS_BORDER_ENABLE (1 << 15) ++#define LVDS_BORDER_ENABLE REG_BIT(15) + /* + * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per + * pixel. + */ +-#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) +-#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) +-#define LVDS_A0A2_CLKA_POWER_UP (3 << 8) ++#define LVDS_A0A2_CLKA_POWER_MASK REG_GENMASK(9, 8) ++#define LVDS_A0A2_CLKA_POWER_DOWN REG_FIELD_PREP(LVDS_A0A2_CLKA_POWER_MASK, 0) ++#define LVDS_A0A2_CLKA_POWER_UP REG_FIELD_PREP(LVDS_A0A2_CLKA_POWER_MASK, 3) + /* + * Controls the A3 data pair, which contains the additional LSBs for 24 bit + * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be + * on. + */ +-#define LVDS_A3_POWER_MASK (3 << 6) +-#define LVDS_A3_POWER_DOWN (0 << 6) +-#define LVDS_A3_POWER_UP (3 << 6) ++#define LVDS_A3_POWER_MASK REG_GENMASK(7, 6) ++#define LVDS_A3_POWER_DOWN REG_FIELD_PREP(LVDS_A3_POWER_MASK, 0) ++#define LVDS_A3_POWER_UP REG_FIELD_PREP(LVDS_A3_POWER_MASK, 3) + /* + * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP + * is set. + */ +-#define LVDS_CLKB_POWER_MASK (3 << 4) +-#define LVDS_CLKB_POWER_DOWN (0 << 4) +-#define LVDS_CLKB_POWER_UP (3 << 4) ++#define LVDS_CLKB_POWER_MASK REG_GENMASK(5, 4) ++#define LVDS_CLKB_POWER_DOWN REG_FIELD_PREP(LVDS_CLKB_POWER_MASK, 0) ++#define LVDS_CLKB_POWER_UP REG_FIELD_PREP(LVDS_CLKB_POWER_MASK, 3) + /* + * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 + * setting for whether we are in dual-channel mode. The B3 pair will + * additionally only be powered up when LVDS_A3_POWER_UP is set. + */ +-#define LVDS_B0B3_POWER_MASK (3 << 2) +-#define LVDS_B0B3_POWER_DOWN (0 << 2) +-#define LVDS_B0B3_POWER_UP (3 << 2) ++#define LVDS_B0B3_POWER_MASK REG_GENMASK(3, 2) ++#define LVDS_B0B3_POWER_DOWN REG_FIELD_PREP(LVDS_B0B3_POWER_MASK, 0) ++#define LVDS_B0B3_POWER_UP REG_FIELD_PREP(LVDS_B0B3_POWER_MASK, 3) + + /* Video Data Island Packet control */ + #define VIDEO_DIP_DATA _MMIO(0x61178) +@@ -6461,7 +6459,7 @@ + #define FDI_PLL_CTL_2 _MMIO(0xfe004) + + #define PCH_LVDS _MMIO(0xe1180) +-#define LVDS_DETECTED (1 << 1) ++#define LVDS_DETECTED REG_BIT(1) + + #define _PCH_DP_B 0xe4100 + #define PCH_DP_B _MMIO(_PCH_DP_B) +diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c +index 0962c12eba5a0..2147afb725581 100644 +--- a/drivers/hwmon/acpi_power_meter.c ++++ b/drivers/hwmon/acpi_power_meter.c +@@ -31,6 +31,7 @@ + #define POWER_METER_CAN_NOTIFY (1 << 3) + #define POWER_METER_IS_BATTERY (1 << 8) + #define UNKNOWN_HYSTERESIS 0xFFFFFFFF ++#define UNKNOWN_POWER 0xFFFFFFFF + + #define METER_NOTIFY_CONFIG 0x80 + #define METER_NOTIFY_TRIP 0x81 +@@ -348,6 +349,9 @@ static ssize_t show_power(struct device *dev, + update_meter(resource); + mutex_unlock(&resource->lock); + ++ if (resource->power == UNKNOWN_POWER) ++ return -ENODATA; ++ + return sprintf(buf, "%llu\n", resource->power * 1000); + } + +diff --git a/drivers/hwmon/nzxt-kraken2.c b/drivers/hwmon/nzxt-kraken2.c +index 89f7ea4f42d47..badbcaf01f90b 100644 +--- a/drivers/hwmon/nzxt-kraken2.c ++++ b/drivers/hwmon/nzxt-kraken2.c +@@ -161,13 +161,13 @@ static int kraken2_probe(struct hid_device *hdev, + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); + if (ret) { + hid_err(hdev, "hid hw start failed with %d\n", ret); +- goto fail_and_stop; ++ return ret; + } + + ret = hid_hw_open(hdev); + if (ret) { + hid_err(hdev, "hid hw open failed with %d\n", ret); +- goto fail_and_close; ++ goto fail_and_stop; + } + + priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "kraken2", +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 1cf7478da6ee8..fda48a0afc1a5 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -2072,7 +2072,7 @@ static void clear_etmdrvdata(void *info) + etmdrvdata[cpu] = NULL; + } + +-static int __exit etm4_remove_dev(struct etmv4_drvdata *drvdata) ++static void etm4_remove_dev(struct etmv4_drvdata *drvdata) + { + etm_perf_symlink(drvdata->csdev, false); + /* +@@ -2094,10 +2094,9 @@ static int __exit etm4_remove_dev(struct etmv4_drvdata *drvdata) + cscfg_unregister_csdev(drvdata->csdev); + coresight_unregister(drvdata->csdev); + +- return 0; + } + +-static void __exit etm4_remove_amba(struct amba_device *adev) ++static void etm4_remove_amba(struct amba_device *adev) + { + struct etmv4_drvdata *drvdata = dev_get_drvdata(&adev->dev); + +@@ -2105,15 +2104,14 @@ static void __exit etm4_remove_amba(struct amba_device *adev) + etm4_remove_dev(drvdata); + } + +-static int __exit etm4_remove_platform_dev(struct platform_device *pdev) ++static int etm4_remove_platform_dev(struct platform_device *pdev) + { +- int ret = 0; + struct etmv4_drvdata *drvdata = dev_get_drvdata(&pdev->dev); + + if (drvdata) +- ret = etm4_remove_dev(drvdata); ++ etm4_remove_dev(drvdata); + pm_runtime_disable(&pdev->dev); +- return ret; ++ return 0; + } + + static const struct amba_id etm4_ids[] = { +diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c +index 4140efd664097..016220ba0addd 100644 +--- a/drivers/hwtracing/ptt/hisi_ptt.c ++++ b/drivers/hwtracing/ptt/hisi_ptt.c +@@ -837,6 +837,10 @@ static void hisi_ptt_pmu_del(struct perf_event *event, int flags) + hisi_ptt_pmu_stop(event, PERF_EF_UPDATE); + } + ++static void hisi_ptt_pmu_read(struct perf_event *event) ++{ ++} ++ + static void hisi_ptt_remove_cpuhp_instance(void *hotplug_node) + { + cpuhp_state_remove_instance_nocalls(hisi_ptt_pmu_online, hotplug_node); +@@ -880,6 +884,7 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt) + .stop = hisi_ptt_pmu_stop, + .add = hisi_ptt_pmu_add, + .del = hisi_ptt_pmu_del, ++ .read = hisi_ptt_pmu_read, + }; + + reg = readl(hisi_ptt->iobase + HISI_PTT_LOCATION); +diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c +index 6fdb25a5f8016..ad98c85ec2e7a 100644 +--- a/drivers/i2c/busses/i2c-designware-common.c ++++ b/drivers/i2c/busses/i2c-designware-common.c +@@ -63,7 +63,7 @@ static int dw_reg_read(void *context, unsigned int reg, unsigned int *val) + { + struct dw_i2c_dev *dev = context; + +- *val = readl_relaxed(dev->base + reg); ++ *val = readl(dev->base + reg); + + return 0; + } +@@ -72,7 +72,7 @@ static int dw_reg_write(void *context, unsigned int reg, unsigned int val) + { + struct dw_i2c_dev *dev = context; + +- writel_relaxed(val, dev->base + reg); ++ writel(val, dev->base + reg); + + return 0; + } +@@ -81,7 +81,7 @@ static int dw_reg_read_swab(void *context, unsigned int reg, unsigned int *val) + { + struct dw_i2c_dev *dev = context; + +- *val = swab32(readl_relaxed(dev->base + reg)); ++ *val = swab32(readl(dev->base + reg)); + + return 0; + } +@@ -90,7 +90,7 @@ static int dw_reg_write_swab(void *context, unsigned int reg, unsigned int val) + { + struct dw_i2c_dev *dev = context; + +- writel_relaxed(swab32(val), dev->base + reg); ++ writel(swab32(val), dev->base + reg); + + return 0; + } +@@ -99,8 +99,8 @@ static int dw_reg_read_word(void *context, unsigned int reg, unsigned int *val) + { + struct dw_i2c_dev *dev = context; + +- *val = readw_relaxed(dev->base + reg) | +- (readw_relaxed(dev->base + reg + 2) << 16); ++ *val = readw(dev->base + reg) | ++ (readw(dev->base + reg + 2) << 16); + + return 0; + } +@@ -109,8 +109,8 @@ static int dw_reg_write_word(void *context, unsigned int reg, unsigned int val) + { + struct dw_i2c_dev *dev = context; + +- writew_relaxed(val, dev->base + reg); +- writew_relaxed(val >> 16, dev->base + reg + 2); ++ writew(val, dev->base + reg); ++ writew(val >> 16, dev->base + reg + 2); + + return 0; + } +diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c +index 957634eceba8f..8ce569bf7525e 100644 +--- a/drivers/infiniband/core/umem.c ++++ b/drivers/infiniband/core/umem.c +@@ -96,12 +96,6 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, + return page_size; + } + +- /* rdma_for_each_block() has a bug if the page size is smaller than the +- * page size used to build the umem. For now prevent smaller page sizes +- * from being returned. +- */ +- pgsz_bitmap &= GENMASK(BITS_PER_LONG - 1, PAGE_SHIFT); +- + /* The best result is the smallest page size that results in the minimum + * number of required pages. Compute the largest page size that could + * work based on VA address bits that don't change. +diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c +index e58893387bb4d..43d396a7d8e16 100644 +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -70,7 +70,7 @@ static char version[] = + BNXT_RE_DESC "\n"; + + MODULE_AUTHOR("Eddie Wai "); +-MODULE_DESCRIPTION(BNXT_RE_DESC " Driver"); ++MODULE_DESCRIPTION(BNXT_RE_DESC); + MODULE_LICENSE("Dual BSD/GPL"); + + /* globals */ +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 8a9d28f81149a..c2ee80546d120 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -4913,10 +4913,15 @@ static int check_cong_type(struct ib_qp *ibqp, + cong_alg->wnd_mode_sel = WND_LIMIT; + break; + default: +- ibdev_err(&hr_dev->ib_dev, +- "error type(%u) for congestion selection.\n", +- hr_dev->caps.cong_type); +- return -EINVAL; ++ ibdev_warn(&hr_dev->ib_dev, ++ "invalid type(%u) for congestion selection.\n", ++ hr_dev->caps.cong_type); ++ hr_dev->caps.cong_type = CONG_TYPE_DCQCN; ++ cong_alg->alg_sel = CONG_DCQCN; ++ cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL; ++ cong_alg->dip_vld = DIP_INVALID; ++ cong_alg->wnd_mode_sel = WND_LIMIT; ++ break; + } + + return 0; +diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c +index c07ce85d243f1..311a1138e838d 100644 +--- a/drivers/infiniband/hw/irdma/hw.c ++++ b/drivers/infiniband/hw/irdma/hw.c +@@ -322,7 +322,11 @@ static void irdma_process_aeq(struct irdma_pci_f *rf) + break; + case IRDMA_AE_QP_SUSPEND_COMPLETE: + if (iwqp->iwdev->vsi.tc_change_pending) { +- atomic_dec(&iwqp->sc_qp.vsi->qp_suspend_reqs); ++ if (!atomic_dec_return(&qp->vsi->qp_suspend_reqs)) ++ wake_up(&iwqp->iwdev->suspend_wq); ++ } ++ if (iwqp->suspend_pending) { ++ iwqp->suspend_pending = false; + wake_up(&iwqp->iwdev->suspend_wq); + } + break; +@@ -568,16 +572,13 @@ static void irdma_destroy_irq(struct irdma_pci_f *rf, + * Issue destroy cqp request and + * free the resources associated with the cqp + */ +-static void irdma_destroy_cqp(struct irdma_pci_f *rf, bool free_hwcqp) ++static void irdma_destroy_cqp(struct irdma_pci_f *rf) + { + struct irdma_sc_dev *dev = &rf->sc_dev; + struct irdma_cqp *cqp = &rf->cqp; + int status = 0; + +- if (rf->cqp_cmpl_wq) +- destroy_workqueue(rf->cqp_cmpl_wq); +- if (free_hwcqp) +- status = irdma_sc_cqp_destroy(dev->cqp); ++ status = irdma_sc_cqp_destroy(dev->cqp); + if (status) + ibdev_dbg(to_ibdev(dev), "ERR: Destroy CQP failed %d\n", status); + +@@ -741,6 +742,9 @@ static void irdma_destroy_ccq(struct irdma_pci_f *rf) + struct irdma_ccq *ccq = &rf->ccq; + int status = 0; + ++ if (rf->cqp_cmpl_wq) ++ destroy_workqueue(rf->cqp_cmpl_wq); ++ + if (!rf->reset) + status = irdma_sc_ccq_destroy(dev->ccq, 0, true); + if (status) +@@ -921,8 +925,8 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) + + cqp->scratch_array = kcalloc(sqsize, sizeof(*cqp->scratch_array), GFP_KERNEL); + if (!cqp->scratch_array) { +- kfree(cqp->cqp_requests); +- return -ENOMEM; ++ status = -ENOMEM; ++ goto err_scratch; + } + + dev->cqp = &cqp->sc_cqp; +@@ -932,15 +936,14 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) + cqp->sq.va = dma_alloc_coherent(dev->hw->device, cqp->sq.size, + &cqp->sq.pa, GFP_KERNEL); + if (!cqp->sq.va) { +- kfree(cqp->scratch_array); +- kfree(cqp->cqp_requests); +- return -ENOMEM; ++ status = -ENOMEM; ++ goto err_sq; + } + + status = irdma_obj_aligned_mem(rf, &mem, sizeof(struct irdma_cqp_ctx), + IRDMA_HOST_CTX_ALIGNMENT_M); + if (status) +- goto exit; ++ goto err_ctx; + + dev->cqp->host_ctx_pa = mem.pa; + dev->cqp->host_ctx = mem.va; +@@ -966,7 +969,7 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) + status = irdma_sc_cqp_init(dev->cqp, &cqp_init_info); + if (status) { + ibdev_dbg(to_ibdev(dev), "ERR: cqp init status %d\n", status); +- goto exit; ++ goto err_ctx; + } + + spin_lock_init(&cqp->req_lock); +@@ -977,7 +980,7 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) + ibdev_dbg(to_ibdev(dev), + "ERR: cqp create failed - status %d maj_err %d min_err %d\n", + status, maj_err, min_err); +- goto exit; ++ goto err_ctx; + } + + INIT_LIST_HEAD(&cqp->cqp_avail_reqs); +@@ -991,8 +994,16 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) + init_waitqueue_head(&cqp->remove_wq); + return 0; + +-exit: +- irdma_destroy_cqp(rf, false); ++err_ctx: ++ dma_free_coherent(dev->hw->device, cqp->sq.size, ++ cqp->sq.va, cqp->sq.pa); ++ cqp->sq.va = NULL; ++err_sq: ++ kfree(cqp->scratch_array); ++ cqp->scratch_array = NULL; ++err_scratch: ++ kfree(cqp->cqp_requests); ++ cqp->cqp_requests = NULL; + + return status; + } +@@ -1159,7 +1170,6 @@ static int irdma_create_ceq(struct irdma_pci_f *rf, struct irdma_ceq *iwceq, + int status; + struct irdma_ceq_init_info info = {}; + struct irdma_sc_dev *dev = &rf->sc_dev; +- u64 scratch; + u32 ceq_size; + + info.ceq_id = ceq_id; +@@ -1180,14 +1190,13 @@ static int irdma_create_ceq(struct irdma_pci_f *rf, struct irdma_ceq *iwceq, + iwceq->sc_ceq.ceq_id = ceq_id; + info.dev = dev; + info.vsi = vsi; +- scratch = (uintptr_t)&rf->cqp.sc_cqp; + status = irdma_sc_ceq_init(&iwceq->sc_ceq, &info); + if (!status) { + if (dev->ceq_valid) + status = irdma_cqp_ceq_cmd(&rf->sc_dev, &iwceq->sc_ceq, + IRDMA_OP_CEQ_CREATE); + else +- status = irdma_sc_cceq_create(&iwceq->sc_ceq, scratch); ++ status = irdma_sc_cceq_create(&iwceq->sc_ceq, 0); + } + + if (status) { +@@ -1740,7 +1749,7 @@ void irdma_ctrl_deinit_hw(struct irdma_pci_f *rf) + rf->reset, rf->rdma_ver); + fallthrough; + case CQP_CREATED: +- irdma_destroy_cqp(rf, true); ++ irdma_destroy_cqp(rf); + fallthrough; + case INITIAL_STATE: + irdma_del_init_mem(rf); +diff --git a/drivers/infiniband/hw/irdma/main.c b/drivers/infiniband/hw/irdma/main.c +index 514453777e07d..be1030d1adfaf 100644 +--- a/drivers/infiniband/hw/irdma/main.c ++++ b/drivers/infiniband/hw/irdma/main.c +@@ -48,7 +48,7 @@ static void irdma_prep_tc_change(struct irdma_device *iwdev) + /* Wait for all qp's to suspend */ + wait_event_timeout(iwdev->suspend_wq, + !atomic_read(&iwdev->vsi.qp_suspend_reqs), +- IRDMA_EVENT_TIMEOUT); ++ msecs_to_jiffies(IRDMA_EVENT_TIMEOUT_MS)); + irdma_ws_reset(&iwdev->vsi); + } + +diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h +index 9cbe64311f985..6a6b14d8fca45 100644 +--- a/drivers/infiniband/hw/irdma/main.h ++++ b/drivers/infiniband/hw/irdma/main.h +@@ -78,7 +78,7 @@ extern struct auxiliary_driver i40iw_auxiliary_drv; + + #define MAX_DPC_ITERATIONS 128 + +-#define IRDMA_EVENT_TIMEOUT 50000 ++#define IRDMA_EVENT_TIMEOUT_MS 5000 + #define IRDMA_VCHNL_EVENT_TIMEOUT 100000 + #define IRDMA_RST_TIMEOUT_HZ 4 + +diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c +index 3b8b2341981ea..447e1bcc82a32 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -1098,6 +1098,21 @@ static int irdma_query_pkey(struct ib_device *ibdev, u32 port, u16 index, + return 0; + } + ++static int irdma_wait_for_suspend(struct irdma_qp *iwqp) ++{ ++ if (!wait_event_timeout(iwqp->iwdev->suspend_wq, ++ !iwqp->suspend_pending, ++ msecs_to_jiffies(IRDMA_EVENT_TIMEOUT_MS))) { ++ iwqp->suspend_pending = false; ++ ibdev_warn(&iwqp->iwdev->ibdev, ++ "modify_qp timed out waiting for suspend. qp_id = %d, last_ae = 0x%x\n", ++ iwqp->ibqp.qp_num, iwqp->last_aeq); ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++ + /** + * irdma_modify_qp_roce - modify qp request + * @ibqp: qp's pointer for modify +@@ -1359,17 +1374,11 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr, + + info.next_iwarp_state = IRDMA_QP_STATE_SQD; + issue_modify_qp = 1; ++ iwqp->suspend_pending = true; + break; + case IB_QPS_SQE: + case IB_QPS_ERR: + case IB_QPS_RESET: +- if (iwqp->iwarp_state == IRDMA_QP_STATE_RTS) { +- spin_unlock_irqrestore(&iwqp->lock, flags); +- info.next_iwarp_state = IRDMA_QP_STATE_SQD; +- irdma_hw_modify_qp(iwdev, iwqp, &info, true); +- spin_lock_irqsave(&iwqp->lock, flags); +- } +- + if (iwqp->iwarp_state == IRDMA_QP_STATE_ERROR) { + spin_unlock_irqrestore(&iwqp->lock, flags); + if (udata && udata->inlen) { +@@ -1406,6 +1415,11 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr, + ctx_info->rem_endpoint_idx = udp_info->arp_idx; + if (irdma_hw_modify_qp(iwdev, iwqp, &info, true)) + return -EINVAL; ++ if (info.next_iwarp_state == IRDMA_QP_STATE_SQD) { ++ ret = irdma_wait_for_suspend(iwqp); ++ if (ret) ++ return ret; ++ } + spin_lock_irqsave(&iwqp->lock, flags); + if (iwqp->iwarp_state == info.curr_iwarp_state) { + iwqp->iwarp_state = info.next_iwarp_state; +diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h +index a536e9fa85ebf..9f9e273bbff3e 100644 +--- a/drivers/infiniband/hw/irdma/verbs.h ++++ b/drivers/infiniband/hw/irdma/verbs.h +@@ -193,6 +193,7 @@ struct irdma_qp { + u8 flush_issued : 1; + u8 sig_all : 1; + u8 pau_mode : 1; ++ u8 suspend_pending : 1; + u8 rsvd : 1; + u8 iwarp_state; + u16 term_sq_flush_code; +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c +index a67f58359de9e..cc07c91f9c549 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c +@@ -382,7 +382,7 @@ static void complete_rdma_req(struct rtrs_clt_io_req *req, int errno, + struct rtrs_clt_path *clt_path; + int err; + +- if (WARN_ON(!req->in_use)) ++ if (!req->in_use) + return; + if (WARN_ON(!req->con)) + return; +@@ -1694,7 +1694,7 @@ static int create_con_cq_qp(struct rtrs_clt_con *con) + clt_path->s.dev_ref++; + max_send_wr = min_t(int, wr_limit, + /* QD * (REQ + RSP + FR REGS or INVS) + drain */ +- clt_path->queue_depth * 3 + 1); ++ clt_path->queue_depth * 4 + 1); + max_recv_wr = min_t(int, wr_limit, + clt_path->queue_depth * 3 + 1); + max_send_sge = 2; +@@ -2346,8 +2346,6 @@ static int init_conns(struct rtrs_clt_path *clt_path) + if (err) + goto destroy; + +- rtrs_start_hb(&clt_path->s); +- + return 0; + + destroy: +@@ -2621,6 +2619,7 @@ static int init_path(struct rtrs_clt_path *clt_path) + goto out; + } + rtrs_clt_path_up(clt_path); ++ rtrs_start_hb(&clt_path->s); + out: + mutex_unlock(&clt_path->init_mutex); + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index 22d7ba05e9fe8..e978ee4bb73ae 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -63,8 +63,9 @@ static bool rtrs_srv_change_state(struct rtrs_srv_path *srv_path, + { + enum rtrs_srv_state old_state; + bool changed = false; ++ unsigned long flags; + +- spin_lock_irq(&srv_path->state_lock); ++ spin_lock_irqsave(&srv_path->state_lock, flags); + old_state = srv_path->state; + switch (new_state) { + case RTRS_SRV_CONNECTED: +@@ -85,7 +86,7 @@ static bool rtrs_srv_change_state(struct rtrs_srv_path *srv_path, + } + if (changed) + srv_path->state = new_state; +- spin_unlock_irq(&srv_path->state_lock); ++ spin_unlock_irqrestore(&srv_path->state_lock, flags); + + return changed; + } +@@ -548,7 +549,10 @@ static void unmap_cont_bufs(struct rtrs_srv_path *srv_path) + struct rtrs_srv_mr *srv_mr; + + srv_mr = &srv_path->mrs[i]; +- rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1); ++ ++ if (always_invalidate) ++ rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1); ++ + ib_dereg_mr(srv_mr->mr); + ib_dma_unmap_sg(srv_path->s.dev->ib_dev, srv_mr->sgt.sgl, + srv_mr->sgt.nents, DMA_BIDIRECTIONAL); +@@ -714,20 +718,23 @@ static void rtrs_srv_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc) + WARN_ON(wc->opcode != IB_WC_SEND); + } + +-static void rtrs_srv_path_up(struct rtrs_srv_path *srv_path) ++static int rtrs_srv_path_up(struct rtrs_srv_path *srv_path) + { + struct rtrs_srv_sess *srv = srv_path->srv; + struct rtrs_srv_ctx *ctx = srv->ctx; +- int up; ++ int up, ret = 0; + + mutex_lock(&srv->paths_ev_mutex); + up = ++srv->paths_up; + if (up == 1) +- ctx->ops.link_ev(srv, RTRS_SRV_LINK_EV_CONNECTED, NULL); ++ ret = ctx->ops.link_ev(srv, RTRS_SRV_LINK_EV_CONNECTED, NULL); + mutex_unlock(&srv->paths_ev_mutex); + + /* Mark session as established */ +- srv_path->established = true; ++ if (!ret) ++ srv_path->established = true; ++ ++ return ret; + } + + static void rtrs_srv_path_down(struct rtrs_srv_path *srv_path) +@@ -856,7 +863,12 @@ static int process_info_req(struct rtrs_srv_con *con, + goto iu_free; + kobject_get(&srv_path->kobj); + get_device(&srv_path->srv->dev); +- rtrs_srv_change_state(srv_path, RTRS_SRV_CONNECTED); ++ err = rtrs_srv_change_state(srv_path, RTRS_SRV_CONNECTED); ++ if (!err) { ++ rtrs_err(s, "rtrs_srv_change_state(), err: %d\n", err); ++ goto iu_free; ++ } ++ + rtrs_srv_start_hb(srv_path); + + /* +@@ -865,7 +877,11 @@ static int process_info_req(struct rtrs_srv_con *con, + * all connections are successfully established. Thus, simply notify + * listener with a proper event if we are the first path. + */ +- rtrs_srv_path_up(srv_path); ++ err = rtrs_srv_path_up(srv_path); ++ if (err) { ++ rtrs_err(s, "rtrs_srv_path_up(), err: %d\n", err); ++ goto iu_free; ++ } + + ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev, + tx_iu->dma_addr, +@@ -1521,7 +1537,6 @@ static void rtrs_srv_close_work(struct work_struct *work) + + srv_path = container_of(work, typeof(*srv_path), close_work); + +- rtrs_srv_destroy_path_files(srv_path); + rtrs_srv_stop_hb(srv_path); + + for (i = 0; i < srv_path->s.con_num; i++) { +@@ -1541,6 +1556,8 @@ static void rtrs_srv_close_work(struct work_struct *work) + /* Wait for all completion */ + wait_for_completion(&srv_path->complete_done); + ++ rtrs_srv_destroy_path_files(srv_path); ++ + /* Notify upper layer if we are the last path */ + rtrs_srv_path_down(srv_path); + +diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c +index 2bcd1f23d07d2..8b38972394776 100644 +--- a/drivers/iommu/iommu.c ++++ b/drivers/iommu/iommu.c +@@ -278,12 +278,13 @@ static void dev_iommu_free(struct device *dev) + kfree(param); + } + ++DEFINE_MUTEX(iommu_probe_device_lock); ++ + static int __iommu_probe_device(struct device *dev, struct list_head *group_list) + { + const struct iommu_ops *ops = dev->bus->iommu_ops; + struct iommu_device *iommu_dev; + struct iommu_group *group; +- static DEFINE_MUTEX(iommu_probe_device_lock); + int ret; + + if (!ops) +@@ -295,11 +296,9 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list + * probably be able to use device_lock() here to minimise the scope, + * but for now enforcing a simple global ordering is fine. + */ +- mutex_lock(&iommu_probe_device_lock); +- if (!dev_iommu_get(dev)) { +- ret = -ENOMEM; +- goto err_unlock; +- } ++ lockdep_assert_held(&iommu_probe_device_lock); ++ if (!dev_iommu_get(dev)) ++ return -ENOMEM; + + if (!try_module_get(ops->owner)) { + ret = -EINVAL; +@@ -326,7 +325,6 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list + mutex_unlock(&group->mutex); + iommu_group_put(group); + +- mutex_unlock(&iommu_probe_device_lock); + iommu_device_link(iommu_dev, dev); + + return 0; +@@ -341,9 +339,6 @@ out_module_put: + err_free: + dev_iommu_free(dev); + +-err_unlock: +- mutex_unlock(&iommu_probe_device_lock); +- + return ret; + } + +@@ -353,7 +348,9 @@ int iommu_probe_device(struct device *dev) + struct iommu_group *group; + int ret; + ++ mutex_lock(&iommu_probe_device_lock); + ret = __iommu_probe_device(dev, NULL); ++ mutex_unlock(&iommu_probe_device_lock); + if (ret) + goto err_out; + +@@ -1684,7 +1681,9 @@ static int probe_iommu_group(struct device *dev, void *data) + return 0; + } + ++ mutex_lock(&iommu_probe_device_lock); + ret = __iommu_probe_device(dev, group_list); ++ mutex_unlock(&iommu_probe_device_lock); + if (ret == -ENODEV) + ret = 0; + +diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c +index 5696314ae69e7..1fa1db3be8529 100644 +--- a/drivers/iommu/of_iommu.c ++++ b/drivers/iommu/of_iommu.c +@@ -112,16 +112,20 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, + const u32 *id) + { + const struct iommu_ops *ops = NULL; +- struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); ++ struct iommu_fwspec *fwspec; + int err = NO_IOMMU; + + if (!master_np) + return NULL; + ++ /* Serialise to make dev->iommu stable under our potential fwspec */ ++ mutex_lock(&iommu_probe_device_lock); ++ fwspec = dev_iommu_fwspec_get(dev); + if (fwspec) { +- if (fwspec->ops) ++ if (fwspec->ops) { ++ mutex_unlock(&iommu_probe_device_lock); + return fwspec->ops; +- ++ } + /* In the deferred case, start again from scratch */ + iommu_fwspec_free(dev); + } +@@ -155,6 +159,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, + fwspec = dev_iommu_fwspec_get(dev); + ops = fwspec->ops; + } ++ mutex_unlock(&iommu_probe_device_lock); ++ + /* + * If we have reason to believe the IOMMU driver missed the initial + * probe for dev, replay it to get things in order. +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 20f67edae95d0..0c2801d770901 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -93,6 +93,18 @@ static int remove_and_add_spares(struct mddev *mddev, + struct md_rdev *this); + static void mddev_detach(struct mddev *mddev); + ++enum md_ro_state { ++ MD_RDWR, ++ MD_RDONLY, ++ MD_AUTO_READ, ++ MD_MAX_STATE ++}; ++ ++static bool md_is_rdwr(struct mddev *mddev) ++{ ++ return (mddev->ro == MD_RDWR); ++} ++ + /* + * Default number of read corrections we'll attempt on an rdev + * before ejecting it from the array. We divide the read error +@@ -444,7 +456,7 @@ static void md_submit_bio(struct bio *bio) + if (!bio) + return; + +- if (mddev->ro == 1 && unlikely(rw == WRITE)) { ++ if (mddev->ro == MD_RDONLY && unlikely(rw == WRITE)) { + if (bio_sectors(bio) != 0) + bio->bi_status = BLK_STS_IOERR; + bio_endio(bio); +@@ -2643,7 +2655,7 @@ void md_update_sb(struct mddev *mddev, int force_change) + int any_badblocks_changed = 0; + int ret = -1; + +- if (mddev->ro) { ++ if (!md_is_rdwr(mddev)) { + if (force_change) + set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags); + return; +@@ -3909,7 +3921,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len) + goto out_unlock; + } + rv = -EROFS; +- if (mddev->ro) ++ if (!md_is_rdwr(mddev)) + goto out_unlock; + + /* request to change the personality. Need to ensure: +@@ -4115,7 +4127,7 @@ layout_store(struct mddev *mddev, const char *buf, size_t len) + if (mddev->pers) { + if (mddev->pers->check_reshape == NULL) + err = -EBUSY; +- else if (mddev->ro) ++ else if (!md_is_rdwr(mddev)) + err = -EROFS; + else { + mddev->new_layout = n; +@@ -4224,7 +4236,7 @@ chunk_size_store(struct mddev *mddev, const char *buf, size_t len) + if (mddev->pers) { + if (mddev->pers->check_reshape == NULL) + err = -EBUSY; +- else if (mddev->ro) ++ else if (!md_is_rdwr(mddev)) + err = -EROFS; + else { + mddev->new_chunk_sectors = n >> 9; +@@ -4347,13 +4359,13 @@ array_state_show(struct mddev *mddev, char *page) + + if (mddev->pers && !test_bit(MD_NOT_READY, &mddev->flags)) { + switch(mddev->ro) { +- case 1: ++ case MD_RDONLY: + st = readonly; + break; +- case 2: ++ case MD_AUTO_READ: + st = read_auto; + break; +- case 0: ++ case MD_RDWR: + spin_lock(&mddev->lock); + if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) + st = write_pending; +@@ -4389,7 +4401,8 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) + int err = 0; + enum array_state st = match_word(buf, array_states); + +- if (mddev->pers && (st == active || st == clean) && mddev->ro != 1) { ++ if (mddev->pers && (st == active || st == clean) && ++ mddev->ro != MD_RDONLY) { + /* don't take reconfig_mutex when toggling between + * clean and active + */ +@@ -4433,23 +4446,23 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) + if (mddev->pers) + err = md_set_readonly(mddev, NULL); + else { +- mddev->ro = 1; ++ mddev->ro = MD_RDONLY; + set_disk_ro(mddev->gendisk, 1); + err = do_md_run(mddev); + } + break; + case read_auto: + if (mddev->pers) { +- if (mddev->ro == 0) ++ if (md_is_rdwr(mddev)) + err = md_set_readonly(mddev, NULL); +- else if (mddev->ro == 1) ++ else if (mddev->ro == MD_RDONLY) + err = restart_array(mddev); + if (err == 0) { +- mddev->ro = 2; ++ mddev->ro = MD_AUTO_READ; + set_disk_ro(mddev->gendisk, 0); + } + } else { +- mddev->ro = 2; ++ mddev->ro = MD_AUTO_READ; + err = do_md_run(mddev); + } + break; +@@ -4474,7 +4487,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) + wake_up(&mddev->sb_wait); + err = 0; + } else { +- mddev->ro = 0; ++ mddev->ro = MD_RDWR; + set_disk_ro(mddev->gendisk, 0); + err = do_md_run(mddev); + } +@@ -4775,7 +4788,7 @@ action_show(struct mddev *mddev, char *page) + if (test_bit(MD_RECOVERY_FROZEN, &recovery)) + type = "frozen"; + else if (test_bit(MD_RECOVERY_RUNNING, &recovery) || +- (!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &recovery))) { ++ (md_is_rdwr(mddev) && test_bit(MD_RECOVERY_NEEDED, &recovery))) { + if (test_bit(MD_RECOVERY_RESHAPE, &recovery)) + type = "reshape"; + else if (test_bit(MD_RECOVERY_SYNC, &recovery)) { +@@ -4861,11 +4874,11 @@ action_store(struct mddev *mddev, const char *page, size_t len) + set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); + set_bit(MD_RECOVERY_SYNC, &mddev->recovery); + } +- if (mddev->ro == 2) { ++ if (mddev->ro == MD_AUTO_READ) { + /* A write to sync_action is enough to justify + * canceling read-auto mode + */ +- mddev->ro = 0; ++ mddev->ro = MD_RDWR; + md_wakeup_thread(mddev->sync_thread); + } + set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); +@@ -5093,8 +5106,7 @@ max_sync_store(struct mddev *mddev, const char *buf, size_t len) + goto out_unlock; + + err = -EBUSY; +- if (max < mddev->resync_max && +- mddev->ro == 0 && ++ if (max < mddev->resync_max && md_is_rdwr(mddev) && + test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) + goto out_unlock; + +@@ -5829,8 +5841,8 @@ int md_run(struct mddev *mddev) + continue; + sync_blockdev(rdev->bdev); + invalidate_bdev(rdev->bdev); +- if (mddev->ro != 1 && rdev_read_only(rdev)) { +- mddev->ro = 1; ++ if (mddev->ro != MD_RDONLY && rdev_read_only(rdev)) { ++ mddev->ro = MD_RDONLY; + if (mddev->gendisk) + set_disk_ro(mddev->gendisk, 1); + } +@@ -5938,8 +5950,8 @@ int md_run(struct mddev *mddev) + + mddev->ok_start_degraded = start_dirty_degraded; + +- if (start_readonly && mddev->ro == 0) +- mddev->ro = 2; /* read-only, but switch on first write */ ++ if (start_readonly && md_is_rdwr(mddev)) ++ mddev->ro = MD_AUTO_READ; /* read-only, but switch on first write */ + + err = pers->run(mddev); + if (err) +@@ -6017,8 +6029,8 @@ int md_run(struct mddev *mddev) + mddev->sysfs_action = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_action"); + mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed"); + mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded"); +- } else if (mddev->ro == 2) /* auto-readonly not meaningful */ +- mddev->ro = 0; ++ } else if (mddev->ro == MD_AUTO_READ) ++ mddev->ro = MD_RDWR; + + atomic_set(&mddev->max_corr_read_errors, + MD_DEFAULT_MAX_CORRECTED_READ_ERRORS); +@@ -6036,7 +6048,7 @@ int md_run(struct mddev *mddev) + if (rdev->raid_disk >= 0) + sysfs_link_rdev(mddev, rdev); /* failure here is OK */ + +- if (mddev->degraded && !mddev->ro) ++ if (mddev->degraded && md_is_rdwr(mddev)) + /* This ensures that recovering status is reported immediately + * via sysfs - until a lack of spares is confirmed. + */ +@@ -6128,7 +6140,7 @@ static int restart_array(struct mddev *mddev) + return -ENXIO; + if (!mddev->pers) + return -EINVAL; +- if (!mddev->ro) ++ if (md_is_rdwr(mddev)) + return -EBUSY; + + rcu_read_lock(); +@@ -6147,7 +6159,7 @@ static int restart_array(struct mddev *mddev) + return -EROFS; + + mddev->safemode = 0; +- mddev->ro = 0; ++ mddev->ro = MD_RDWR; + set_disk_ro(disk, 0); + pr_debug("md: %s switched to read-write mode.\n", mdname(mddev)); + /* Kick recovery or resync if necessary */ +@@ -6174,7 +6186,7 @@ static void md_clean(struct mddev *mddev) + mddev->clevel[0] = 0; + mddev->flags = 0; + mddev->sb_flags = 0; +- mddev->ro = 0; ++ mddev->ro = MD_RDWR; + mddev->metadata_type[0] = 0; + mddev->chunk_sectors = 0; + mddev->ctime = mddev->utime = 0; +@@ -6226,7 +6238,7 @@ static void __md_stop_writes(struct mddev *mddev) + } + md_bitmap_flush(mddev); + +- if (mddev->ro == 0 && ++ if (md_is_rdwr(mddev) && + ((!mddev->in_sync && !mddev_is_clustered(mddev)) || + mddev->sb_flags)) { + /* mark array as shutdown cleanly */ +@@ -6302,6 +6314,9 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) + int err = 0; + int did_freeze = 0; + ++ if (mddev->external && test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) ++ return -EBUSY; ++ + if (!test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) { + did_freeze = 1; + set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); +@@ -6314,8 +6329,6 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) + * which will now never happen */ + wake_up_process(mddev->sync_thread->tsk); + +- if (mddev->external && test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) +- return -EBUSY; + mddev_unlock(mddev); + wait_event(resync_wait, !test_bit(MD_RECOVERY_RUNNING, + &mddev->recovery)); +@@ -6328,29 +6341,30 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) + mddev->sync_thread || + test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) { + pr_warn("md: %s still in use.\n",mdname(mddev)); +- if (did_freeze) { +- clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); +- set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); +- md_wakeup_thread(mddev->thread); +- } + err = -EBUSY; + goto out; + } ++ + if (mddev->pers) { + __md_stop_writes(mddev); + +- err = -ENXIO; +- if (mddev->ro==1) ++ if (mddev->ro == MD_RDONLY) { ++ err = -ENXIO; + goto out; +- mddev->ro = 1; ++ } ++ ++ mddev->ro = MD_RDONLY; + set_disk_ro(mddev->gendisk, 1); ++ } ++ ++out: ++ if ((mddev->pers && !err) || did_freeze) { + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); + set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); + md_wakeup_thread(mddev->thread); + sysfs_notify_dirent_safe(mddev->sysfs_state); +- err = 0; + } +-out: ++ + mutex_unlock(&mddev->open_mutex); + return err; + } +@@ -6399,7 +6413,7 @@ static int do_md_stop(struct mddev *mddev, int mode, + return -EBUSY; + } + if (mddev->pers) { +- if (mddev->ro) ++ if (!md_is_rdwr(mddev)) + set_disk_ro(disk, 0); + + __md_stop_writes(mddev); +@@ -6416,8 +6430,8 @@ static int do_md_stop(struct mddev *mddev, int mode, + mutex_unlock(&mddev->open_mutex); + mddev->changed = 1; + +- if (mddev->ro) +- mddev->ro = 0; ++ if (!md_is_rdwr(mddev)) ++ mddev->ro = MD_RDWR; + } else + mutex_unlock(&mddev->open_mutex); + /* +@@ -7232,7 +7246,7 @@ static int update_size(struct mddev *mddev, sector_t num_sectors) + if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || + mddev->sync_thread) + return -EBUSY; +- if (mddev->ro) ++ if (!md_is_rdwr(mddev)) + return -EROFS; + + rdev_for_each(rdev, mddev) { +@@ -7262,7 +7276,7 @@ static int update_raid_disks(struct mddev *mddev, int raid_disks) + /* change the number of raid disks */ + if (mddev->pers->check_reshape == NULL) + return -EINVAL; +- if (mddev->ro) ++ if (!md_is_rdwr(mddev)) + return -EROFS; + if (raid_disks <= 0 || + (mddev->max_disks && raid_disks >= mddev->max_disks)) +@@ -7686,26 +7700,25 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, + * The remaining ioctls are changing the state of the + * superblock, so we do not allow them on read-only arrays. + */ +- if (mddev->ro && mddev->pers) { +- if (mddev->ro == 2) { +- mddev->ro = 0; +- sysfs_notify_dirent_safe(mddev->sysfs_state); +- set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); +- /* mddev_unlock will wake thread */ +- /* If a device failed while we were read-only, we +- * need to make sure the metadata is updated now. +- */ +- if (test_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags)) { +- mddev_unlock(mddev); +- wait_event(mddev->sb_wait, +- !test_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags) && +- !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)); +- mddev_lock_nointr(mddev); +- } +- } else { ++ if (!md_is_rdwr(mddev) && mddev->pers) { ++ if (mddev->ro != MD_AUTO_READ) { + err = -EROFS; + goto unlock; + } ++ mddev->ro = MD_RDWR; ++ sysfs_notify_dirent_safe(mddev->sysfs_state); ++ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); ++ /* mddev_unlock will wake thread */ ++ /* If a device failed while we were read-only, we ++ * need to make sure the metadata is updated now. ++ */ ++ if (test_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags)) { ++ mddev_unlock(mddev); ++ wait_event(mddev->sb_wait, ++ !test_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags) && ++ !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)); ++ mddev_lock_nointr(mddev); ++ } + } + + switch (cmd) { +@@ -7791,11 +7804,11 @@ static int md_set_read_only(struct block_device *bdev, bool ro) + * Transitioning to read-auto need only happen for arrays that call + * md_write_start and which are not ready for writes yet. + */ +- if (!ro && mddev->ro == 1 && mddev->pers) { ++ if (!ro && mddev->ro == MD_RDONLY && mddev->pers) { + err = restart_array(mddev); + if (err) + goto out_unlock; +- mddev->ro = 2; ++ mddev->ro = MD_AUTO_READ; + } + + out_unlock: +@@ -8269,9 +8282,9 @@ static int md_seq_show(struct seq_file *seq, void *v) + seq_printf(seq, "%s : %sactive", mdname(mddev), + mddev->pers ? "" : "in"); + if (mddev->pers) { +- if (mddev->ro==1) ++ if (mddev->ro == MD_RDONLY) + seq_printf(seq, " (read-only)"); +- if (mddev->ro==2) ++ if (mddev->ro == MD_AUTO_READ) + seq_printf(seq, " (auto-read-only)"); + seq_printf(seq, " %s", mddev->pers->name); + } +@@ -8530,10 +8543,10 @@ bool md_write_start(struct mddev *mddev, struct bio *bi) + if (bio_data_dir(bi) != WRITE) + return true; + +- BUG_ON(mddev->ro == 1); +- if (mddev->ro == 2) { ++ BUG_ON(mddev->ro == MD_RDONLY); ++ if (mddev->ro == MD_AUTO_READ) { + /* need to switch to read/write */ +- mddev->ro = 0; ++ mddev->ro = MD_RDWR; + set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); + md_wakeup_thread(mddev->thread); + md_wakeup_thread(mddev->sync_thread); +@@ -8584,7 +8597,7 @@ void md_write_inc(struct mddev *mddev, struct bio *bi) + { + if (bio_data_dir(bi) != WRITE) + return; +- WARN_ON_ONCE(mddev->in_sync || mddev->ro); ++ WARN_ON_ONCE(mddev->in_sync || !md_is_rdwr(mddev)); + percpu_ref_get(&mddev->writes_pending); + } + EXPORT_SYMBOL(md_write_inc); +@@ -8690,7 +8703,7 @@ void md_allow_write(struct mddev *mddev) + { + if (!mddev->pers) + return; +- if (mddev->ro) ++ if (!md_is_rdwr(mddev)) + return; + if (!mddev->pers->sync_request) + return; +@@ -8738,7 +8751,7 @@ void md_do_sync(struct md_thread *thread) + if (test_bit(MD_RECOVERY_DONE, &mddev->recovery) || + test_bit(MD_RECOVERY_WAIT, &mddev->recovery)) + return; +- if (mddev->ro) {/* never try to sync a read-only array */ ++ if (!md_is_rdwr(mddev)) {/* never try to sync a read-only array */ + set_bit(MD_RECOVERY_INTR, &mddev->recovery); + return; + } +@@ -9207,9 +9220,9 @@ static int remove_and_add_spares(struct mddev *mddev, + if (test_bit(Faulty, &rdev->flags)) + continue; + if (!test_bit(Journal, &rdev->flags)) { +- if (mddev->ro && +- ! (rdev->saved_raid_disk >= 0 && +- !test_bit(Bitmap_sync, &rdev->flags))) ++ if (!md_is_rdwr(mddev) && ++ !(rdev->saved_raid_disk >= 0 && ++ !test_bit(Bitmap_sync, &rdev->flags))) + continue; + + rdev->recovery_offset = 0; +@@ -9307,7 +9320,8 @@ void md_check_recovery(struct mddev *mddev) + flush_signals(current); + } + +- if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) ++ if (!md_is_rdwr(mddev) && ++ !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) + return; + if ( ! ( + (mddev->sb_flags & ~ (1<external && mddev->safemode == 1) + mddev->safemode = 0; + +- if (mddev->ro) { ++ if (!md_is_rdwr(mddev)) { + struct md_rdev *rdev; + if (!mddev->external && mddev->in_sync) + /* 'Blocked' flag not needed as failed devices +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 98d4e93efa31c..e4564ca1f2434 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -5905,11 +5905,11 @@ static bool stripe_ahead_of_reshape(struct mddev *mddev, struct r5conf *conf, + int dd_idx; + + for (dd_idx = 0; dd_idx < sh->disks; dd_idx++) { +- if (dd_idx == sh->pd_idx) ++ if (dd_idx == sh->pd_idx || dd_idx == sh->qd_idx) + continue; + + min_sector = min(min_sector, sh->dev[dd_idx].sector); +- max_sector = min(max_sector, sh->dev[dd_idx].sector); ++ max_sector = max(max_sector, sh->dev[dd_idx].sector); + } + + spin_lock_irq(&conf->device_lock); +diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c +index 0b2fbe1335a77..c70c89209fe55 100644 +--- a/drivers/misc/mei/client.c ++++ b/drivers/misc/mei/client.c +@@ -1978,7 +1978,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) + + mei_hdr = mei_msg_hdr_init(cb); + if (IS_ERR(mei_hdr)) { +- rets = -PTR_ERR(mei_hdr); ++ rets = PTR_ERR(mei_hdr); + mei_hdr = NULL; + goto err; + } +@@ -2002,7 +2002,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) + + hbuf_slots = mei_hbuf_empty_slots(dev); + if (hbuf_slots < 0) { +- rets = -EOVERFLOW; ++ buf_len = -EOVERFLOW; + goto out; + } + +diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h +index 19e996a829c9d..b54275389f8ac 100644 +--- a/drivers/net/arcnet/arcdevice.h ++++ b/drivers/net/arcnet/arcdevice.h +@@ -186,6 +186,8 @@ do { \ + #define ARC_IS_5MBIT 1 /* card default speed is 5MBit */ + #define ARC_CAN_10MBIT 2 /* card uses COM20022, supporting 10MBit, + but default is 2.5MBit. */ ++#define ARC_HAS_LED 4 /* card has software controlled LEDs */ ++#define ARC_HAS_ROTARY 8 /* card has rotary encoder */ + + /* information needed to define an encapsulation driver */ + struct ArcProto { +diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c +index c580acb8b1d34..7b5c8bb02f119 100644 +--- a/drivers/net/arcnet/com20020-pci.c ++++ b/drivers/net/arcnet/com20020-pci.c +@@ -213,12 +213,13 @@ static int com20020pci_probe(struct pci_dev *pdev, + if (!strncmp(ci->name, "EAE PLX-PCI FB2", 15)) + lp->backplane = 1; + +- /* Get the dev_id from the PLX rotary coder */ +- if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) +- dev_id_mask = 0x3; +- dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask; +- +- snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); ++ if (ci->flags & ARC_HAS_ROTARY) { ++ /* Get the dev_id from the PLX rotary coder */ ++ if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) ++ dev_id_mask = 0x3; ++ dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask; ++ snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); ++ } + + if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { + pr_err("IO address %Xh is empty!\n", ioaddr); +@@ -230,6 +231,10 @@ static int com20020pci_probe(struct pci_dev *pdev, + goto err_free_arcdev; + } + ++ ret = com20020_found(dev, IRQF_SHARED); ++ if (ret) ++ goto err_free_arcdev; ++ + card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev), + GFP_KERNEL); + if (!card) { +@@ -239,41 +244,39 @@ static int com20020pci_probe(struct pci_dev *pdev, + + card->index = i; + card->pci_priv = priv; +- card->tx_led.brightness_set = led_tx_set; +- card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, +- GFP_KERNEL, "arc%d-%d-tx", +- dev->dev_id, i); +- card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, +- "pci:green:tx:%d-%d", +- dev->dev_id, i); +- +- card->tx_led.dev = &dev->dev; +- card->recon_led.brightness_set = led_recon_set; +- card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, +- GFP_KERNEL, "arc%d-%d-recon", +- dev->dev_id, i); +- card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, +- "pci:red:recon:%d-%d", +- dev->dev_id, i); +- card->recon_led.dev = &dev->dev; +- card->dev = dev; +- +- ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); +- if (ret) +- goto err_free_arcdev; + +- ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); +- if (ret) +- goto err_free_arcdev; +- +- dev_set_drvdata(&dev->dev, card); +- +- ret = com20020_found(dev, IRQF_SHARED); +- if (ret) +- goto err_free_arcdev; +- +- devm_arcnet_led_init(dev, dev->dev_id, i); ++ if (ci->flags & ARC_HAS_LED) { ++ card->tx_led.brightness_set = led_tx_set; ++ card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, ++ GFP_KERNEL, "arc%d-%d-tx", ++ dev->dev_id, i); ++ card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, ++ "pci:green:tx:%d-%d", ++ dev->dev_id, i); ++ ++ card->tx_led.dev = &dev->dev; ++ card->recon_led.brightness_set = led_recon_set; ++ card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, ++ GFP_KERNEL, "arc%d-%d-recon", ++ dev->dev_id, i); ++ card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, ++ "pci:red:recon:%d-%d", ++ dev->dev_id, i); ++ card->recon_led.dev = &dev->dev; ++ ++ ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); ++ if (ret) ++ goto err_free_arcdev; ++ ++ ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); ++ if (ret) ++ goto err_free_arcdev; ++ ++ dev_set_drvdata(&dev->dev, card); ++ devm_arcnet_led_init(dev, dev->dev_id, i); ++ } + ++ card->dev = dev; + list_add(&card->list, &priv->list_dev); + continue; + +@@ -329,7 +332,7 @@ static struct com20020_pci_card_info card_info_5mbit = { + }; + + static struct com20020_pci_card_info card_info_sohard = { +- .name = "PLX-PCI", ++ .name = "SOHARD SH ARC-PCI", + .devcount = 1, + /* SOHARD needs PCI base addr 4 */ + .chan_map_tbl = { +@@ -364,7 +367,7 @@ static struct com20020_pci_card_info card_info_eae_arc1 = { + }, + }, + .rotary = 0x0, +- .flags = ARC_CAN_10MBIT, ++ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, + }; + + static struct com20020_pci_card_info card_info_eae_ma1 = { +@@ -396,7 +399,7 @@ static struct com20020_pci_card_info card_info_eae_ma1 = { + }, + }, + .rotary = 0x0, +- .flags = ARC_CAN_10MBIT, ++ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, + }; + + static struct com20020_pci_card_info card_info_eae_fb2 = { +@@ -421,7 +424,7 @@ static struct com20020_pci_card_info card_info_eae_fb2 = { + }, + }, + .rotary = 0x0, +- .flags = ARC_CAN_10MBIT, ++ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, + }; + + static const struct pci_device_id com20020pci_id_table[] = { +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c +index 80b44043e6c53..28c9b6f1a54f1 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c +@@ -553,17 +553,17 @@ void aq_ptp_tx_hwtstamp(struct aq_nic_s *aq_nic, u64 timestamp) + + /* aq_ptp_rx_hwtstamp - utility function which checks for RX time stamp + * @adapter: pointer to adapter struct +- * @skb: particular skb to send timestamp with ++ * @shhwtstamps: particular skb_shared_hwtstamps to save timestamp + * + * if the timestamp is valid, we convert it into the timecounter ns + * value, then store that result into the hwtstamps structure which + * is passed up the network stack + */ +-static void aq_ptp_rx_hwtstamp(struct aq_ptp_s *aq_ptp, struct sk_buff *skb, ++static void aq_ptp_rx_hwtstamp(struct aq_ptp_s *aq_ptp, struct skb_shared_hwtstamps *shhwtstamps, + u64 timestamp) + { + timestamp -= atomic_read(&aq_ptp->offset_ingress); +- aq_ptp_convert_to_hwtstamp(aq_ptp, skb_hwtstamps(skb), timestamp); ++ aq_ptp_convert_to_hwtstamp(aq_ptp, shhwtstamps, timestamp); + } + + void aq_ptp_hwtstamp_config_get(struct aq_ptp_s *aq_ptp, +@@ -639,7 +639,7 @@ bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring) + &aq_ptp->ptp_rx == ring || &aq_ptp->hwts_rx == ring; + } + +-u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p, ++u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct skb_shared_hwtstamps *shhwtstamps, u8 *p, + unsigned int len) + { + struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp; +@@ -648,7 +648,7 @@ u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p, + p, len, ×tamp); + + if (ret > 0) +- aq_ptp_rx_hwtstamp(aq_ptp, skb, timestamp); ++ aq_ptp_rx_hwtstamp(aq_ptp, shhwtstamps, timestamp); + + return ret; + } +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h +index 28ccb7ca2df9e..210b723f22072 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h +@@ -67,7 +67,7 @@ int aq_ptp_hwtstamp_config_set(struct aq_ptp_s *aq_ptp, + /* Return either ring is belong to PTP or not*/ + bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring); + +-u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p, ++u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct skb_shared_hwtstamps *shhwtstamps, u8 *p, + unsigned int len); + + struct ptp_clock *aq_ptp_get_ptp_clock(struct aq_ptp_s *aq_ptp); +@@ -143,7 +143,7 @@ static inline bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring) + } + + static inline u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, +- struct sk_buff *skb, u8 *p, ++ struct skb_shared_hwtstamps *shhwtstamps, u8 *p, + unsigned int len) + { + return 0; +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +index 2dc8d215a5918..b5a49166fa972 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +@@ -647,7 +647,7 @@ static int __aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi, + } + if (is_ptp_ring) + buff->len -= +- aq_ptp_extract_ts(self->aq_nic, skb, ++ aq_ptp_extract_ts(self->aq_nic, skb_hwtstamps(skb), + aq_buf_vaddr(&buff->rxdata), + buff->len); + +@@ -742,6 +742,8 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring, + struct aq_ring_buff_s *buff = &rx_ring->buff_ring[rx_ring->sw_head]; + bool is_ptp_ring = aq_ptp_ring(rx_ring->aq_nic, rx_ring); + struct aq_ring_buff_s *buff_ = NULL; ++ u16 ptp_hwtstamp_len = 0; ++ struct skb_shared_hwtstamps shhwtstamps; + struct sk_buff *skb = NULL; + unsigned int next_ = 0U; + struct xdp_buff xdp; +@@ -810,11 +812,12 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring, + hard_start = page_address(buff->rxdata.page) + + buff->rxdata.pg_off - rx_ring->page_offset; + +- if (is_ptp_ring) +- buff->len -= +- aq_ptp_extract_ts(rx_ring->aq_nic, skb, +- aq_buf_vaddr(&buff->rxdata), +- buff->len); ++ if (is_ptp_ring) { ++ ptp_hwtstamp_len = aq_ptp_extract_ts(rx_ring->aq_nic, &shhwtstamps, ++ aq_buf_vaddr(&buff->rxdata), ++ buff->len); ++ buff->len -= ptp_hwtstamp_len; ++ } + + xdp_init_buff(&xdp, frame_sz, &rx_ring->xdp_rxq); + xdp_prepare_buff(&xdp, hard_start, rx_ring->page_offset, +@@ -834,6 +837,9 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring, + if (IS_ERR(skb) || !skb) + continue; + ++ if (ptp_hwtstamp_len > 0) ++ *skb_hwtstamps(skb) = shhwtstamps; ++ + if (buff->is_vlan) + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), + buff->vlan_rx_tag); +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +index d8afcf8d6b30e..4d6663ff84722 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +@@ -2075,6 +2075,7 @@ destroy_flow_table: + rhashtable_destroy(&tc_info->flow_table); + free_tc_info: + kfree(tc_info); ++ bp->tc_info = NULL; + return rc; + } + +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 85570e40c8e9b..f60a16de565ed 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -6853,7 +6853,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) + desc_idx, *post_ptr); + drop_it_no_recycle: + /* Other statistics kept track of by card. */ +- tp->rx_dropped++; ++ tnapi->rx_dropped++; + goto next_pkt; + } + +@@ -7879,8 +7879,10 @@ static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi, + + segs = skb_gso_segment(skb, tp->dev->features & + ~(NETIF_F_TSO | NETIF_F_TSO6)); +- if (IS_ERR(segs) || !segs) ++ if (IS_ERR(segs) || !segs) { ++ tnapi->tx_dropped++; + goto tg3_tso_bug_end; ++ } + + skb_list_walk_safe(segs, seg, next) { + skb_mark_not_on_list(seg); +@@ -8151,7 +8153,7 @@ dma_error: + drop: + dev_kfree_skb_any(skb); + drop_nofree: +- tp->tx_dropped++; ++ tnapi->tx_dropped++; + return NETDEV_TX_OK; + } + +@@ -9330,7 +9332,7 @@ static void __tg3_set_rx_mode(struct net_device *); + /* tp->lock is held. */ + static int tg3_halt(struct tg3 *tp, int kind, bool silent) + { +- int err; ++ int err, i; + + tg3_stop_fw(tp); + +@@ -9351,6 +9353,13 @@ static int tg3_halt(struct tg3 *tp, int kind, bool silent) + + /* And make sure the next sample is new data */ + memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); ++ ++ for (i = 0; i < TG3_IRQ_MAX_VECS; ++i) { ++ struct tg3_napi *tnapi = &tp->napi[i]; ++ ++ tnapi->rx_dropped = 0; ++ tnapi->tx_dropped = 0; ++ } + } + + return err; +@@ -11900,6 +11909,9 @@ static void tg3_get_nstats(struct tg3 *tp, struct rtnl_link_stats64 *stats) + { + struct rtnl_link_stats64 *old_stats = &tp->net_stats_prev; + struct tg3_hw_stats *hw_stats = tp->hw_stats; ++ unsigned long rx_dropped; ++ unsigned long tx_dropped; ++ int i; + + stats->rx_packets = old_stats->rx_packets + + get_stat64(&hw_stats->rx_ucast_packets) + +@@ -11946,8 +11958,26 @@ static void tg3_get_nstats(struct tg3 *tp, struct rtnl_link_stats64 *stats) + stats->rx_missed_errors = old_stats->rx_missed_errors + + get_stat64(&hw_stats->rx_discards); + +- stats->rx_dropped = tp->rx_dropped; +- stats->tx_dropped = tp->tx_dropped; ++ /* Aggregate per-queue counters. The per-queue counters are updated ++ * by a single writer, race-free. The result computed by this loop ++ * might not be 100% accurate (counters can be updated in the middle of ++ * the loop) but the next tg3_get_nstats() will recompute the current ++ * value so it is acceptable. ++ * ++ * Note that these counters wrap around at 4G on 32bit machines. ++ */ ++ rx_dropped = (unsigned long)(old_stats->rx_dropped); ++ tx_dropped = (unsigned long)(old_stats->tx_dropped); ++ ++ for (i = 0; i < tp->irq_cnt; i++) { ++ struct tg3_napi *tnapi = &tp->napi[i]; ++ ++ rx_dropped += tnapi->rx_dropped; ++ tx_dropped += tnapi->tx_dropped; ++ } ++ ++ stats->rx_dropped = rx_dropped; ++ stats->tx_dropped = tx_dropped; + } + + static int tg3_get_regs_len(struct net_device *dev) +diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h +index 1000c894064f0..8d753f8c5b065 100644 +--- a/drivers/net/ethernet/broadcom/tg3.h ++++ b/drivers/net/ethernet/broadcom/tg3.h +@@ -3018,6 +3018,7 @@ struct tg3_napi { + u16 *rx_rcb_prod_idx; + struct tg3_rx_prodring_set prodring; + struct tg3_rx_buffer_desc *rx_rcb; ++ unsigned long rx_dropped; + + u32 tx_prod ____cacheline_aligned; + u32 tx_cons; +@@ -3026,6 +3027,7 @@ struct tg3_napi { + u32 prodmbox; + struct tg3_tx_buffer_desc *tx_ring; + struct tg3_tx_ring_info *tx_buffers; ++ unsigned long tx_dropped; + + dma_addr_t status_mapping; + dma_addr_t rx_rcb_mapping; +@@ -3219,8 +3221,6 @@ struct tg3 { + + + /* begin "everything else" cacheline(s) section */ +- unsigned long rx_dropped; +- unsigned long tx_dropped; + struct rtnl_link_stats64 net_stats_prev; + struct tg3_ethtool_stats estats_prev; + +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +index 928d934cb21a5..f75668c479351 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +@@ -66,6 +66,27 @@ static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb) + } + } + ++static u32 hns_mac_link_anti_shake(struct mac_driver *mac_ctrl_drv) ++{ ++#define HNS_MAC_LINK_WAIT_TIME 5 ++#define HNS_MAC_LINK_WAIT_CNT 40 ++ ++ u32 link_status = 0; ++ int i; ++ ++ if (!mac_ctrl_drv->get_link_status) ++ return link_status; ++ ++ for (i = 0; i < HNS_MAC_LINK_WAIT_CNT; i++) { ++ msleep(HNS_MAC_LINK_WAIT_TIME); ++ mac_ctrl_drv->get_link_status(mac_ctrl_drv, &link_status); ++ if (!link_status) ++ break; ++ } ++ ++ return link_status; ++} ++ + void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) + { + struct mac_driver *mac_ctrl_drv; +@@ -83,6 +104,14 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) + &sfp_prsnt); + if (!ret) + *link_status = *link_status && sfp_prsnt; ++ ++ /* for FIBER port, it may have a fake link up. ++ * when the link status changes from down to up, we need to do ++ * anti-shake. the anti-shake time is base on tests. ++ * only FIBER port need to do this. ++ */ ++ if (*link_status && !mac_cb->link) ++ *link_status = hns_mac_link_anti_shake(mac_ctrl_drv); + } + + mac_cb->link = *link_status; +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c +index 7cf10d1e2b311..85722afe21770 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c +@@ -142,7 +142,8 @@ MODULE_DEVICE_TABLE(acpi, hns_enet_acpi_match); + + static void fill_desc(struct hnae_ring *ring, void *priv, + int size, dma_addr_t dma, int frag_end, +- int buf_num, enum hns_desc_type type, int mtu) ++ int buf_num, enum hns_desc_type type, int mtu, ++ bool is_gso) + { + struct hnae_desc *desc = &ring->desc[ring->next_to_use]; + struct hnae_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use]; +@@ -275,6 +276,15 @@ static int hns_nic_maybe_stop_tso( + return 0; + } + ++static int hns_nic_maybe_stop_tx_v2(struct sk_buff **out_skb, int *bnum, ++ struct hnae_ring *ring) ++{ ++ if (skb_is_gso(*out_skb)) ++ return hns_nic_maybe_stop_tso(out_skb, bnum, ring); ++ else ++ return hns_nic_maybe_stop_tx(out_skb, bnum, ring); ++} ++ + static void fill_tso_desc(struct hnae_ring *ring, void *priv, + int size, dma_addr_t dma, int frag_end, + int buf_num, enum hns_desc_type type, int mtu) +@@ -300,6 +310,19 @@ static void fill_tso_desc(struct hnae_ring *ring, void *priv, + mtu); + } + ++static void fill_desc_v2(struct hnae_ring *ring, void *priv, ++ int size, dma_addr_t dma, int frag_end, ++ int buf_num, enum hns_desc_type type, int mtu, ++ bool is_gso) ++{ ++ if (is_gso) ++ fill_tso_desc(ring, priv, size, dma, frag_end, buf_num, type, ++ mtu); ++ else ++ fill_v2_desc(ring, priv, size, dma, frag_end, buf_num, type, ++ mtu); ++} ++ + netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, + struct sk_buff *skb, + struct hns_nic_ring_data *ring_data) +@@ -313,6 +336,7 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, + int seg_num; + dma_addr_t dma; + int size, next_to_use; ++ bool is_gso; + int i; + + switch (priv->ops.maybe_stop_tx(&skb, &buf_num, ring)) { +@@ -339,8 +363,9 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, + ring->stats.sw_err_cnt++; + goto out_err_tx_ok; + } ++ is_gso = skb_is_gso(skb); + priv->ops.fill_desc(ring, skb, size, dma, seg_num == 1 ? 1 : 0, +- buf_num, DESC_TYPE_SKB, ndev->mtu); ++ buf_num, DESC_TYPE_SKB, ndev->mtu, is_gso); + + /* fill the fragments */ + for (i = 1; i < seg_num; i++) { +@@ -354,7 +379,7 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, + } + priv->ops.fill_desc(ring, skb_frag_page(frag), size, dma, + seg_num - 1 == i ? 1 : 0, buf_num, +- DESC_TYPE_PAGE, ndev->mtu); ++ DESC_TYPE_PAGE, ndev->mtu, is_gso); + } + + /*complete translate all packets*/ +@@ -1776,15 +1801,6 @@ static int hns_nic_set_features(struct net_device *netdev, + netdev_info(netdev, "enet v1 do not support tso!\n"); + break; + default: +- if (features & (NETIF_F_TSO | NETIF_F_TSO6)) { +- priv->ops.fill_desc = fill_tso_desc; +- priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso; +- /* The chip only support 7*4096 */ +- netif_set_tso_max_size(netdev, 7 * 4096); +- } else { +- priv->ops.fill_desc = fill_v2_desc; +- priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; +- } + break; + } + netdev->features = features; +@@ -2159,16 +2175,9 @@ static void hns_nic_set_priv_ops(struct net_device *netdev) + priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; + } else { + priv->ops.get_rxd_bnum = get_v2rx_desc_bnum; +- if ((netdev->features & NETIF_F_TSO) || +- (netdev->features & NETIF_F_TSO6)) { +- priv->ops.fill_desc = fill_tso_desc; +- priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso; +- /* This chip only support 7*4096 */ +- netif_set_tso_max_size(netdev, 7 * 4096); +- } else { +- priv->ops.fill_desc = fill_v2_desc; +- priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; +- } ++ priv->ops.fill_desc = fill_desc_v2; ++ priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx_v2; ++ netif_set_tso_max_size(netdev, 7 * 4096); + /* enable tso when init + * control tso on/off through TSE bit in bd + */ +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h b/drivers/net/ethernet/hisilicon/hns/hns_enet.h +index ffa9d6573f54b..3f3ee032f631c 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.h ++++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.h +@@ -44,7 +44,8 @@ struct hns_nic_ring_data { + struct hns_nic_ops { + void (*fill_desc)(struct hnae_ring *ring, void *priv, + int size, dma_addr_t dma, int frag_end, +- int buf_num, enum hns_desc_type type, int mtu); ++ int buf_num, enum hns_desc_type type, int mtu, ++ bool is_gso); + int (*maybe_stop_tx)(struct sk_buff **out_skb, + int *bnum, struct hnae_ring *ring); + void (*get_rxd_bnum)(u32 bnum_flag, int *out_bnum); +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 9f5824eb8808a..b4157ff370a31 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -16158,7 +16158,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + I40E_PRTGL_SAH_MFS_MASK) >> I40E_PRTGL_SAH_MFS_SHIFT; + if (val < MAX_FRAME_SIZE_DEFAULT) + dev_warn(&pdev->dev, "MFS for port %x has been set below the default: %x\n", +- i, val); ++ pf->hw.port, val); + + /* Add a filter to drop all Flow control frames from any VSI from being + * transmitted. By doing so we stop a malicious VF from sending out +diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +index c13b4fa659ee9..31e02624aca48 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +@@ -829,18 +829,10 @@ static int __iavf_set_coalesce(struct net_device *netdev, + struct iavf_adapter *adapter = netdev_priv(netdev); + int i; + +- if (ec->rx_coalesce_usecs == 0) { +- if (ec->use_adaptive_rx_coalesce) +- netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n"); +- } else if ((ec->rx_coalesce_usecs < IAVF_MIN_ITR) || +- (ec->rx_coalesce_usecs > IAVF_MAX_ITR)) { ++ if (ec->rx_coalesce_usecs > IAVF_MAX_ITR) { + netif_info(adapter, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n"); + return -EINVAL; +- } else if (ec->tx_coalesce_usecs == 0) { +- if (ec->use_adaptive_tx_coalesce) +- netif_info(adapter, drv, netdev, "tx-usecs=0, need to disable adaptive-tx for a complete disable\n"); +- } else if ((ec->tx_coalesce_usecs < IAVF_MIN_ITR) || +- (ec->tx_coalesce_usecs > IAVF_MAX_ITR)) { ++ } else if (ec->tx_coalesce_usecs > IAVF_MAX_ITR) { + netif_info(adapter, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n"); + return -EINVAL; + } +diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.h b/drivers/net/ethernet/intel/iavf/iavf_txrx.h +index 7e6ee32d19b69..10ba36602c0c1 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_txrx.h ++++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.h +@@ -15,7 +15,6 @@ + */ + #define IAVF_ITR_DYNAMIC 0x8000 /* use top bit as a flag */ + #define IAVF_ITR_MASK 0x1FFE /* mask for ITR register value */ +-#define IAVF_MIN_ITR 2 /* reg uses 2 usec resolution */ + #define IAVF_ITR_100K 10 /* all values below must be even */ + #define IAVF_ITR_50K 20 + #define IAVF_ITR_20K 50 +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +index a0c31f5b2ce05..03ebabd616353 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +@@ -1877,7 +1877,7 @@ struct mcs_hw_info { + u8 tcam_entries; /* RX/TX Tcam entries per mcs block */ + u8 secy_entries; /* RX/TX SECY entries per mcs block */ + u8 sc_entries; /* RX/TX SC CAM entries per mcs block */ +- u8 sa_entries; /* PN table entries = SA entries */ ++ u16 sa_entries; /* PN table entries = SA entries */ + u64 rsvd[16]; + }; + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs.c b/drivers/net/ethernet/marvell/octeontx2/af/mcs.c +index c43f19dfbd744..c1775bd01c2b4 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/mcs.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs.c +@@ -117,7 +117,7 @@ void mcs_get_rx_secy_stats(struct mcs *mcs, struct mcs_secy_stats *stats, int id + reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYTAGGEDCTLX(id); + stats->pkt_tagged_ctl_cnt = mcs_reg_read(mcs, reg); + +- reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDORNOTAGX(id); ++ reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(id); + stats->pkt_untaged_cnt = mcs_reg_read(mcs, reg); + + reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(id); +@@ -215,7 +215,7 @@ void mcs_get_sc_stats(struct mcs *mcs, struct mcs_sc_stats *stats, + reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCNOTVALIDX(id); + stats->pkt_notvalid_cnt = mcs_reg_read(mcs, reg); + +- reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDOROKX(id); ++ reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDX(id); + stats->pkt_unchecked_cnt = mcs_reg_read(mcs, reg); + + if (mcs->hw->mcs_blks > 1) { +@@ -1219,6 +1219,17 @@ struct mcs *mcs_get_pdata(int mcs_id) + return NULL; + } + ++bool is_mcs_bypass(int mcs_id) ++{ ++ struct mcs *mcs_dev; ++ ++ list_for_each_entry(mcs_dev, &mcs_list, mcs_list) { ++ if (mcs_dev->mcs_id == mcs_id) ++ return mcs_dev->bypass; ++ } ++ return true; ++} ++ + void mcs_set_port_cfg(struct mcs *mcs, struct mcs_port_cfg_set_req *req) + { + u64 val = 0; +@@ -1436,7 +1447,7 @@ static int mcs_x2p_calibration(struct mcs *mcs) + return err; + } + +-static void mcs_set_external_bypass(struct mcs *mcs, u8 bypass) ++static void mcs_set_external_bypass(struct mcs *mcs, bool bypass) + { + u64 val; + +@@ -1447,6 +1458,7 @@ static void mcs_set_external_bypass(struct mcs *mcs, u8 bypass) + else + val &= ~BIT_ULL(6); + mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val); ++ mcs->bypass = bypass; + } + + static void mcs_global_cfg(struct mcs *mcs) +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs.h b/drivers/net/ethernet/marvell/octeontx2/af/mcs.h +index 0f89dcb764654..f927cc61dfd21 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/mcs.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs.h +@@ -149,6 +149,7 @@ struct mcs { + u16 num_vec; + void *rvu; + u16 *tx_sa_active; ++ bool bypass; + }; + + struct mcs_ops { +@@ -206,6 +207,7 @@ void mcs_get_custom_tag_cfg(struct mcs *mcs, struct mcs_custom_tag_cfg_get_req * + int mcs_alloc_ctrlpktrule(struct rsrc_bmap *rsrc, u16 *pf_map, u16 offset, u16 pcifunc); + int mcs_free_ctrlpktrule(struct mcs *mcs, struct mcs_free_ctrl_pkt_rule_req *req); + int mcs_ctrlpktrule_write(struct mcs *mcs, struct mcs_ctrl_pkt_rule_write_req *req); ++bool is_mcs_bypass(int mcs_id); + + /* CN10K-B APIs */ + void cn10kb_mcs_set_hw_capabilities(struct mcs *mcs); +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs_reg.h b/drivers/net/ethernet/marvell/octeontx2/af/mcs_reg.h +index f3ab01fc363c8..f4c6de89002c1 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/mcs_reg.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs_reg.h +@@ -810,14 +810,37 @@ + offset = 0x9d8ull; \ + offset; }) + ++#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDX(a) ({ \ ++ u64 offset; \ ++ \ ++ offset = 0xee80ull; \ ++ if (mcs->hw->mcs_blks > 1) \ ++ offset = 0xe818ull; \ ++ offset += (a) * 0x8ull; \ ++ offset; }) ++ ++#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(a) ({ \ ++ u64 offset; \ ++ \ ++ offset = 0xa680ull; \ ++ if (mcs->hw->mcs_blks > 1) \ ++ offset = 0xd018ull; \ ++ offset += (a) * 0x8ull; \ ++ offset; }) ++ ++#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCLATEORDELAYEDX(a) ({ \ ++ u64 offset; \ ++ \ ++ offset = 0xf680ull; \ ++ if (mcs->hw->mcs_blks > 1) \ ++ offset = 0xe018ull; \ ++ offset += (a) * 0x8ull; \ ++ offset; }) ++ + #define MCSX_CSE_RX_MEM_SLAVE_INOCTETSSCDECRYPTEDX(a) (0xe680ull + (a) * 0x8ull) + #define MCSX_CSE_RX_MEM_SLAVE_INOCTETSSCVALIDATEX(a) (0xde80ull + (a) * 0x8ull) +-#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDORNOTAGX(a) (0xa680ull + (a) * 0x8ull) + #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYNOTAGX(a) (0xd218 + (a) * 0x8ull) +-#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(a) (0xd018ull + (a) * 0x8ull) +-#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDOROKX(a) (0xee80ull + (a) * 0x8ull) + #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(a) (0xb680ull + (a) * 0x8ull) +-#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCLATEORDELAYEDX(a) (0xf680ull + (a) * 0x8ull) + #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSAINVALIDX(a) (0x12680ull + (a) * 0x8ull) + #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSANOTUSINGSAERRORX(a) (0x15680ull + (a) * 0x8ull) + #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSANOTVALIDX(a) (0x13680ull + (a) * 0x8ull) +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +index 733add3a9dc6b..d88d86bf07b03 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +@@ -2622,6 +2622,9 @@ static void __rvu_flr_handler(struct rvu *rvu, u16 pcifunc) + */ + rvu_npc_free_mcam_entries(rvu, pcifunc, -1); + ++ if (rvu->mcs_blk_cnt) ++ rvu_mcs_flr_handler(rvu, pcifunc); ++ + mutex_unlock(&rvu->flr_lock); + } + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +index a3346ea7876c5..95a7bc396e8ea 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +@@ -325,6 +325,7 @@ struct nix_hw { + struct nix_txvlan txvlan; + struct nix_ipolicer *ipolicer; + u64 *tx_credits; ++ u8 cc_mcs_cnt; + }; + + /* RVU block's capabilities or functionality, +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +index dc7bd2ce78f7d..d609512998992 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +@@ -1285,7 +1285,7 @@ static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl) + + rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq"); + if (!rvu_dl->devlink_wq) +- goto err; ++ return -ENOMEM; + + INIT_WORK(&rvu_reporters->intr_work, rvu_npa_intr_work); + INIT_WORK(&rvu_reporters->err_work, rvu_npa_err_work); +@@ -1293,9 +1293,6 @@ static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl) + INIT_WORK(&rvu_reporters->ras_work, rvu_npa_ras_work); + + return 0; +-err: +- rvu_npa_health_reporters_destroy(rvu_dl); +- return -ENOMEM; + } + + static int rvu_npa_health_reporters_create(struct rvu_devlink *rvu_dl) +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +index 7310047136986..959f36efdc4a6 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +@@ -12,6 +12,7 @@ + #include "rvu_reg.h" + #include "rvu.h" + #include "npc.h" ++#include "mcs.h" + #include "cgx.h" + #include "lmac_common.h" + #include "rvu_npc_hash.h" +@@ -4164,6 +4165,12 @@ static void nix_link_config(struct rvu *rvu, int blkaddr, + SDP_HW_MAX_FRS << 16 | NIC_HW_MIN_FRS); + } + ++ /* Get MCS external bypass status for CN10K-B */ ++ if (mcs_get_blkcnt() == 1) { ++ /* Adjust for 2 credits when external bypass is disabled */ ++ nix_hw->cc_mcs_cnt = is_mcs_bypass(0) ? 0 : 2; ++ } ++ + /* Set credits for Tx links assuming max packet length allowed. + * This will be reconfigured based on MTU set for PF/VF. + */ +@@ -4187,6 +4194,7 @@ static void nix_link_config(struct rvu *rvu, int blkaddr, + tx_credits = (lmac_fifo_len - lmac_max_frs) / 16; + /* Enable credits and set credit pkt count to max allowed */ + cfg = (tx_credits << 12) | (0x1FF << 2) | BIT_ULL(1); ++ cfg |= FIELD_PREP(NIX_AF_LINKX_MCS_CNT_MASK, nix_hw->cc_mcs_cnt); + + link = iter + slink; + nix_hw->tx_credits[link] = tx_credits; +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index 16cfc802e348d..f65805860c8d4 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -389,7 +389,13 @@ static u64 npc_get_default_entry_action(struct rvu *rvu, struct npc_mcam *mcam, + int bank, nixlf, index; + + /* get ucast entry rule entry index */ +- nix_get_nixlf(rvu, pf_func, &nixlf, NULL); ++ if (nix_get_nixlf(rvu, pf_func, &nixlf, NULL)) { ++ dev_err(rvu->dev, "%s: nixlf not attached to pcifunc:0x%x\n", ++ __func__, pf_func); ++ /* Action 0 is drop */ ++ return 0; ++ } ++ + index = npc_get_nixlf_mcam_index(mcam, pf_func, nixlf, + NIXLF_UCAST_ENTRY); + bank = npc_get_bank(mcam, index); +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c +index b3150f0532919..d46ac29adb966 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c +@@ -31,8 +31,8 @@ static struct hw_reg_map txsch_reg_map[NIX_TXSCH_LVL_CNT] = { + {NIX_TXSCH_LVL_TL4, 3, 0xFFFF, {{0x0B00, 0x0B08}, {0x0B10, 0x0B18}, + {0x1200, 0x12E0} } }, + {NIX_TXSCH_LVL_TL3, 4, 0xFFFF, {{0x1000, 0x10E0}, {0x1600, 0x1608}, +- {0x1610, 0x1618}, {0x1700, 0x17B0} } }, +- {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x17B0} } }, ++ {0x1610, 0x1618}, {0x1700, 0x17C8} } }, ++ {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x17C8} } }, + {NIX_TXSCH_LVL_TL1, 1, 0xFFFF, {{0x0C00, 0x0D98} } }, + }; + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h +index 39f7a7cb27558..b690e5566f12a 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h +@@ -434,6 +434,7 @@ + + #define NIX_AF_LINKX_BASE_MASK GENMASK_ULL(11, 0) + #define NIX_AF_LINKX_RANGE_MASK GENMASK_ULL(19, 16) ++#define NIX_AF_LINKX_MCS_CNT_MASK GENMASK_ULL(33, 32) + + /* SSO */ + #define SSO_AF_CONST (0x1000) +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +index aaf1af2a402ec..af779ae40d3c2 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +@@ -323,9 +323,12 @@ static void otx2_get_pauseparam(struct net_device *netdev, + if (is_otx2_lbkvf(pfvf->pdev)) + return; + ++ mutex_lock(&pfvf->mbox.lock); + req = otx2_mbox_alloc_msg_cgx_cfg_pause_frm(&pfvf->mbox); +- if (!req) ++ if (!req) { ++ mutex_unlock(&pfvf->mbox.lock); + return; ++ } + + if (!otx2_sync_mbox_msg(&pfvf->mbox)) { + rsp = (struct cgx_pause_frm_cfg *) +@@ -333,6 +336,7 @@ static void otx2_get_pauseparam(struct net_device *netdev, + pause->rx_pause = rsp->rx_pause; + pause->tx_pause = rsp->tx_pause; + } ++ mutex_unlock(&pfvf->mbox.lock); + } + + static int otx2_set_pauseparam(struct net_device *netdev, +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +index 18c5d2b3f7f95..55807e2043edf 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +@@ -1676,6 +1676,14 @@ static void otx2_do_set_rx_mode(struct otx2_nic *pf) + mutex_unlock(&pf->mbox.lock); + } + ++static void otx2_set_irq_coalesce(struct otx2_nic *pfvf) ++{ ++ int cint; ++ ++ for (cint = 0; cint < pfvf->hw.cint_cnt; cint++) ++ otx2_config_irq_coalescing(pfvf, cint); ++} ++ + static void otx2_dim_work(struct work_struct *w) + { + struct dim_cq_moder cur_moder; +@@ -1691,6 +1699,7 @@ static void otx2_dim_work(struct work_struct *w) + CQ_TIMER_THRESH_MAX : cur_moder.usec; + pfvf->hw.cq_ecount_wait = (cur_moder.pkts > NAPI_POLL_WEIGHT) ? + NAPI_POLL_WEIGHT : cur_moder.pkts; ++ otx2_set_irq_coalesce(pfvf); + dim->state = DIM_START_MEASURE; + } + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +index 20d801d30c732..aee392a15b23c 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +@@ -510,11 +510,18 @@ static void otx2_adjust_adaptive_coalese(struct otx2_nic *pfvf, struct otx2_cq_p + { + struct dim_sample dim_sample; + u64 rx_frames, rx_bytes; ++ u64 tx_frames, tx_bytes; + + rx_frames = OTX2_GET_RX_STATS(RX_BCAST) + OTX2_GET_RX_STATS(RX_MCAST) + + OTX2_GET_RX_STATS(RX_UCAST); + rx_bytes = OTX2_GET_RX_STATS(RX_OCTS); +- dim_update_sample(pfvf->napi_events, rx_frames, rx_bytes, &dim_sample); ++ tx_bytes = OTX2_GET_TX_STATS(TX_OCTS); ++ tx_frames = OTX2_GET_TX_STATS(TX_UCAST); ++ ++ dim_update_sample(pfvf->napi_events, ++ rx_frames + tx_frames, ++ rx_bytes + tx_bytes, ++ &dim_sample); + net_dim(&cq_poll->dim, dim_sample); + } + +@@ -555,16 +562,9 @@ int otx2_napi_handler(struct napi_struct *napi, int budget) + if (pfvf->flags & OTX2_FLAG_INTF_DOWN) + return workdone; + +- /* Check for adaptive interrupt coalesce */ +- if (workdone != 0 && +- ((pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED) == +- OTX2_FLAG_ADPTV_INT_COAL_ENABLED)) { +- /* Adjust irq coalese using net_dim */ ++ /* Adjust irq coalese using net_dim */ ++ if (pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED) + otx2_adjust_adaptive_coalese(pfvf, cq_poll); +- /* Update irq coalescing */ +- for (i = 0; i < pfvf->hw.cint_cnt; i++) +- otx2_config_irq_coalescing(pfvf, i); +- } + + /* Re-enable interrupts */ + otx2_write64(pfvf, NIX_LF_CINTX_ENA_W1S(cq_poll->cint_idx), +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h +index 93a4258421667..13dfcf9f75dad 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h ++++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h +@@ -214,7 +214,7 @@ struct ionic_desc_info { + void *cb_arg; + }; + +-#define IONIC_QUEUE_NAME_MAX_SZ 32 ++#define IONIC_QUEUE_NAME_MAX_SZ 16 + + struct ionic_queue { + struct device *dev; +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c +index a89ab455af67d..f7634884c7508 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c +@@ -46,24 +46,24 @@ static void ionic_lif_queue_identify(struct ionic_lif *lif); + static void ionic_dim_work(struct work_struct *work) + { + struct dim *dim = container_of(work, struct dim, work); ++ struct ionic_intr_info *intr; + struct dim_cq_moder cur_moder; + struct ionic_qcq *qcq; ++ struct ionic_lif *lif; + u32 new_coal; + + cur_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix); + qcq = container_of(dim, struct ionic_qcq, dim); +- new_coal = ionic_coal_usec_to_hw(qcq->q.lif->ionic, cur_moder.usec); ++ lif = qcq->q.lif; ++ new_coal = ionic_coal_usec_to_hw(lif->ionic, cur_moder.usec); + new_coal = new_coal ? new_coal : 1; + +- if (qcq->intr.dim_coal_hw != new_coal) { +- unsigned int qi = qcq->cq.bound_q->index; +- struct ionic_lif *lif = qcq->q.lif; +- +- qcq->intr.dim_coal_hw = new_coal; ++ intr = &qcq->intr; ++ if (intr->dim_coal_hw != new_coal) { ++ intr->dim_coal_hw = new_coal; + + ionic_intr_coal_init(lif->ionic->idev.intr_ctrl, +- lif->rxqcqs[qi]->intr.index, +- qcq->intr.dim_coal_hw); ++ intr->index, intr->dim_coal_hw); + } + + dim->state = DIM_START_MEASURE; +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index abfa375b08878..d22457f2cf9cf 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -193,6 +193,7 @@ enum rtl_registers { + /* No threshold before first PCI xfer */ + #define RX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT) + #define RX_EARLY_OFF (1 << 11) ++#define RX_PAUSE_SLOT_ON (1 << 11) /* 8125b and later */ + #define RXCFG_DMA_SHIFT 8 + /* Unlimited maximum PCI burst. */ + #define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT) +@@ -2237,9 +2238,13 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) + case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53: + RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF); + break; +- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63: ++ case RTL_GIGA_MAC_VER_61: + RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST); + break; ++ case RTL_GIGA_MAC_VER_63: ++ RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST | ++ RX_PAUSE_SLOT_ON); ++ break; + default: + RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST); + break; +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c +index e95d35f1e5a0c..8fd167501fa0e 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c +@@ -710,28 +710,22 @@ void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev, + } + } + +-void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq, ++void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, ++ u32 num_txq, u32 num_rxq, + bool enable) + { + u32 value; + +- if (!enable) { +- value = readl(ioaddr + MAC_FPE_CTRL_STS); +- +- value &= ~EFPE; +- +- writel(value, ioaddr + MAC_FPE_CTRL_STS); +- return; ++ if (enable) { ++ cfg->fpe_csr = EFPE; ++ value = readl(ioaddr + GMAC_RXQ_CTRL1); ++ value &= ~GMAC_RXQCTRL_FPRQ; ++ value |= (num_rxq - 1) << GMAC_RXQCTRL_FPRQ_SHIFT; ++ writel(value, ioaddr + GMAC_RXQ_CTRL1); ++ } else { ++ cfg->fpe_csr = 0; + } +- +- value = readl(ioaddr + GMAC_RXQ_CTRL1); +- value &= ~GMAC_RXQCTRL_FPRQ; +- value |= (num_rxq - 1) << GMAC_RXQCTRL_FPRQ_SHIFT; +- writel(value, ioaddr + GMAC_RXQ_CTRL1); +- +- value = readl(ioaddr + MAC_FPE_CTRL_STS); +- value |= EFPE; +- writel(value, ioaddr + MAC_FPE_CTRL_STS); ++ writel(cfg->fpe_csr, ioaddr + MAC_FPE_CTRL_STS); + } + + int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev) +@@ -741,6 +735,9 @@ int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev) + + status = FPE_EVENT_UNKNOWN; + ++ /* Reads from the MAC_FPE_CTRL_STS register should only be performed ++ * here, since the status flags of MAC_FPE_CTRL_STS are "clear on read" ++ */ + value = readl(ioaddr + MAC_FPE_CTRL_STS); + + if (value & TRSP) { +@@ -766,19 +763,15 @@ int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev) + return status; + } + +-void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, enum stmmac_mpacket_type type) ++void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, ++ enum stmmac_mpacket_type type) + { +- u32 value; ++ u32 value = cfg->fpe_csr; + +- value = readl(ioaddr + MAC_FPE_CTRL_STS); +- +- if (type == MPACKET_VERIFY) { +- value &= ~SRSP; ++ if (type == MPACKET_VERIFY) + value |= SVER; +- } else { +- value &= ~SVER; ++ else if (type == MPACKET_RESPONSE) + value |= SRSP; +- } + + writel(value, ioaddr + MAC_FPE_CTRL_STS); + } +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h +index 53c138d0ff480..34e620790eb37 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h +@@ -153,9 +153,11 @@ int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, + unsigned int ptp_rate); + void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev, + struct stmmac_extra_stats *x, u32 txqcnt); +-void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq, ++void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, ++ u32 num_txq, u32 num_rxq, + bool enable); + void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, ++ struct stmmac_fpe_cfg *cfg, + enum stmmac_mpacket_type type); + int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev); + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +index f30e08a106cbe..c2181c277291b 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +@@ -1441,7 +1441,8 @@ static int dwxgmac3_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, + return 0; + } + +-static void dwxgmac3_fpe_configure(void __iomem *ioaddr, u32 num_txq, ++static void dwxgmac3_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, ++ u32 num_txq, + u32 num_rxq, bool enable) + { + u32 value; +diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h +index 592b4067f9b8f..b2b9cf04bc726 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h ++++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h +@@ -392,9 +392,11 @@ struct stmmac_ops { + unsigned int ptp_rate); + void (*est_irq_status)(void __iomem *ioaddr, struct net_device *dev, + struct stmmac_extra_stats *x, u32 txqcnt); +- void (*fpe_configure)(void __iomem *ioaddr, u32 num_txq, u32 num_rxq, ++ void (*fpe_configure)(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, ++ u32 num_txq, u32 num_rxq, + bool enable); + void (*fpe_send_mpacket)(void __iomem *ioaddr, ++ struct stmmac_fpe_cfg *cfg, + enum stmmac_mpacket_type type); + int (*fpe_irq_status)(void __iomem *ioaddr, struct net_device *dev); + }; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 9f76c2f7d513b..69aac8ed84f67 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -957,7 +957,8 @@ static void stmmac_fpe_link_state_handle(struct stmmac_priv *priv, bool is_up) + bool *hs_enable = &fpe_cfg->hs_enable; + + if (is_up && *hs_enable) { +- stmmac_fpe_send_mpacket(priv, priv->ioaddr, MPACKET_VERIFY); ++ stmmac_fpe_send_mpacket(priv, priv->ioaddr, fpe_cfg, ++ MPACKET_VERIFY); + } else { + *lo_state = FPE_STATE_OFF; + *lp_state = FPE_STATE_OFF; +@@ -5704,6 +5705,7 @@ static void stmmac_fpe_event_status(struct stmmac_priv *priv, int status) + /* If user has requested FPE enable, quickly response */ + if (*hs_enable) + stmmac_fpe_send_mpacket(priv, priv->ioaddr, ++ fpe_cfg, + MPACKET_RESPONSE); + } + +@@ -7028,6 +7030,7 @@ static void stmmac_fpe_lp_task(struct work_struct *work) + if (*lo_state == FPE_STATE_ENTERING_ON && + *lp_state == FPE_STATE_ENTERING_ON) { + stmmac_fpe_configure(priv, priv->ioaddr, ++ fpe_cfg, + priv->plat->tx_queues_to_use, + priv->plat->rx_queues_to_use, + *enable); +@@ -7046,6 +7049,7 @@ static void stmmac_fpe_lp_task(struct work_struct *work) + netdev_info(priv->dev, SEND_VERIFY_MPAKCET_FMT, + *lo_state, *lp_state); + stmmac_fpe_send_mpacket(priv, priv->ioaddr, ++ fpe_cfg, + MPACKET_VERIFY); + } + /* Sleep then retry */ +@@ -7060,6 +7064,7 @@ void stmmac_fpe_handshake(struct stmmac_priv *priv, bool enable) + if (priv->plat->fpe_cfg->hs_enable != enable) { + if (enable) { + stmmac_fpe_send_mpacket(priv, priv->ioaddr, ++ priv->plat->fpe_cfg, + MPACKET_VERIFY); + } else { + priv->plat->fpe_cfg->lo_fpe_state = FPE_STATE_OFF; +@@ -7472,6 +7477,7 @@ int stmmac_suspend(struct device *dev) + if (priv->dma_cap.fpesel) { + /* Disable FPE */ + stmmac_fpe_configure(priv, priv->ioaddr, ++ priv->plat->fpe_cfg, + priv->plat->tx_queues_to_use, + priv->plat->rx_queues_to_use, false); + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +index 773e415cc2de6..390c900832cd2 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +@@ -1073,6 +1073,7 @@ disable: + + priv->plat->fpe_cfg->enable = false; + stmmac_fpe_configure(priv, priv->ioaddr, ++ priv->plat->fpe_cfg, + priv->plat->tx_queues_to_use, + priv->plat->rx_queues_to_use, + false); +diff --git a/drivers/net/hyperv/Kconfig b/drivers/net/hyperv/Kconfig +index ca7bf7f897d36..c8cbd85adcf99 100644 +--- a/drivers/net/hyperv/Kconfig ++++ b/drivers/net/hyperv/Kconfig +@@ -3,5 +3,6 @@ config HYPERV_NET + tristate "Microsoft Hyper-V virtual network driver" + depends on HYPERV + select UCS2_STRING ++ select NLS + help + Select this option to enable the Hyper-V virtual network driver. +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index 345e341d22338..4d833781294a4 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -763,7 +763,7 @@ enum rtl_register_content { + + /* rtl8152 flags */ + enum rtl8152_flags { +- RTL8152_UNPLUG = 0, ++ RTL8152_INACCESSIBLE = 0, + RTL8152_SET_RX_MODE, + WORK_ENABLE, + RTL8152_LINK_CHG, +@@ -1244,7 +1244,7 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) + static void rtl_set_unplug(struct r8152 *tp) + { + if (tp->udev->state == USB_STATE_NOTATTACHED) { +- set_bit(RTL8152_UNPLUG, &tp->flags); ++ set_bit(RTL8152_INACCESSIBLE, &tp->flags); + smp_mb__after_atomic(); + } + } +@@ -1255,7 +1255,7 @@ static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, + u16 limit = 64; + int ret = 0; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + + /* both size and indix must be 4 bytes align */ +@@ -1299,7 +1299,7 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, + u16 byteen_start, byteen_end, byen; + u16 limit = 512; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + + /* both size and indix must be 4 bytes align */ +@@ -1529,7 +1529,7 @@ static int read_mii_word(struct net_device *netdev, int phy_id, int reg) + struct r8152 *tp = netdev_priv(netdev); + int ret; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + + if (phy_id != R8152_PHY_ID) +@@ -1545,7 +1545,7 @@ void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val) + { + struct r8152 *tp = netdev_priv(netdev); + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + if (phy_id != R8152_PHY_ID) +@@ -1750,7 +1750,7 @@ static void read_bulk_callback(struct urb *urb) + if (!tp) + return; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + if (!test_bit(WORK_ENABLE, &tp->flags)) +@@ -1842,7 +1842,7 @@ static void write_bulk_callback(struct urb *urb) + if (!test_bit(WORK_ENABLE, &tp->flags)) + return; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + if (!skb_queue_empty(&tp->tx_queue)) +@@ -1863,7 +1863,7 @@ static void intr_callback(struct urb *urb) + if (!test_bit(WORK_ENABLE, &tp->flags)) + return; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + switch (status) { +@@ -2607,7 +2607,7 @@ static void bottom_half(struct tasklet_struct *t) + { + struct r8152 *tp = from_tasklet(tp, t, tx_tl); + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + if (!test_bit(WORK_ENABLE, &tp->flags)) +@@ -2650,7 +2650,7 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) + int ret; + + /* The rx would be stopped, so skip submitting */ +- if (test_bit(RTL8152_UNPLUG, &tp->flags) || ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags) || + !test_bit(WORK_ENABLE, &tp->flags) || !netif_carrier_ok(tp->netdev)) + return 0; + +@@ -2857,6 +2857,8 @@ static void rtl8152_nic_reset(struct r8152 *tp) + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST); + + for (i = 0; i < 1000; i++) { ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) ++ break; + if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) + break; + usleep_range(100, 400); +@@ -3050,7 +3052,7 @@ static int rtl_enable(struct r8152 *tp) + + static int rtl8152_enable(struct r8152 *tp) + { +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + + set_tx_qlen(tp); +@@ -3137,7 +3139,7 @@ static int rtl8153_enable(struct r8152 *tp) + { + u32 ocp_data; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + + set_tx_qlen(tp); +@@ -3169,7 +3171,7 @@ static void rtl_disable(struct r8152 *tp) + u32 ocp_data; + int i; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { + rtl_drop_queued_tx(tp); + return; + } +@@ -3186,6 +3188,8 @@ static void rtl_disable(struct r8152 *tp) + rxdy_gated_en(tp, true); + + for (i = 0; i < 1000; i++) { ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) ++ break; + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); + if ((ocp_data & FIFO_EMPTY) == FIFO_EMPTY) + break; +@@ -3193,6 +3197,8 @@ static void rtl_disable(struct r8152 *tp) + } + + for (i = 0; i < 1000; i++) { ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) ++ break; + if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0) & TCR0_TX_EMPTY) + break; + usleep_range(1000, 2000); +@@ -3623,7 +3629,7 @@ static u16 r8153_phy_status(struct r8152 *tp, u16 desired) + } + + msleep(20); +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + break; + } + +@@ -3655,7 +3661,7 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable) + int i; + + for (i = 0; i < 500; i++) { +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & + AUTOLOAD_DONE) +@@ -3697,7 +3703,7 @@ static void r8153c_ups_en(struct r8152 *tp, bool enable) + int i; + + for (i = 0; i < 500; i++) { +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & + AUTOLOAD_DONE) +@@ -4062,8 +4068,8 @@ static int rtl_phy_patch_request(struct r8152 *tp, bool request, bool wait) + for (i = 0; wait && i < 5000; i++) { + u32 ocp_data; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) +- break; ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) ++ return -ENODEV; + + usleep_range(1000, 2000); + ocp_data = ocp_reg_read(tp, OCP_PHY_PATCH_STAT); +@@ -5381,6 +5387,8 @@ static void wait_oob_link_list_ready(struct r8152 *tp) + int i; + + for (i = 0; i < 1000; i++) { ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) ++ break; + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); + if (ocp_data & LINK_LIST_READY) + break; +@@ -5395,6 +5403,8 @@ static void r8156b_wait_loading_flash(struct r8152 *tp) + int i; + + for (i = 0; i < 100; i++) { ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) ++ break; + if (ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL) & GPHY_PATCH_DONE) + break; + usleep_range(1000, 2000); +@@ -5517,6 +5527,8 @@ static int r8153_pre_firmware_1(struct r8152 *tp) + for (i = 0; i < 104; i++) { + u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_WDT1_CTRL); + ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) ++ return -ENODEV; + if (!(ocp_data & WTD1_EN)) + break; + usleep_range(1000, 2000); +@@ -5673,6 +5685,8 @@ static void r8153_aldps_en(struct r8152 *tp, bool enable) + data &= ~EN_ALDPS; + ocp_reg_write(tp, OCP_POWER_CFG, data); + for (i = 0; i < 20; i++) { ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) ++ return; + usleep_range(1000, 2000); + if (ocp_read_word(tp, MCU_TYPE_PLA, 0xe000) & 0x0100) + break; +@@ -6026,7 +6040,7 @@ static int rtl8156_enable(struct r8152 *tp) + u32 ocp_data; + u16 speed; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + + r8156_fc_parameter(tp); +@@ -6084,7 +6098,7 @@ static int rtl8156b_enable(struct r8152 *tp) + u32 ocp_data; + u16 speed; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + + set_tx_qlen(tp); +@@ -6270,7 +6284,7 @@ out: + + static void rtl8152_up(struct r8152 *tp) + { +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8152_aldps_en(tp, false); +@@ -6280,7 +6294,7 @@ static void rtl8152_up(struct r8152 *tp) + + static void rtl8152_down(struct r8152 *tp) + { +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { + rtl_drop_queued_tx(tp); + return; + } +@@ -6295,7 +6309,7 @@ static void rtl8153_up(struct r8152 *tp) + { + u32 ocp_data; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8153_u1u2en(tp, false); +@@ -6335,7 +6349,7 @@ static void rtl8153_down(struct r8152 *tp) + { + u32 ocp_data; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { + rtl_drop_queued_tx(tp); + return; + } +@@ -6356,7 +6370,7 @@ static void rtl8153b_up(struct r8152 *tp) + { + u32 ocp_data; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8153b_u1u2en(tp, false); +@@ -6380,7 +6394,7 @@ static void rtl8153b_down(struct r8152 *tp) + { + u32 ocp_data; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { + rtl_drop_queued_tx(tp); + return; + } +@@ -6417,7 +6431,7 @@ static void rtl8153c_up(struct r8152 *tp) + { + u32 ocp_data; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8153b_u1u2en(tp, false); +@@ -6498,7 +6512,7 @@ static void rtl8156_up(struct r8152 *tp) + { + u32 ocp_data; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8153b_u1u2en(tp, false); +@@ -6571,7 +6585,7 @@ static void rtl8156_down(struct r8152 *tp) + { + u32 ocp_data; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { + rtl_drop_queued_tx(tp); + return; + } +@@ -6709,7 +6723,7 @@ static void rtl_work_func_t(struct work_struct *work) + /* If the device is unplugged or !netif_running(), the workqueue + * doesn't need to wake the device, and could return directly. + */ +- if (test_bit(RTL8152_UNPLUG, &tp->flags) || !netif_running(tp->netdev)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags) || !netif_running(tp->netdev)) + return; + + if (usb_autopm_get_interface(tp->intf) < 0) +@@ -6748,7 +6762,7 @@ static void rtl_hw_phy_work_func_t(struct work_struct *work) + { + struct r8152 *tp = container_of(work, struct r8152, hw_phy_work.work); + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + if (usb_autopm_get_interface(tp->intf) < 0) +@@ -6875,7 +6889,7 @@ static int rtl8152_close(struct net_device *netdev) + netif_stop_queue(netdev); + + res = usb_autopm_get_interface(tp->intf); +- if (res < 0 || test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ if (res < 0 || test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { + rtl_drop_queued_tx(tp); + rtl_stop_rx(tp); + } else { +@@ -6908,7 +6922,7 @@ static void r8152b_init(struct r8152 *tp) + u32 ocp_data; + u16 data; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + data = r8152_mdio_read(tp, MII_BMCR); +@@ -6952,7 +6966,7 @@ static void r8153_init(struct r8152 *tp) + u16 data; + int i; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8153_u1u2en(tp, false); +@@ -6963,7 +6977,7 @@ static void r8153_init(struct r8152 *tp) + break; + + msleep(20); +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + break; + } + +@@ -7092,7 +7106,7 @@ static void r8153b_init(struct r8152 *tp) + u16 data; + int i; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8153b_u1u2en(tp, false); +@@ -7103,7 +7117,7 @@ static void r8153b_init(struct r8152 *tp) + break; + + msleep(20); +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + break; + } + +@@ -7174,7 +7188,7 @@ static void r8153c_init(struct r8152 *tp) + u16 data; + int i; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8153b_u1u2en(tp, false); +@@ -7194,7 +7208,7 @@ static void r8153c_init(struct r8152 *tp) + break; + + msleep(20); +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + } + +@@ -8023,7 +8037,7 @@ static void r8156_init(struct r8152 *tp) + u16 data; + int i; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); +@@ -8044,7 +8058,7 @@ static void r8156_init(struct r8152 *tp) + break; + + msleep(20); +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + } + +@@ -8119,7 +8133,7 @@ static void r8156b_init(struct r8152 *tp) + u16 data; + int i; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); +@@ -8153,7 +8167,7 @@ static void r8156b_init(struct r8152 *tp) + break; + + msleep(20); +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + } + +@@ -9219,7 +9233,7 @@ static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) + struct mii_ioctl_data *data = if_mii(rq); + int res; + +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + + res = usb_autopm_get_interface(tp->intf); +@@ -9321,7 +9335,7 @@ static const struct net_device_ops rtl8152_netdev_ops = { + + static void rtl8152_unload(struct r8152 *tp) + { +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + if (tp->version != RTL_VER_01) +@@ -9330,7 +9344,7 @@ static void rtl8152_unload(struct r8152 *tp) + + static void rtl8153_unload(struct r8152 *tp) + { +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8153_power_cut_en(tp, false); +@@ -9338,7 +9352,7 @@ static void rtl8153_unload(struct r8152 *tp) + + static void rtl8153b_unload(struct r8152 *tp) + { +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8153b_power_cut_en(tp, false); +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index 69f9e69208f68..118bf08a708b9 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -154,6 +154,11 @@ enum nvme_quirks { + * No temperature thresholds for channels other than 0 (Composite). + */ + NVME_QUIRK_NO_SECONDARY_TEMP_THRESH = (1 << 19), ++ ++ /* ++ * Disables simple suspend/resume path. ++ */ ++ NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND = (1 << 20), + }; + + /* +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 886c3fc9578e4..3d01290994d89 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3093,6 +3093,18 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) + if ((dmi_match(DMI_BOARD_VENDOR, "LENOVO")) && + dmi_match(DMI_BOARD_NAME, "LNVNB161216")) + return NVME_QUIRK_SIMPLE_SUSPEND; ++ } else if (pdev->vendor == 0x2646 && (pdev->device == 0x2263 || ++ pdev->device == 0x500f)) { ++ /* ++ * Exclude some Kingston NV1 and A2000 devices from ++ * NVME_QUIRK_SIMPLE_SUSPEND. Do a full suspend to save a ++ * lot fo energy with s2idle sleep on some TUXEDO platforms. ++ */ ++ if (dmi_match(DMI_BOARD_NAME, "NS5X_NS7XAU") || ++ dmi_match(DMI_BOARD_NAME, "NS5x_7xAU") || ++ dmi_match(DMI_BOARD_NAME, "NS5x_7xPU") || ++ dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1")) ++ return NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND; + } + + return 0; +@@ -3133,7 +3145,9 @@ static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev, + dev->dev = get_device(&pdev->dev); + + quirks |= check_vendor_combination_bug(pdev); +- if (!noacpi && acpi_storage_d3(&pdev->dev)) { ++ if (!noacpi && ++ !(quirks & NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND) && ++ acpi_storage_d3(&pdev->dev)) { + /* + * Some systems use a bios work around to ask for D3 on + * platforms that support kernel managed suspend. +diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c +index 0fbf331a748fd..9bb9fe0fad07c 100644 +--- a/drivers/of/dynamic.c ++++ b/drivers/of/dynamic.c +@@ -104,8 +104,9 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p) + * + * Returns the new state of a device based on the notifier used. + * +- * Return: 0 on device going from enabled to disabled, 1 on device +- * going from disabled to enabled and -1 on no change. ++ * Return: OF_RECONFIG_CHANGE_REMOVE on device going from enabled to ++ * disabled, OF_RECONFIG_CHANGE_ADD on device going from disabled to ++ * enabled and OF_RECONFIG_NO_CHANGE on no change. + */ + int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr) + { +diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c +index 5784dc20fb382..4605758d32146 100644 +--- a/drivers/parport/parport_pc.c ++++ b/drivers/parport/parport_pc.c +@@ -2614,6 +2614,8 @@ enum parport_pc_pci_cards { + netmos_9865, + quatech_sppxp100, + wch_ch382l, ++ brainboxes_uc146, ++ brainboxes_px203, + }; + + +@@ -2678,6 +2680,8 @@ static struct parport_pc_pci { + /* netmos_9865 */ { 1, { { 0, -1 }, } }, + /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, + /* wch_ch382l */ { 1, { { 2, -1 }, } }, ++ /* brainboxes_uc146 */ { 1, { { 3, -1 }, } }, ++ /* brainboxes_px203 */ { 1, { { 0, -1 }, } }, + }; + + static const struct pci_device_id parport_pc_pci_tbl[] = { +@@ -2771,6 +2775,23 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { + PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, + /* WCH CH382L PCI-E single parallel port card */ + { 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382l }, ++ /* Brainboxes IX-500/550 */ ++ { PCI_VENDOR_ID_INTASHIELD, 0x402a, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, ++ /* Brainboxes UC-146/UC-157 */ ++ { PCI_VENDOR_ID_INTASHIELD, 0x0be1, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc146 }, ++ { PCI_VENDOR_ID_INTASHIELD, 0x0be2, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc146 }, ++ /* Brainboxes PX-146/PX-257 */ ++ { PCI_VENDOR_ID_INTASHIELD, 0x401c, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, ++ /* Brainboxes PX-203 */ ++ { PCI_VENDOR_ID_INTASHIELD, 0x4007, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_px203 }, ++ /* Brainboxes PX-475 */ ++ { PCI_VENDOR_ID_INTASHIELD, 0x401f, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, + { 0, } /* terminate list */ + }; + MODULE_DEVICE_TABLE(pci, parport_pc_pci_tbl); +diff --git a/drivers/platform/mellanox/mlxbf-bootctl.c b/drivers/platform/mellanox/mlxbf-bootctl.c +index 1c7a288b59a5c..6a171a4f9dc68 100644 +--- a/drivers/platform/mellanox/mlxbf-bootctl.c ++++ b/drivers/platform/mellanox/mlxbf-bootctl.c +@@ -17,6 +17,7 @@ + + #define MLXBF_BOOTCTL_SB_SECURE_MASK 0x03 + #define MLXBF_BOOTCTL_SB_TEST_MASK 0x0c ++#define MLXBF_BOOTCTL_SB_DEV_MASK BIT(4) + + #define MLXBF_SB_KEY_NUM 4 + +@@ -37,11 +38,18 @@ static struct mlxbf_bootctl_name boot_names[] = { + { MLXBF_BOOTCTL_NONE, "none" }, + }; + ++enum { ++ MLXBF_BOOTCTL_SB_LIFECYCLE_PRODUCTION = 0, ++ MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE = 1, ++ MLXBF_BOOTCTL_SB_LIFECYCLE_GA_NON_SECURE = 2, ++ MLXBF_BOOTCTL_SB_LIFECYCLE_RMA = 3 ++}; ++ + static const char * const mlxbf_bootctl_lifecycle_states[] = { +- [0] = "Production", +- [1] = "GA Secured", +- [2] = "GA Non-Secured", +- [3] = "RMA", ++ [MLXBF_BOOTCTL_SB_LIFECYCLE_PRODUCTION] = "Production", ++ [MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE] = "GA Secured", ++ [MLXBF_BOOTCTL_SB_LIFECYCLE_GA_NON_SECURE] = "GA Non-Secured", ++ [MLXBF_BOOTCTL_SB_LIFECYCLE_RMA] = "RMA", + }; + + /* ARM SMC call which is atomic and no need for lock. */ +@@ -165,25 +173,30 @@ static ssize_t second_reset_action_store(struct device *dev, + static ssize_t lifecycle_state_show(struct device *dev, + struct device_attribute *attr, char *buf) + { ++ int status_bits; ++ int use_dev_key; ++ int test_state; + int lc_state; + +- lc_state = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS, +- MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE); +- if (lc_state < 0) +- return lc_state; ++ status_bits = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS, ++ MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE); ++ if (status_bits < 0) ++ return status_bits; + +- lc_state &= +- MLXBF_BOOTCTL_SB_TEST_MASK | MLXBF_BOOTCTL_SB_SECURE_MASK; ++ use_dev_key = status_bits & MLXBF_BOOTCTL_SB_DEV_MASK; ++ test_state = status_bits & MLXBF_BOOTCTL_SB_TEST_MASK; ++ lc_state = status_bits & MLXBF_BOOTCTL_SB_SECURE_MASK; + + /* + * If the test bits are set, we specify that the current state may be + * due to using the test bits. + */ +- if (lc_state & MLXBF_BOOTCTL_SB_TEST_MASK) { +- lc_state &= MLXBF_BOOTCTL_SB_SECURE_MASK; +- ++ if (test_state) { + return sprintf(buf, "%s(test)\n", + mlxbf_bootctl_lifecycle_states[lc_state]); ++ } else if (use_dev_key && ++ (lc_state == MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE)) { ++ return sprintf(buf, "Secured (development)\n"); + } + + return sprintf(buf, "%s\n", mlxbf_bootctl_lifecycle_states[lc_state]); +diff --git a/drivers/platform/mellanox/mlxbf-pmc.c b/drivers/platform/mellanox/mlxbf-pmc.c +index 2d4bbe99959ef..db7a1d360cd2c 100644 +--- a/drivers/platform/mellanox/mlxbf-pmc.c ++++ b/drivers/platform/mellanox/mlxbf-pmc.c +@@ -1202,6 +1202,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num) + attr->dev_attr.show = mlxbf_pmc_event_list_show; + attr->nr = blk_num; + attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, "event_list"); ++ if (!attr->dev_attr.attr.name) ++ return -ENOMEM; + pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr; + attr = NULL; + +@@ -1214,6 +1216,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num) + attr->nr = blk_num; + attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + "enable"); ++ if (!attr->dev_attr.attr.name) ++ return -ENOMEM; + pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr; + attr = NULL; + } +@@ -1240,6 +1244,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num) + attr->nr = blk_num; + attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + "counter%d", j); ++ if (!attr->dev_attr.attr.name) ++ return -ENOMEM; + pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr; + attr = NULL; + +@@ -1251,6 +1257,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num) + attr->nr = blk_num; + attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + "event%d", j); ++ if (!attr->dev_attr.attr.name) ++ return -ENOMEM; + pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr; + attr = NULL; + } +@@ -1283,6 +1291,8 @@ static int mlxbf_pmc_init_perftype_reg(struct device *dev, int blk_num) + attr->nr = blk_num; + attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + events[j].evt_name); ++ if (!attr->dev_attr.attr.name) ++ return -ENOMEM; + pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr; + attr = NULL; + i++; +@@ -1311,6 +1321,8 @@ static int mlxbf_pmc_create_groups(struct device *dev, int blk_num) + pmc->block[blk_num].block_attr_grp.attrs = pmc->block[blk_num].block_attr; + pmc->block[blk_num].block_attr_grp.name = devm_kasprintf( + dev, GFP_KERNEL, pmc->block_name[blk_num]); ++ if (!pmc->block[blk_num].block_attr_grp.name) ++ return -ENOMEM; + pmc->groups[blk_num] = &pmc->block[blk_num].block_attr_grp; + + return 0; +@@ -1442,6 +1454,8 @@ static int mlxbf_pmc_probe(struct platform_device *pdev) + + pmc->hwmon_dev = devm_hwmon_device_register_with_groups( + dev, "bfperf", pmc, pmc->groups); ++ if (IS_ERR(pmc->hwmon_dev)) ++ return PTR_ERR(pmc->hwmon_dev); + platform_set_drvdata(pdev, pmc); + + return 0; +diff --git a/drivers/platform/surface/aggregator/core.c b/drivers/platform/surface/aggregator/core.c +index 1a6373dea109c..6152be38398c4 100644 +--- a/drivers/platform/surface/aggregator/core.c ++++ b/drivers/platform/surface/aggregator/core.c +@@ -231,9 +231,12 @@ static int ssam_receive_buf(struct serdev_device *dev, const unsigned char *buf, + size_t n) + { + struct ssam_controller *ctrl; ++ int ret; + + ctrl = serdev_device_get_drvdata(dev); +- return ssam_controller_receive_buf(ctrl, buf, n); ++ ret = ssam_controller_receive_buf(ctrl, buf, n); ++ ++ return ret < 0 ? 0 : ret; + } + + static void ssam_write_wakeup(struct serdev_device *dev) +diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig +index 1396a839dd8a4..d5acef3202dad 100644 +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -271,6 +271,7 @@ config ASUS_WMI + depends on RFKILL || RFKILL = n + depends on HOTPLUG_PCI + depends on ACPI_VIDEO || ACPI_VIDEO = n ++ depends on SERIO_I8042 || SERIO_I8042 = n + select INPUT_SPARSEKMAP + select LEDS_CLASS + select NEW_LEDS +@@ -287,7 +288,6 @@ config ASUS_WMI + config ASUS_NB_WMI + tristate "Asus Notebook WMI Driver" + depends on ASUS_WMI +- depends on SERIO_I8042 || SERIO_I8042 = n + help + This is a driver for newer Asus notebooks. It adds extra features + like wireless radio and bluetooth control, leds, hotkeys, backlight... +diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c +index df1db54d4e183..af3da303e2b15 100644 +--- a/drivers/platform/x86/asus-nb-wmi.c ++++ b/drivers/platform/x86/asus-nb-wmi.c +@@ -501,8 +501,6 @@ static const struct dmi_system_id asus_quirks[] = { + + static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) + { +- int ret; +- + quirks = &quirk_asus_unknown; + dmi_check_system(asus_quirks); + +@@ -517,15 +515,6 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) + + if (tablet_mode_sw != -1) + quirks->tablet_switch_mode = tablet_mode_sw; +- +- if (quirks->i8042_filter) { +- ret = i8042_install_filter(quirks->i8042_filter); +- if (ret) { +- pr_warn("Unable to install key filter\n"); +- return; +- } +- pr_info("Using i8042 filter function for receiving events\n"); +- } + } + + static const struct key_entry asus_nb_wmi_keymap[] = { +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 49dd55b8e8faf..296150eaef929 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -3839,6 +3839,12 @@ static int asus_wmi_add(struct platform_device *pdev) + goto fail_wmi_handler; + } + ++ if (asus->driver->quirks->i8042_filter) { ++ err = i8042_install_filter(asus->driver->quirks->i8042_filter); ++ if (err) ++ pr_warn("Unable to install key filter - %d\n", err); ++ } ++ + asus_wmi_battery_init(asus); + + asus_wmi_debugfs_init(asus); +@@ -3873,6 +3879,8 @@ static int asus_wmi_remove(struct platform_device *device) + struct asus_wmi *asus; + + asus = platform_get_drvdata(device); ++ if (asus->driver->quirks->i8042_filter) ++ i8042_remove_filter(asus->driver->quirks->i8042_filter); + wmi_remove_notify_handler(asus->driver->event_guid); + asus_wmi_backlight_exit(asus); + asus_wmi_input_exit(asus); +diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c +index 2b79377cc21e2..b3f3e23a64eee 100644 +--- a/drivers/platform/x86/wmi.c ++++ b/drivers/platform/x86/wmi.c +@@ -1227,6 +1227,11 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) + if (debug_dump_wdg) + wmi_dump_wdg(&gblock[i]); + ++ if (!gblock[i].instance_count) { ++ dev_info(wmi_bus_dev, FW_INFO "%pUL has zero instances\n", &gblock[i].guid); ++ continue; ++ } ++ + if (guid_already_parsed_for_legacy(device, &gblock[i].guid)) + continue; + +diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c +index 8a2f18fa3faf5..9193c3b8edebe 100644 +--- a/drivers/powercap/dtpm_cpu.c ++++ b/drivers/powercap/dtpm_cpu.c +@@ -140,6 +140,8 @@ static void pd_release(struct dtpm *dtpm) + if (policy) { + for_each_cpu(dtpm_cpu->cpu, policy->related_cpus) + per_cpu(dtpm_per_cpu, dtpm_cpu->cpu) = NULL; ++ ++ cpufreq_cpu_put(policy); + } + + kfree(dtpm_cpu); +@@ -191,12 +193,16 @@ static int __dtpm_cpu_setup(int cpu, struct dtpm *parent) + return 0; + + pd = em_cpu_get(cpu); +- if (!pd || em_is_artificial(pd)) +- return -EINVAL; ++ if (!pd || em_is_artificial(pd)) { ++ ret = -EINVAL; ++ goto release_policy; ++ } + + dtpm_cpu = kzalloc(sizeof(*dtpm_cpu), GFP_KERNEL); +- if (!dtpm_cpu) +- return -ENOMEM; ++ if (!dtpm_cpu) { ++ ret = -ENOMEM; ++ goto release_policy; ++ } + + dtpm_init(&dtpm_cpu->dtpm, &dtpm_ops); + dtpm_cpu->cpu = cpu; +@@ -216,6 +222,7 @@ static int __dtpm_cpu_setup(int cpu, struct dtpm *parent) + if (ret) + goto out_dtpm_unregister; + ++ cpufreq_cpu_put(policy); + return 0; + + out_dtpm_unregister: +@@ -227,6 +234,8 @@ out_kfree_dtpm_cpu: + per_cpu(dtpm_per_cpu, cpu) = NULL; + kfree(dtpm_cpu); + ++release_policy: ++ cpufreq_cpu_put(policy); + return ret; + } + +diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c +index 50a577ac3bb42..b6df0d4319072 100644 +--- a/drivers/scsi/be2iscsi/be_main.c ++++ b/drivers/scsi/be2iscsi/be_main.c +@@ -2710,6 +2710,7 @@ init_wrb_hndl_failed: + kfree(pwrb_context->pwrb_handle_base); + kfree(pwrb_context->pwrb_handle_basestd); + } ++ kfree(phwi_ctxt->be_wrbq); + return -ENOMEM; + } + +diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c +index 64f0e047c23d2..4b10921276942 100644 +--- a/drivers/tee/optee/device.c ++++ b/drivers/tee/optee/device.c +@@ -60,7 +60,16 @@ static void optee_release_device(struct device *dev) + kfree(optee_device); + } + +-static int optee_register_device(const uuid_t *device_uuid) ++static ssize_t need_supplicant_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ return 0; ++} ++ ++static DEVICE_ATTR_RO(need_supplicant); ++ ++static int optee_register_device(const uuid_t *device_uuid, u32 func) + { + struct tee_client_device *optee_device = NULL; + int rc; +@@ -83,6 +92,10 @@ static int optee_register_device(const uuid_t *device_uuid) + put_device(&optee_device->dev); + } + ++ if (func == PTA_CMD_GET_DEVICES_SUPP) ++ device_create_file(&optee_device->dev, ++ &dev_attr_need_supplicant); ++ + return rc; + } + +@@ -142,7 +155,7 @@ static int __optee_enumerate_devices(u32 func) + num_devices = shm_size / sizeof(uuid_t); + + for (idx = 0; idx < num_devices; idx++) { +- rc = optee_register_device(&device_uuid[idx]); ++ rc = optee_register_device(&device_uuid[idx], func); + if (rc) + goto out_shm; + } +diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c +index 7db51781289ed..88035100b86c6 100644 +--- a/drivers/tty/serial/8250/8250_dw.c ++++ b/drivers/tty/serial/8250/8250_dw.c +@@ -795,6 +795,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = { + { "INT33C5", (kernel_ulong_t)&dw8250_dw_apb }, + { "INT3434", (kernel_ulong_t)&dw8250_dw_apb }, + { "INT3435", (kernel_ulong_t)&dw8250_dw_apb }, ++ { "INTC10EE", (kernel_ulong_t)&dw8250_dw_apb }, + { }, + }; + MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); +diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c +index f271becfc46c1..02c9b98a6bbf1 100644 +--- a/drivers/tty/serial/8250/8250_early.c ++++ b/drivers/tty/serial/8250/8250_early.c +@@ -197,6 +197,7 @@ static int __init early_omap8250_setup(struct earlycon_device *device, + OF_EARLYCON_DECLARE(omap8250, "ti,omap2-uart", early_omap8250_setup); + OF_EARLYCON_DECLARE(omap8250, "ti,omap3-uart", early_omap8250_setup); + OF_EARLYCON_DECLARE(omap8250, "ti,omap4-uart", early_omap8250_setup); ++OF_EARLYCON_DECLARE(omap8250, "ti,am654-uart", early_omap8250_setup); + + #endif + +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index 2e21f74a24705..0b04d810b3e61 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -825,7 +825,7 @@ static void __dma_rx_do_complete(struct uart_8250_port *p) + if (priv->habit & UART_HAS_RHR_IT_DIS) { + reg = serial_in(p, UART_OMAP_IER2); + reg &= ~UART_OMAP_IER2_RHR_IT_DIS; +- serial_out(p, UART_OMAP_IER2, UART_OMAP_IER2_RHR_IT_DIS); ++ serial_out(p, UART_OMAP_IER2, reg); + } + + dmaengine_tx_status(rxchan, cookie, &state); +@@ -967,7 +967,7 @@ static int omap_8250_rx_dma(struct uart_8250_port *p) + if (priv->habit & UART_HAS_RHR_IT_DIS) { + reg = serial_in(p, UART_OMAP_IER2); + reg |= UART_OMAP_IER2_RHR_IT_DIS; +- serial_out(p, UART_OMAP_IER2, UART_OMAP_IER2_RHR_IT_DIS); ++ serial_out(p, UART_OMAP_IER2, reg); + } + + dma_async_issue_pending(dma->rxchan); +@@ -1186,10 +1186,12 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) + + status = serial_port_in(port, UART_LSR); + +- if (priv->habit & UART_HAS_EFR2) +- am654_8250_handle_rx_dma(up, iir, status); +- else +- status = omap_8250_handle_rx_dma(up, iir, status); ++ if ((iir & 0x3f) != UART_IIR_THRI) { ++ if (priv->habit & UART_HAS_EFR2) ++ am654_8250_handle_rx_dma(up, iir, status); ++ else ++ status = omap_8250_handle_rx_dma(up, iir, status); ++ } + + serial8250_modem_status(up); + if (status & UART_LSR_THRE && up->dma->tx_err) { +diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index 0a1cc36f93aa7..c74eaf2552c32 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -218,17 +218,18 @@ static struct vendor_data vendor_st = { + + /* Deals with DMA transactions */ + +-struct pl011_sgbuf { +- struct scatterlist sg; +- char *buf; ++struct pl011_dmabuf { ++ dma_addr_t dma; ++ size_t len; ++ char *buf; + }; + + struct pl011_dmarx_data { + struct dma_chan *chan; + struct completion complete; + bool use_buf_b; +- struct pl011_sgbuf sgbuf_a; +- struct pl011_sgbuf sgbuf_b; ++ struct pl011_dmabuf dbuf_a; ++ struct pl011_dmabuf dbuf_b; + dma_cookie_t cookie; + bool running; + struct timer_list timer; +@@ -241,7 +242,8 @@ struct pl011_dmarx_data { + + struct pl011_dmatx_data { + struct dma_chan *chan; +- struct scatterlist sg; ++ dma_addr_t dma; ++ size_t len; + char *buf; + bool queued; + }; +@@ -365,32 +367,24 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap) + + #define PL011_DMA_BUFFER_SIZE PAGE_SIZE + +-static int pl011_sgbuf_init(struct dma_chan *chan, struct pl011_sgbuf *sg, ++static int pl011_dmabuf_init(struct dma_chan *chan, struct pl011_dmabuf *db, + enum dma_data_direction dir) + { +- dma_addr_t dma_addr; +- +- sg->buf = dma_alloc_coherent(chan->device->dev, +- PL011_DMA_BUFFER_SIZE, &dma_addr, GFP_KERNEL); +- if (!sg->buf) ++ db->buf = dma_alloc_coherent(chan->device->dev, PL011_DMA_BUFFER_SIZE, ++ &db->dma, GFP_KERNEL); ++ if (!db->buf) + return -ENOMEM; +- +- sg_init_table(&sg->sg, 1); +- sg_set_page(&sg->sg, phys_to_page(dma_addr), +- PL011_DMA_BUFFER_SIZE, offset_in_page(dma_addr)); +- sg_dma_address(&sg->sg) = dma_addr; +- sg_dma_len(&sg->sg) = PL011_DMA_BUFFER_SIZE; ++ db->len = PL011_DMA_BUFFER_SIZE; + + return 0; + } + +-static void pl011_sgbuf_free(struct dma_chan *chan, struct pl011_sgbuf *sg, ++static void pl011_dmabuf_free(struct dma_chan *chan, struct pl011_dmabuf *db, + enum dma_data_direction dir) + { +- if (sg->buf) { ++ if (db->buf) { + dma_free_coherent(chan->device->dev, +- PL011_DMA_BUFFER_SIZE, sg->buf, +- sg_dma_address(&sg->sg)); ++ PL011_DMA_BUFFER_SIZE, db->buf, db->dma); + } + } + +@@ -551,8 +545,8 @@ static void pl011_dma_tx_callback(void *data) + + spin_lock_irqsave(&uap->port.lock, flags); + if (uap->dmatx.queued) +- dma_unmap_sg(dmatx->chan->device->dev, &dmatx->sg, 1, +- DMA_TO_DEVICE); ++ dma_unmap_single(dmatx->chan->device->dev, dmatx->dma, ++ dmatx->len, DMA_TO_DEVICE); + + dmacr = uap->dmacr; + uap->dmacr = dmacr & ~UART011_TXDMAE; +@@ -638,18 +632,19 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap) + memcpy(&dmatx->buf[first], &xmit->buf[0], second); + } + +- dmatx->sg.length = count; +- +- if (dma_map_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE) != 1) { ++ dmatx->len = count; ++ dmatx->dma = dma_map_single(dma_dev->dev, dmatx->buf, count, ++ DMA_TO_DEVICE); ++ if (dmatx->dma == DMA_MAPPING_ERROR) { + uap->dmatx.queued = false; + dev_dbg(uap->port.dev, "unable to map TX DMA\n"); + return -EBUSY; + } + +- desc = dmaengine_prep_slave_sg(chan, &dmatx->sg, 1, DMA_MEM_TO_DEV, ++ desc = dmaengine_prep_slave_single(chan, dmatx->dma, dmatx->len, DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc) { +- dma_unmap_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE); ++ dma_unmap_single(dma_dev->dev, dmatx->dma, dmatx->len, DMA_TO_DEVICE); + uap->dmatx.queued = false; + /* + * If DMA cannot be used right now, we complete this +@@ -813,8 +808,8 @@ __acquires(&uap->port.lock) + dmaengine_terminate_async(uap->dmatx.chan); + + if (uap->dmatx.queued) { +- dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1, +- DMA_TO_DEVICE); ++ dma_unmap_single(uap->dmatx.chan->device->dev, uap->dmatx.dma, ++ uap->dmatx.len, DMA_TO_DEVICE); + uap->dmatx.queued = false; + uap->dmacr &= ~UART011_TXDMAE; + pl011_write(uap->dmacr, uap, REG_DMACR); +@@ -828,15 +823,15 @@ static int pl011_dma_rx_trigger_dma(struct uart_amba_port *uap) + struct dma_chan *rxchan = uap->dmarx.chan; + struct pl011_dmarx_data *dmarx = &uap->dmarx; + struct dma_async_tx_descriptor *desc; +- struct pl011_sgbuf *sgbuf; ++ struct pl011_dmabuf *dbuf; + + if (!rxchan) + return -EIO; + + /* Start the RX DMA job */ +- sgbuf = uap->dmarx.use_buf_b ? +- &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; +- desc = dmaengine_prep_slave_sg(rxchan, &sgbuf->sg, 1, ++ dbuf = uap->dmarx.use_buf_b ? ++ &uap->dmarx.dbuf_b : &uap->dmarx.dbuf_a; ++ desc = dmaengine_prep_slave_single(rxchan, dbuf->dma, dbuf->len, + DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + /* +@@ -876,8 +871,8 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, + bool readfifo) + { + struct tty_port *port = &uap->port.state->port; +- struct pl011_sgbuf *sgbuf = use_buf_b ? +- &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; ++ struct pl011_dmabuf *dbuf = use_buf_b ? ++ &uap->dmarx.dbuf_b : &uap->dmarx.dbuf_a; + int dma_count = 0; + u32 fifotaken = 0; /* only used for vdbg() */ + +@@ -886,7 +881,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, + + if (uap->dmarx.poll_rate) { + /* The data can be taken by polling */ +- dmataken = sgbuf->sg.length - dmarx->last_residue; ++ dmataken = dbuf->len - dmarx->last_residue; + /* Recalculate the pending size */ + if (pending >= dmataken) + pending -= dmataken; +@@ -900,7 +895,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, + * Note that tty_insert_flip_buf() tries to take as many chars + * as it can. + */ +- dma_count = tty_insert_flip_string(port, sgbuf->buf + dmataken, ++ dma_count = tty_insert_flip_string(port, dbuf->buf + dmataken, + pending); + + uap->port.icount.rx += dma_count; +@@ -911,7 +906,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, + + /* Reset the last_residue for Rx DMA poll */ + if (uap->dmarx.poll_rate) +- dmarx->last_residue = sgbuf->sg.length; ++ dmarx->last_residue = dbuf->len; + + /* + * Only continue with trying to read the FIFO if all DMA chars have +@@ -946,8 +941,8 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap) + { + struct pl011_dmarx_data *dmarx = &uap->dmarx; + struct dma_chan *rxchan = dmarx->chan; +- struct pl011_sgbuf *sgbuf = dmarx->use_buf_b ? +- &dmarx->sgbuf_b : &dmarx->sgbuf_a; ++ struct pl011_dmabuf *dbuf = dmarx->use_buf_b ? ++ &dmarx->dbuf_b : &dmarx->dbuf_a; + size_t pending; + struct dma_tx_state state; + enum dma_status dmastat; +@@ -969,7 +964,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap) + pl011_write(uap->dmacr, uap, REG_DMACR); + uap->dmarx.running = false; + +- pending = sgbuf->sg.length - state.residue; ++ pending = dbuf->len - state.residue; + BUG_ON(pending > PL011_DMA_BUFFER_SIZE); + /* Then we terminate the transfer - we now know our residue */ + dmaengine_terminate_all(rxchan); +@@ -996,8 +991,8 @@ static void pl011_dma_rx_callback(void *data) + struct pl011_dmarx_data *dmarx = &uap->dmarx; + struct dma_chan *rxchan = dmarx->chan; + bool lastbuf = dmarx->use_buf_b; +- struct pl011_sgbuf *sgbuf = dmarx->use_buf_b ? +- &dmarx->sgbuf_b : &dmarx->sgbuf_a; ++ struct pl011_dmabuf *dbuf = dmarx->use_buf_b ? ++ &dmarx->dbuf_b : &dmarx->dbuf_a; + size_t pending; + struct dma_tx_state state; + int ret; +@@ -1015,7 +1010,7 @@ static void pl011_dma_rx_callback(void *data) + * the DMA irq handler. So we check the residue here. + */ + rxchan->device->device_tx_status(rxchan, dmarx->cookie, &state); +- pending = sgbuf->sg.length - state.residue; ++ pending = dbuf->len - state.residue; + BUG_ON(pending > PL011_DMA_BUFFER_SIZE); + /* Then we terminate the transfer - we now know our residue */ + dmaengine_terminate_all(rxchan); +@@ -1067,16 +1062,16 @@ static void pl011_dma_rx_poll(struct timer_list *t) + unsigned long flags; + unsigned int dmataken = 0; + unsigned int size = 0; +- struct pl011_sgbuf *sgbuf; ++ struct pl011_dmabuf *dbuf; + int dma_count; + struct dma_tx_state state; + +- sgbuf = dmarx->use_buf_b ? &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; ++ dbuf = dmarx->use_buf_b ? &uap->dmarx.dbuf_b : &uap->dmarx.dbuf_a; + rxchan->device->device_tx_status(rxchan, dmarx->cookie, &state); + if (likely(state.residue < dmarx->last_residue)) { +- dmataken = sgbuf->sg.length - dmarx->last_residue; ++ dmataken = dbuf->len - dmarx->last_residue; + size = dmarx->last_residue - state.residue; +- dma_count = tty_insert_flip_string(port, sgbuf->buf + dmataken, ++ dma_count = tty_insert_flip_string(port, dbuf->buf + dmataken, + size); + if (dma_count == size) + dmarx->last_residue = state.residue; +@@ -1123,7 +1118,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap) + return; + } + +- sg_init_one(&uap->dmatx.sg, uap->dmatx.buf, PL011_DMA_BUFFER_SIZE); ++ uap->dmatx.len = PL011_DMA_BUFFER_SIZE; + + /* The DMA buffer is now the FIFO the TTY subsystem can use */ + uap->port.fifosize = PL011_DMA_BUFFER_SIZE; +@@ -1133,7 +1128,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap) + goto skip_rx; + + /* Allocate and map DMA RX buffers */ +- ret = pl011_sgbuf_init(uap->dmarx.chan, &uap->dmarx.sgbuf_a, ++ ret = pl011_dmabuf_init(uap->dmarx.chan, &uap->dmarx.dbuf_a, + DMA_FROM_DEVICE); + if (ret) { + dev_err(uap->port.dev, "failed to init DMA %s: %d\n", +@@ -1141,12 +1136,12 @@ static void pl011_dma_startup(struct uart_amba_port *uap) + goto skip_rx; + } + +- ret = pl011_sgbuf_init(uap->dmarx.chan, &uap->dmarx.sgbuf_b, ++ ret = pl011_dmabuf_init(uap->dmarx.chan, &uap->dmarx.dbuf_b, + DMA_FROM_DEVICE); + if (ret) { + dev_err(uap->port.dev, "failed to init DMA %s: %d\n", + "RX buffer B", ret); +- pl011_sgbuf_free(uap->dmarx.chan, &uap->dmarx.sgbuf_a, ++ pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_a, + DMA_FROM_DEVICE); + goto skip_rx; + } +@@ -1200,8 +1195,9 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap) + /* In theory, this should already be done by pl011_dma_flush_buffer */ + dmaengine_terminate_all(uap->dmatx.chan); + if (uap->dmatx.queued) { +- dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1, +- DMA_TO_DEVICE); ++ dma_unmap_single(uap->dmatx.chan->device->dev, ++ uap->dmatx.dma, uap->dmatx.len, ++ DMA_TO_DEVICE); + uap->dmatx.queued = false; + } + +@@ -1212,8 +1208,8 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap) + if (uap->using_rx_dma) { + dmaengine_terminate_all(uap->dmarx.chan); + /* Clean up the RX DMA */ +- pl011_sgbuf_free(uap->dmarx.chan, &uap->dmarx.sgbuf_a, DMA_FROM_DEVICE); +- pl011_sgbuf_free(uap->dmarx.chan, &uap->dmarx.sgbuf_b, DMA_FROM_DEVICE); ++ pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_a, DMA_FROM_DEVICE); ++ pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_b, DMA_FROM_DEVICE); + if (uap->dmarx.poll_rate) + del_timer_sync(&uap->dmarx.timer); + uap->using_rx_dma = false; +diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c +index b398fba942964..b4b849415c503 100644 +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -769,6 +769,18 @@ static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) + case SC16IS7XX_IIR_RTOI_SRC: + case SC16IS7XX_IIR_XOFFI_SRC: + rxlen = sc16is7xx_port_read(port, SC16IS7XX_RXLVL_REG); ++ ++ /* ++ * There is a silicon bug that makes the chip report a ++ * time-out interrupt but no data in the FIFO. This is ++ * described in errata section 18.1.4. ++ * ++ * When this happens, read one byte from the FIFO to ++ * clear the interrupt. ++ */ ++ if (iir == SC16IS7XX_IIR_RTOI_SRC && !rxlen) ++ rxlen = 1; ++ + if (rxlen) + sc16is7xx_handle_rx(port, rxlen, iir); + break; +diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c +index 6be6009f911e1..f1ca9250cad96 100644 +--- a/drivers/usb/gadget/function/f_hid.c ++++ b/drivers/usb/gadget/function/f_hid.c +@@ -88,6 +88,7 @@ static void hidg_release(struct device *dev) + { + struct f_hidg *hidg = container_of(dev, struct f_hidg, dev); + ++ kfree(hidg->report_desc); + kfree(hidg->set_report_buf); + kfree(hidg); + } +@@ -1287,9 +1288,9 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) + hidg->report_length = opts->report_length; + hidg->report_desc_length = opts->report_desc_length; + if (opts->report_desc) { +- hidg->report_desc = devm_kmemdup(&hidg->dev, opts->report_desc, +- opts->report_desc_length, +- GFP_KERNEL); ++ hidg->report_desc = kmemdup(opts->report_desc, ++ opts->report_desc_length, ++ GFP_KERNEL); + if (!hidg->report_desc) { + put_device(&hidg->dev); + --opts->refcnt; +diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c +index 1c0c61e8ba696..c40f2ecbe1b8c 100644 +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -1608,8 +1608,6 @@ static void gadget_unbind_driver(struct device *dev) + + dev_dbg(&udc->dev, "unbinding gadget driver [%s]\n", driver->function); + +- kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); +- + udc->allow_connect = false; + cancel_work_sync(&udc->vbus_work); + mutex_lock(&udc->connect_lock); +@@ -1629,6 +1627,8 @@ static void gadget_unbind_driver(struct device *dev) + driver->is_bound = false; + udc->driver = NULL; + mutex_unlock(&udc_lock); ++ ++ kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); + } + + /* ------------------------------------------------------------------------- */ +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index 24bcf6ab12d8a..e02ef31da68e4 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -348,8 +348,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + /* xHC spec requires PCI devices to support D3hot and D3cold */ + if (xhci->hci_version >= 0x120) + xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; +- else if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version >= 0x110) +- xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; + + if (xhci->quirks & XHCI_RESET_ON_RESUME) + xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, +diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c +index 3c3bab33e03a5..49d6b2388b874 100644 +--- a/drivers/usb/typec/class.c ++++ b/drivers/usb/typec/class.c +@@ -267,7 +267,7 @@ static void typec_altmode_put_partner(struct altmode *altmode) + if (!partner) + return; + +- adev = &partner->adev; ++ adev = &altmode->adev; + + if (is_typec_plug(adev->dev.parent)) { + struct typec_plug *plug = to_typec_plug(adev->dev.parent); +@@ -497,7 +497,8 @@ static void typec_altmode_release(struct device *dev) + { + struct altmode *alt = to_altmode(to_typec_altmode(dev)); + +- typec_altmode_put_partner(alt); ++ if (!is_typec_port(dev->parent)) ++ typec_altmode_put_partner(alt); + + altmode_id_remove(alt->adev.dev.parent, alt->id); + kfree(alt); +diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c +index bf99654371b35..2b7e796c48897 100644 +--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c ++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c +@@ -2508,13 +2508,18 @@ static int setup_cvq_vring(struct mlx5_vdpa_dev *mvdev) + struct mlx5_control_vq *cvq = &mvdev->cvq; + int err = 0; + +- if (mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)) ++ if (mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)) { ++ u16 idx = cvq->vring.last_avail_idx; ++ + err = vringh_init_iotlb(&cvq->vring, mvdev->actual_features, + MLX5_CVQ_MAX_ENT, false, + (struct vring_desc *)(uintptr_t)cvq->desc_addr, + (struct vring_avail *)(uintptr_t)cvq->driver_addr, + (struct vring_used *)(uintptr_t)cvq->device_addr); + ++ if (!err) ++ cvq->vring.last_avail_idx = cvq->vring.last_used_idx = idx; ++ } + return err; + } + +diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c +index 2c6078a6b8ecb..58ca7c936393c 100644 +--- a/fs/nilfs2/sufile.c ++++ b/fs/nilfs2/sufile.c +@@ -501,15 +501,38 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum) + + down_write(&NILFS_MDT(sufile)->mi_sem); + ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh); +- if (!ret) { +- mark_buffer_dirty(bh); +- nilfs_mdt_mark_dirty(sufile); +- kaddr = kmap_atomic(bh->b_page); +- su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr); ++ if (ret) ++ goto out_sem; ++ ++ kaddr = kmap_atomic(bh->b_page); ++ su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr); ++ if (unlikely(nilfs_segment_usage_error(su))) { ++ struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; ++ ++ kunmap_atomic(kaddr); ++ brelse(bh); ++ if (nilfs_segment_is_active(nilfs, segnum)) { ++ nilfs_error(sufile->i_sb, ++ "active segment %llu is erroneous", ++ (unsigned long long)segnum); ++ } else { ++ /* ++ * Segments marked erroneous are never allocated by ++ * nilfs_sufile_alloc(); only active segments, ie, ++ * the segments indexed by ns_segnum or ns_nextnum, ++ * can be erroneous here. ++ */ ++ WARN_ON_ONCE(1); ++ } ++ ret = -EIO; ++ } else { + nilfs_segment_usage_set_dirty(su); + kunmap_atomic(kaddr); ++ mark_buffer_dirty(bh); ++ nilfs_mdt_mark_dirty(sufile); + brelse(bh); + } ++out_sem: + up_write(&NILFS_MDT(sufile)->mi_sem); + return ret; + } +@@ -536,9 +559,14 @@ int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, + + kaddr = kmap_atomic(bh->b_page); + su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr); +- WARN_ON(nilfs_segment_usage_error(su)); +- if (modtime) ++ if (modtime) { ++ /* ++ * Check segusage error and set su_lastmod only when updating ++ * this entry with a valid timestamp, not for cancellation. ++ */ ++ WARN_ON_ONCE(nilfs_segment_usage_error(su)); + su->su_lastmod = cpu_to_le64(modtime); ++ } + su->su_nblocks = cpu_to_le32(nblocks); + kunmap_atomic(kaddr); + +diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c +index 0f0667957c810..71400496ed365 100644 +--- a/fs/nilfs2/the_nilfs.c ++++ b/fs/nilfs2/the_nilfs.c +@@ -716,7 +716,11 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data) + goto failed_sbh; + } + nilfs_release_super_block(nilfs); +- sb_set_blocksize(sb, blocksize); ++ if (!sb_set_blocksize(sb, blocksize)) { ++ nilfs_err(sb, "bad blocksize %d", blocksize); ++ err = -EINVAL; ++ goto out; ++ } + + err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp); + if (err) +diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c +index 33ea1440f4b06..2e15b182e59fc 100644 +--- a/fs/smb/client/cifsfs.c ++++ b/fs/smb/client/cifsfs.c +@@ -1191,32 +1191,103 @@ const struct inode_operations cifs_symlink_inode_ops = { + .listxattr = cifs_listxattr, + }; + ++/* ++ * Advance the EOF marker to after the source range. ++ */ ++static int cifs_precopy_set_eof(struct inode *src_inode, struct cifsInodeInfo *src_cifsi, ++ struct cifs_tcon *src_tcon, ++ unsigned int xid, loff_t src_end) ++{ ++ struct cifsFileInfo *writeable_srcfile; ++ int rc = -EINVAL; ++ ++ writeable_srcfile = find_writable_file(src_cifsi, FIND_WR_FSUID_ONLY); ++ if (writeable_srcfile) { ++ if (src_tcon->ses->server->ops->set_file_size) ++ rc = src_tcon->ses->server->ops->set_file_size( ++ xid, src_tcon, writeable_srcfile, ++ src_inode->i_size, true /* no need to set sparse */); ++ else ++ rc = -ENOSYS; ++ cifsFileInfo_put(writeable_srcfile); ++ cifs_dbg(FYI, "SetFSize for copychunk rc = %d\n", rc); ++ } ++ ++ if (rc < 0) ++ goto set_failed; ++ ++ netfs_resize_file(&src_cifsi->netfs, src_end); ++ fscache_resize_cookie(cifs_inode_cookie(src_inode), src_end); ++ return 0; ++ ++set_failed: ++ return filemap_write_and_wait(src_inode->i_mapping); ++} ++ ++/* ++ * Flush out either the folio that overlaps the beginning of a range in which ++ * pos resides or the folio that overlaps the end of a range unless that folio ++ * is entirely within the range we're going to invalidate. We extend the flush ++ * bounds to encompass the folio. ++ */ ++static int cifs_flush_folio(struct inode *inode, loff_t pos, loff_t *_fstart, loff_t *_fend, ++ bool first) ++{ ++ struct folio *folio; ++ unsigned long long fpos, fend; ++ pgoff_t index = pos / PAGE_SIZE; ++ size_t size; ++ int rc = 0; ++ ++ folio = filemap_get_folio(inode->i_mapping, index); ++ if (IS_ERR(folio)) ++ return 0; ++ ++ size = folio_size(folio); ++ fpos = folio_pos(folio); ++ fend = fpos + size - 1; ++ *_fstart = min_t(unsigned long long, *_fstart, fpos); ++ *_fend = max_t(unsigned long long, *_fend, fend); ++ if ((first && pos == fpos) || (!first && pos == fend)) ++ goto out; ++ ++ rc = filemap_write_and_wait_range(inode->i_mapping, fpos, fend); ++out: ++ folio_put(folio); ++ return rc; ++} ++ + static loff_t cifs_remap_file_range(struct file *src_file, loff_t off, + struct file *dst_file, loff_t destoff, loff_t len, + unsigned int remap_flags) + { + struct inode *src_inode = file_inode(src_file); + struct inode *target_inode = file_inode(dst_file); ++ struct cifsInodeInfo *src_cifsi = CIFS_I(src_inode); ++ struct cifsInodeInfo *target_cifsi = CIFS_I(target_inode); + struct cifsFileInfo *smb_file_src = src_file->private_data; +- struct cifsFileInfo *smb_file_target; +- struct cifs_tcon *target_tcon; ++ struct cifsFileInfo *smb_file_target = dst_file->private_data; ++ struct cifs_tcon *target_tcon, *src_tcon; ++ unsigned long long destend, fstart, fend, new_size; + unsigned int xid; + int rc; + +- if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY)) ++ if (remap_flags & REMAP_FILE_DEDUP) ++ return -EOPNOTSUPP; ++ if (remap_flags & ~REMAP_FILE_ADVISORY) + return -EINVAL; + + cifs_dbg(FYI, "clone range\n"); + + xid = get_xid(); + +- if (!src_file->private_data || !dst_file->private_data) { ++ if (!smb_file_src || !smb_file_target) { + rc = -EBADF; + cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n"); + goto out; + } + +- smb_file_target = dst_file->private_data; ++ src_tcon = tlink_tcon(smb_file_src->tlink); + target_tcon = tlink_tcon(smb_file_target->tlink); + + /* +@@ -1229,20 +1300,63 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off, + if (len == 0) + len = src_inode->i_size - off; + +- cifs_dbg(FYI, "about to flush pages\n"); +- /* should we flush first and last page first */ +- truncate_inode_pages_range(&target_inode->i_data, destoff, +- PAGE_ALIGN(destoff + len)-1); ++ cifs_dbg(FYI, "clone range\n"); + +- if (target_tcon->ses->server->ops->duplicate_extents) ++ /* Flush the source buffer */ ++ rc = filemap_write_and_wait_range(src_inode->i_mapping, off, ++ off + len - 1); ++ if (rc) ++ goto unlock; ++ ++ /* The server-side copy will fail if the source crosses the EOF marker. ++ * Advance the EOF marker after the flush above to the end of the range ++ * if it's short of that. ++ */ ++ if (src_cifsi->netfs.remote_i_size < off + len) { ++ rc = cifs_precopy_set_eof(src_inode, src_cifsi, src_tcon, xid, off + len); ++ if (rc < 0) ++ goto unlock; ++ } ++ ++ new_size = destoff + len; ++ destend = destoff + len - 1; ++ ++ /* Flush the folios at either end of the destination range to prevent ++ * accidental loss of dirty data outside of the range. ++ */ ++ fstart = destoff; ++ fend = destend; ++ ++ rc = cifs_flush_folio(target_inode, destoff, &fstart, &fend, true); ++ if (rc) ++ goto unlock; ++ rc = cifs_flush_folio(target_inode, destend, &fstart, &fend, false); ++ if (rc) ++ goto unlock; ++ ++ /* Discard all the folios that overlap the destination region. */ ++ cifs_dbg(FYI, "about to discard pages %llx-%llx\n", fstart, fend); ++ truncate_inode_pages_range(&target_inode->i_data, fstart, fend); ++ ++ fscache_invalidate(cifs_inode_cookie(target_inode), NULL, ++ i_size_read(target_inode), 0); ++ ++ rc = -EOPNOTSUPP; ++ if (target_tcon->ses->server->ops->duplicate_extents) { + rc = target_tcon->ses->server->ops->duplicate_extents(xid, + smb_file_src, smb_file_target, off, len, destoff); +- else +- rc = -EOPNOTSUPP; ++ if (rc == 0 && new_size > i_size_read(target_inode)) { ++ truncate_setsize(target_inode, new_size); ++ netfs_resize_file(&target_cifsi->netfs, new_size); ++ fscache_resize_cookie(cifs_inode_cookie(target_inode), ++ new_size); ++ } ++ } + + /* force revalidate of size and timestamps of target file now + that target is updated on the server */ + CIFS_I(target_inode)->time = 0; ++unlock: + /* although unlocking in the reverse order from locking is not + strictly necessary here it is a little cleaner to be consistent */ + unlock_two_nondirectories(src_inode, target_inode); +@@ -1258,10 +1372,12 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, + { + struct inode *src_inode = file_inode(src_file); + struct inode *target_inode = file_inode(dst_file); ++ struct cifsInodeInfo *src_cifsi = CIFS_I(src_inode); + struct cifsFileInfo *smb_file_src; + struct cifsFileInfo *smb_file_target; + struct cifs_tcon *src_tcon; + struct cifs_tcon *target_tcon; ++ unsigned long long destend, fstart, fend; + ssize_t rc; + + cifs_dbg(FYI, "copychunk range\n"); +@@ -1301,13 +1417,41 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, + if (rc) + goto unlock; + +- /* should we flush first and last page first */ +- truncate_inode_pages(&target_inode->i_data, 0); ++ /* The server-side copy will fail if the source crosses the EOF marker. ++ * Advance the EOF marker after the flush above to the end of the range ++ * if it's short of that. ++ */ ++ if (src_cifsi->server_eof < off + len) { ++ rc = cifs_precopy_set_eof(src_inode, src_cifsi, src_tcon, xid, off + len); ++ if (rc < 0) ++ goto unlock; ++ } ++ ++ destend = destoff + len - 1; ++ ++ /* Flush the folios at either end of the destination range to prevent ++ * accidental loss of dirty data outside of the range. ++ */ ++ fstart = destoff; ++ fend = destend; ++ ++ rc = cifs_flush_folio(target_inode, destoff, &fstart, &fend, true); ++ if (rc) ++ goto unlock; ++ rc = cifs_flush_folio(target_inode, destend, &fstart, &fend, false); ++ if (rc) ++ goto unlock; ++ ++ /* Discard all the folios that overlap the destination region. */ ++ truncate_inode_pages_range(&target_inode->i_data, fstart, fend); + + rc = file_modified(dst_file); +- if (!rc) ++ if (!rc) { + rc = target_tcon->ses->server->ops->copychunk_range(xid, + smb_file_src, smb_file_target, off, len, destoff); ++ if (rc > 0 && destoff + rc > i_size_read(target_inode)) ++ truncate_setsize(target_inode, destoff + rc); ++ } + + file_accessed(src_file); + +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index e628848a1df93..6ef3c00de5ca1 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -2834,6 +2834,8 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, + usleep_range(512, 2048); + } while (++retry_count < 5); + ++ if (!rc && !dfs_rsp) ++ rc = -EIO; + if (rc) { + if (!is_retryable_error(rc) && rc != -ENOENT && rc != -EOPNOTSUPP) + cifs_tcon_dbg(VFS, "%s: ioctl error: rc=%d\n", __func__, rc); +diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h +index c7e0d80dbf6a5..67575bc8a7e29 100644 +--- a/include/linux/cpuhotplug.h ++++ b/include/linux/cpuhotplug.h +@@ -196,6 +196,7 @@ enum cpuhp_state { + CPUHP_AP_ARM_CORESIGHT_CTI_STARTING, + CPUHP_AP_ARM64_ISNDEP_STARTING, + CPUHP_AP_SMPCFD_DYING, ++ CPUHP_AP_HRTIMERS_DYING, + CPUHP_AP_X86_TBOOT_DYING, + CPUHP_AP_ARM_CACHE_B15_RAC_DYING, + CPUHP_AP_ONLINE, +diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h +index 0ee140176f102..f2044d5a652b5 100644 +--- a/include/linux/hrtimer.h ++++ b/include/linux/hrtimer.h +@@ -531,9 +531,9 @@ extern void sysrq_timer_list_show(void); + + int hrtimers_prepare_cpu(unsigned int cpu); + #ifdef CONFIG_HOTPLUG_CPU +-int hrtimers_dead_cpu(unsigned int cpu); ++int hrtimers_cpu_dying(unsigned int cpu); + #else +-#define hrtimers_dead_cpu NULL ++#define hrtimers_cpu_dying NULL + #endif + + #endif +diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h +index e46f6b49eb389..1c6f35ba1604f 100644 +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -880,10 +880,7 @@ static inline bool hugepage_migration_supported(struct hstate *h) + return arch_hugetlb_migration_supported(h); + } + +-static inline bool __vma_private_lock(struct vm_area_struct *vma) +-{ +- return (!(vma->vm_flags & VM_MAYSHARE)) && vma->vm_private_data; +-} ++bool __vma_private_lock(struct vm_area_struct *vma); + + /* + * Movability check is different as compared to migration check. +diff --git a/include/linux/iommu.h b/include/linux/iommu.h +index 3c9da1f8979e3..9d87090953bcc 100644 +--- a/include/linux/iommu.h ++++ b/include/linux/iommu.h +@@ -657,6 +657,7 @@ static inline void dev_iommu_priv_set(struct device *dev, void *priv) + dev->iommu->priv = priv; + } + ++extern struct mutex iommu_probe_device_lock; + int iommu_probe_device(struct device *dev); + void iommu_release_device(struct device *dev); + +diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h +index 85a64cb95d755..8de5d51a0b5e7 100644 +--- a/include/linux/kprobes.h ++++ b/include/linux/kprobes.h +@@ -140,7 +140,7 @@ static inline bool kprobe_ftrace(struct kprobe *p) + * + */ + struct kretprobe_holder { +- struct kretprobe *rp; ++ struct kretprobe __rcu *rp; + refcount_t ref; + }; + +@@ -202,10 +202,8 @@ extern int arch_trampoline_kprobe(struct kprobe *p); + #ifdef CONFIG_KRETPROBE_ON_RETHOOK + static nokprobe_inline struct kretprobe *get_kretprobe(struct kretprobe_instance *ri) + { +- RCU_LOCKDEP_WARN(!rcu_read_lock_any_held(), +- "Kretprobe is accessed from instance under preemptive context"); +- +- return (struct kretprobe *)READ_ONCE(ri->node.rethook->data); ++ /* rethook::data is non-changed field, so that you can access it freely. */ ++ return (struct kretprobe *)ri->node.rethook->data; + } + static nokprobe_inline unsigned long get_kretprobe_retaddr(struct kretprobe_instance *ri) + { +@@ -250,10 +248,7 @@ unsigned long kretprobe_trampoline_handler(struct pt_regs *regs, + + static nokprobe_inline struct kretprobe *get_kretprobe(struct kretprobe_instance *ri) + { +- RCU_LOCKDEP_WARN(!rcu_read_lock_any_held(), +- "Kretprobe is accessed from instance under preemptive context"); +- +- return READ_ONCE(ri->rph->rp); ++ return rcu_dereference_check(ri->rph->rp, rcu_read_lock_any_held()); + } + + static nokprobe_inline unsigned long get_kretprobe_retaddr(struct kretprobe_instance *ri) +diff --git a/include/linux/rethook.h b/include/linux/rethook.h +index bdbe6717f45a2..a00963f33bc14 100644 +--- a/include/linux/rethook.h ++++ b/include/linux/rethook.h +@@ -29,7 +29,12 @@ typedef void (*rethook_handler_t) (struct rethook_node *, void *, struct pt_regs + */ + struct rethook { + void *data; +- rethook_handler_t handler; ++ /* ++ * To avoid sparse warnings, this uses a raw function pointer with ++ * __rcu, instead of rethook_handler_t. But this must be same as ++ * rethook_handler_t. ++ */ ++ void (__rcu *handler) (struct rethook_node *, void *, struct pt_regs *); + struct freelist_head pool; + refcount_t ref; + struct rcu_head rcu; +diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h +index d82ff9fa1a6e8..9f4a4f70270df 100644 +--- a/include/linux/stmmac.h ++++ b/include/linux/stmmac.h +@@ -172,6 +172,7 @@ struct stmmac_fpe_cfg { + bool hs_enable; /* FPE handshake enable */ + enum stmmac_fpe_state lp_fpe_state; /* Link Partner FPE state */ + enum stmmac_fpe_state lo_fpe_state; /* Local station FPE state */ ++ u32 fpe_csr; /* MAC_FPE_CTRL_STS reg cache */ + }; + + struct stmmac_safety_feature_cfg { +diff --git a/include/net/genetlink.h b/include/net/genetlink.h +index 9f97f73615b69..b9e5a22ae3ff9 100644 +--- a/include/net/genetlink.h ++++ b/include/net/genetlink.h +@@ -12,10 +12,12 @@ + * struct genl_multicast_group - generic netlink multicast group + * @name: name of the multicast group, names are per-family + * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM) ++ * @cap_sys_admin: whether %CAP_SYS_ADMIN is required for binding + */ + struct genl_multicast_group { + char name[GENL_NAMSIZ]; + u8 flags; ++ u8 cap_sys_admin:1; + }; + + struct genl_ops; +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 19646fdec23dc..c3d56b337f358 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -1460,17 +1460,22 @@ static inline int tcp_full_space(const struct sock *sk) + return tcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf)); + } + +-static inline void tcp_adjust_rcv_ssthresh(struct sock *sk) ++static inline void __tcp_adjust_rcv_ssthresh(struct sock *sk, u32 new_ssthresh) + { + int unused_mem = sk_unused_reserved_mem(sk); + struct tcp_sock *tp = tcp_sk(sk); + +- tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); ++ tp->rcv_ssthresh = min(tp->rcv_ssthresh, new_ssthresh); + if (unused_mem) + tp->rcv_ssthresh = max_t(u32, tp->rcv_ssthresh, + tcp_win_from_space(sk, unused_mem)); + } + ++static inline void tcp_adjust_rcv_ssthresh(struct sock *sk) ++{ ++ __tcp_adjust_rcv_ssthresh(sk, 4U * tcp_sk(sk)->advmss); ++} ++ + void tcp_cleanup_rbuf(struct sock *sk, int copied); + void __tcp_cleanup_rbuf(struct sock *sk, int copied); + +diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h +index 92a673cd9b4fd..77b83ea62dd69 100644 +--- a/include/rdma/ib_umem.h ++++ b/include/rdma/ib_umem.h +@@ -78,6 +78,13 @@ static inline void __rdma_umem_block_iter_start(struct ib_block_iter *biter, + { + __rdma_block_iter_start(biter, umem->sgt_append.sgt.sgl, + umem->sgt_append.sgt.nents, pgsz); ++ biter->__sg_advance = ib_umem_offset(umem) & ~(pgsz - 1); ++ biter->__sg_numblocks = ib_umem_num_dma_blocks(umem, pgsz); ++} ++ ++static inline bool __rdma_umem_block_iter_next(struct ib_block_iter *biter) ++{ ++ return __rdma_block_iter_next(biter) && biter->__sg_numblocks--; + } + + /** +@@ -93,7 +100,7 @@ static inline void __rdma_umem_block_iter_start(struct ib_block_iter *biter, + */ + #define rdma_umem_for_each_dma_block(umem, biter, pgsz) \ + for (__rdma_umem_block_iter_start(biter, umem, pgsz); \ +- __rdma_block_iter_next(biter);) ++ __rdma_umem_block_iter_next(biter);) + + #ifdef CONFIG_INFINIBAND_USER_MEM + +diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h +index 975d6e9efbcb4..5582509003264 100644 +--- a/include/rdma/ib_verbs.h ++++ b/include/rdma/ib_verbs.h +@@ -2835,6 +2835,7 @@ struct ib_block_iter { + /* internal states */ + struct scatterlist *__sg; /* sg holding the current aligned block */ + dma_addr_t __dma_addr; /* unaligned DMA address of this block */ ++ size_t __sg_numblocks; /* ib_umem_num_dma_blocks() */ + unsigned int __sg_nents; /* number of SG entries */ + unsigned int __sg_advance; /* number of bytes to advance in sg in next step */ + unsigned int __pg_bit; /* alignment of current block */ +diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h +index 466fd3f4447c2..af8f4c304d272 100644 +--- a/include/uapi/linux/netfilter/nf_tables.h ++++ b/include/uapi/linux/netfilter/nf_tables.h +@@ -816,12 +816,14 @@ enum nft_exthdr_flags { + * @NFT_EXTHDR_OP_TCP: match against tcp options + * @NFT_EXTHDR_OP_IPV4: match against ipv4 options + * @NFT_EXTHDR_OP_SCTP: match against sctp chunks ++ * @NFT_EXTHDR_OP_DCCP: match against dccp otions + */ + enum nft_exthdr_op { + NFT_EXTHDR_OP_IPV6, + NFT_EXTHDR_OP_TCPOPT, + NFT_EXTHDR_OP_IPV4, + NFT_EXTHDR_OP_SCTP, ++ NFT_EXTHDR_OP_DCCP, + __NFT_EXTHDR_OP_MAX + }; + #define NFT_EXTHDR_OP_MAX (__NFT_EXTHDR_OP_MAX - 1) +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index f413ebed81ab3..35894955b4549 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -1377,6 +1377,7 @@ static __cold void io_iopoll_try_reap_events(struct io_ring_ctx *ctx) + if (!(ctx->flags & IORING_SETUP_IOPOLL)) + return; + ++ percpu_ref_get(&ctx->refs); + mutex_lock(&ctx->uring_lock); + while (!wq_list_empty(&ctx->iopoll_list)) { + /* let it sleep and repeat later if can't complete a request */ +@@ -1394,6 +1395,7 @@ static __cold void io_iopoll_try_reap_events(struct io_ring_ctx *ctx) + } + } + mutex_unlock(&ctx->uring_lock); ++ percpu_ref_put(&ctx->refs); + } + + static int io_iopoll_check(struct io_ring_ctx *ctx, long min) +@@ -2800,12 +2802,7 @@ static __cold void io_ring_exit_work(struct work_struct *work) + init_completion(&exit.completion); + init_task_work(&exit.task_work, io_tctx_exit_cb); + exit.ctx = ctx; +- /* +- * Some may use context even when all refs and requests have been put, +- * and they are free to do so while still holding uring_lock or +- * completion_lock, see io_req_task_submit(). Apart from other work, +- * this lock/unlock section also waits them to finish. +- */ ++ + mutex_lock(&ctx->uring_lock); + while (!list_empty(&ctx->tctx_list)) { + WARN_ON_ONCE(time_after(jiffies, timeout)); +diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h +index d60c758326b42..acaf8dad05401 100644 +--- a/io_uring/rsrc.h ++++ b/io_uring/rsrc.h +@@ -79,17 +79,10 @@ int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, + + int __io_scm_file_account(struct io_ring_ctx *ctx, struct file *file); + +-#if defined(CONFIG_UNIX) +-static inline bool io_file_need_scm(struct file *filp) +-{ +- return !!unix_get_socket(filp); +-} +-#else + static inline bool io_file_need_scm(struct file *filp) + { + return false; + } +-#endif + + static inline int io_scm_file_account(struct io_ring_ctx *ctx, + struct file *file) +diff --git a/kernel/cgroup/legacy_freezer.c b/kernel/cgroup/legacy_freezer.c +index 122dacb3a4439..66d1708042a72 100644 +--- a/kernel/cgroup/legacy_freezer.c ++++ b/kernel/cgroup/legacy_freezer.c +@@ -66,9 +66,15 @@ static struct freezer *parent_freezer(struct freezer *freezer) + bool cgroup_freezing(struct task_struct *task) + { + bool ret; ++ unsigned int state; + + rcu_read_lock(); +- ret = task_freezer(task)->state & CGROUP_FREEZING; ++ /* Check if the cgroup is still FREEZING, but not FROZEN. The extra ++ * !FROZEN check is required, because the FREEZING bit is not cleared ++ * when the state FROZEN is reached. ++ */ ++ state = task_freezer(task)->state; ++ ret = (state & CGROUP_FREEZING) && !(state & CGROUP_FROZEN); + rcu_read_unlock(); + + return ret; +diff --git a/kernel/cpu.c b/kernel/cpu.c +index 0e4d362e90825..551468d9c5a85 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -1733,7 +1733,7 @@ static struct cpuhp_step cpuhp_hp_states[] = { + [CPUHP_HRTIMERS_PREPARE] = { + .name = "hrtimers:prepare", + .startup.single = hrtimers_prepare_cpu, +- .teardown.single = hrtimers_dead_cpu, ++ .teardown.single = NULL, + }, + [CPUHP_SMPCFD_PREPARE] = { + .name = "smpcfd:prepare", +@@ -1800,6 +1800,12 @@ static struct cpuhp_step cpuhp_hp_states[] = { + .startup.single = NULL, + .teardown.single = smpcfd_dying_cpu, + }, ++ [CPUHP_AP_HRTIMERS_DYING] = { ++ .name = "hrtimers:dying", ++ .startup.single = NULL, ++ .teardown.single = hrtimers_cpu_dying, ++ }, ++ + /* Entry state on starting. Interrupts enabled from here on. Transient + * state for synchronsization */ + [CPUHP_AP_ONLINE] = { +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 8f2b9d8b9150e..0193243f65e5c 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -1812,31 +1812,34 @@ static inline void perf_event__state_init(struct perf_event *event) + PERF_EVENT_STATE_INACTIVE; + } + +-static void __perf_event_read_size(struct perf_event *event, int nr_siblings) ++static int __perf_event_read_size(u64 read_format, int nr_siblings) + { + int entry = sizeof(u64); /* value */ + int size = 0; + int nr = 1; + +- if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) ++ if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + size += sizeof(u64); + +- if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) ++ if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + size += sizeof(u64); + +- if (event->attr.read_format & PERF_FORMAT_ID) ++ if (read_format & PERF_FORMAT_ID) + entry += sizeof(u64); + +- if (event->attr.read_format & PERF_FORMAT_LOST) ++ if (read_format & PERF_FORMAT_LOST) + entry += sizeof(u64); + +- if (event->attr.read_format & PERF_FORMAT_GROUP) { ++ if (read_format & PERF_FORMAT_GROUP) { + nr += nr_siblings; + size += sizeof(u64); + } + +- size += entry * nr; +- event->read_size = size; ++ /* ++ * Since perf_event_validate_size() limits this to 16k and inhibits ++ * adding more siblings, this will never overflow. ++ */ ++ return size + nr * entry; + } + + static void __perf_event_header_size(struct perf_event *event, u64 sample_type) +@@ -1886,8 +1889,9 @@ static void __perf_event_header_size(struct perf_event *event, u64 sample_type) + */ + static void perf_event__header_size(struct perf_event *event) + { +- __perf_event_read_size(event, +- event->group_leader->nr_siblings); ++ event->read_size = ++ __perf_event_read_size(event->attr.read_format, ++ event->group_leader->nr_siblings); + __perf_event_header_size(event, event->attr.sample_type); + } + +@@ -1918,24 +1922,35 @@ static void perf_event__id_header_size(struct perf_event *event) + event->id_header_size = size; + } + ++/* ++ * Check that adding an event to the group does not result in anybody ++ * overflowing the 64k event limit imposed by the output buffer. ++ * ++ * Specifically, check that the read_size for the event does not exceed 16k, ++ * read_size being the one term that grows with groups size. Since read_size ++ * depends on per-event read_format, also (re)check the existing events. ++ * ++ * This leaves 48k for the constant size fields and things like callchains, ++ * branch stacks and register sets. ++ */ + static bool perf_event_validate_size(struct perf_event *event) + { +- /* +- * The values computed here will be over-written when we actually +- * attach the event. +- */ +- __perf_event_read_size(event, event->group_leader->nr_siblings + 1); +- __perf_event_header_size(event, event->attr.sample_type & ~PERF_SAMPLE_READ); +- perf_event__id_header_size(event); ++ struct perf_event *sibling, *group_leader = event->group_leader; + +- /* +- * Sum the lot; should not exceed the 64k limit we have on records. +- * Conservative limit to allow for callchains and other variable fields. +- */ +- if (event->read_size + event->header_size + +- event->id_header_size + sizeof(struct perf_event_header) >= 16*1024) ++ if (__perf_event_read_size(event->attr.read_format, ++ group_leader->nr_siblings + 1) > 16*1024) + return false; + ++ if (__perf_event_read_size(group_leader->attr.read_format, ++ group_leader->nr_siblings + 1) > 16*1024) ++ return false; ++ ++ for_each_sibling_event(sibling, group_leader) { ++ if (__perf_event_read_size(sibling->attr.read_format, ++ group_leader->nr_siblings + 1) > 16*1024) ++ return false; ++ } ++ + return true; + } + +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index 3da9726232ff9..dbfddfa86c14e 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -2253,7 +2253,7 @@ int register_kretprobe(struct kretprobe *rp) + if (!rp->rph) + return -ENOMEM; + +- rp->rph->rp = rp; ++ rcu_assign_pointer(rp->rph->rp, rp); + for (i = 0; i < rp->maxactive; i++) { + inst = kzalloc(sizeof(struct kretprobe_instance) + + rp->data_size, GFP_KERNEL); +@@ -2314,7 +2314,7 @@ void unregister_kretprobes(struct kretprobe **rps, int num) + #ifdef CONFIG_KRETPROBE_ON_RETHOOK + rethook_free(rps[i]->rh); + #else +- rps[i]->rph->rp = NULL; ++ rcu_assign_pointer(rps[i]->rph->rp, NULL); + #endif + } + mutex_unlock(&kprobe_mutex); +diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c +index e4f0e3b0c4f4f..5561dabc9b225 100644 +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -2216,29 +2216,22 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, + } + } + +-int hrtimers_dead_cpu(unsigned int scpu) ++int hrtimers_cpu_dying(unsigned int dying_cpu) + { + struct hrtimer_cpu_base *old_base, *new_base; +- int i; ++ int i, ncpu = cpumask_first(cpu_active_mask); + +- BUG_ON(cpu_online(scpu)); +- tick_cancel_sched_timer(scpu); ++ tick_cancel_sched_timer(dying_cpu); ++ ++ old_base = this_cpu_ptr(&hrtimer_bases); ++ new_base = &per_cpu(hrtimer_bases, ncpu); + +- /* +- * this BH disable ensures that raise_softirq_irqoff() does +- * not wakeup ksoftirqd (and acquire the pi-lock) while +- * holding the cpu_base lock +- */ +- local_bh_disable(); +- local_irq_disable(); +- old_base = &per_cpu(hrtimer_bases, scpu); +- new_base = this_cpu_ptr(&hrtimer_bases); + /* + * The caller is globally serialized and nobody else + * takes two locks at once, deadlock is not possible. + */ +- raw_spin_lock(&new_base->lock); +- raw_spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING); ++ raw_spin_lock(&old_base->lock); ++ raw_spin_lock_nested(&new_base->lock, SINGLE_DEPTH_NESTING); + + for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { + migrate_hrtimer_list(&old_base->clock_base[i], +@@ -2249,15 +2242,13 @@ int hrtimers_dead_cpu(unsigned int scpu) + * The migration might have changed the first expiring softirq + * timer on this CPU. Update it. + */ +- hrtimer_update_softirq_timer(new_base, false); ++ __hrtimer_get_next_event(new_base, HRTIMER_ACTIVE_SOFT); ++ /* Tell the other CPU to retrigger the next event */ ++ smp_call_function_single(ncpu, retrigger_next_event, NULL, 0); + +- raw_spin_unlock(&old_base->lock); + raw_spin_unlock(&new_base->lock); ++ raw_spin_unlock(&old_base->lock); + +- /* Check, if we got expired work to do */ +- __hrtimer_peek_ahead_timers(); +- local_irq_enable(); +- local_bh_enable(); + return 0; + } + +diff --git a/kernel/trace/rethook.c b/kernel/trace/rethook.c +index 468006cce7cae..3686626b52c57 100644 +--- a/kernel/trace/rethook.c ++++ b/kernel/trace/rethook.c +@@ -63,7 +63,7 @@ static void rethook_free_rcu(struct rcu_head *head) + */ + void rethook_stop(struct rethook *rh) + { +- WRITE_ONCE(rh->handler, NULL); ++ rcu_assign_pointer(rh->handler, NULL); + } + + /** +@@ -78,11 +78,17 @@ void rethook_stop(struct rethook *rh) + */ + void rethook_free(struct rethook *rh) + { +- WRITE_ONCE(rh->handler, NULL); ++ rethook_stop(rh); + + call_rcu(&rh->rcu, rethook_free_rcu); + } + ++static inline rethook_handler_t rethook_get_handler(struct rethook *rh) ++{ ++ return (rethook_handler_t)rcu_dereference_check(rh->handler, ++ rcu_read_lock_any_held()); ++} ++ + /** + * rethook_alloc() - Allocate struct rethook. + * @data: a data to pass the @handler when hooking the return. +@@ -102,7 +108,7 @@ struct rethook *rethook_alloc(void *data, rethook_handler_t handler) + } + + rh->data = data; +- rh->handler = handler; ++ rcu_assign_pointer(rh->handler, handler); + rh->pool.head = NULL; + refcount_set(&rh->ref, 1); + +@@ -142,9 +148,10 @@ static void free_rethook_node_rcu(struct rcu_head *head) + */ + void rethook_recycle(struct rethook_node *node) + { +- lockdep_assert_preemption_disabled(); ++ rethook_handler_t handler; + +- if (likely(READ_ONCE(node->rethook->handler))) ++ handler = rethook_get_handler(node->rethook); ++ if (likely(handler)) + freelist_add(&node->freelist, &node->rethook->pool); + else + call_rcu(&node->rcu, free_rethook_node_rcu); +@@ -160,11 +167,9 @@ NOKPROBE_SYMBOL(rethook_recycle); + */ + struct rethook_node *rethook_try_get(struct rethook *rh) + { +- rethook_handler_t handler = READ_ONCE(rh->handler); ++ rethook_handler_t handler = rethook_get_handler(rh); + struct freelist_node *fn; + +- lockdep_assert_preemption_disabled(); +- + /* Check whether @rh is going to be freed. */ + if (unlikely(!handler)) + return NULL; +@@ -312,7 +317,7 @@ unsigned long rethook_trampoline_handler(struct pt_regs *regs, + rhn = container_of(first, struct rethook_node, llist); + if (WARN_ON_ONCE(rhn->frame != frame)) + break; +- handler = READ_ONCE(rhn->rethook->handler); ++ handler = rethook_get_handler(rhn->rethook); + if (handler) + handler(rhn, rhn->rethook->data, regs); + +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index b7383358c4ea1..c02a4cb879913 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -646,8 +646,8 @@ static inline bool __rb_time_read(rb_time_t *t, u64 *ret, unsigned long *cnt) + + *cnt = rb_time_cnt(top); + +- /* If top and bottom counts don't match, this interrupted a write */ +- if (*cnt != rb_time_cnt(bottom)) ++ /* If top and msb counts don't match, this interrupted a write */ ++ if (*cnt != rb_time_cnt(msb)) + return false; + + /* The shift to msb will lose its cnt bits */ +@@ -3025,22 +3025,19 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, + local_read(&bpage->write) & ~RB_WRITE_MASK; + unsigned long event_length = rb_event_length(event); + ++ /* ++ * For the before_stamp to be different than the write_stamp ++ * to make sure that the next event adds an absolute ++ * value and does not rely on the saved write stamp, which ++ * is now going to be bogus. ++ */ ++ rb_time_set(&cpu_buffer->before_stamp, 0); ++ + /* Something came in, can't discard */ + if (!rb_time_cmpxchg(&cpu_buffer->write_stamp, + write_stamp, write_stamp - delta)) + return 0; + +- /* +- * It's possible that the event time delta is zero +- * (has the same time stamp as the previous event) +- * in which case write_stamp and before_stamp could +- * be the same. In such a case, force before_stamp +- * to be different than write_stamp. It doesn't +- * matter what it is, as long as its different. +- */ +- if (!delta) +- rb_time_set(&cpu_buffer->before_stamp, 0); +- + /* + * If an event were to come in now, it would see that the + * write_stamp and the before_stamp are different, and assume +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index ddcfc78e93e00..d2db4d6f0f2fd 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -2297,13 +2297,7 @@ int is_tracing_stopped(void) + return global_trace.stop_count; + } + +-/** +- * tracing_start - quick start of the tracer +- * +- * If tracing is enabled but was stopped by tracing_stop, +- * this will start the tracer back up. +- */ +-void tracing_start(void) ++static void tracing_start_tr(struct trace_array *tr) + { + struct trace_buffer *buffer; + unsigned long flags; +@@ -2311,119 +2305,83 @@ void tracing_start(void) + if (tracing_disabled) + return; + +- raw_spin_lock_irqsave(&global_trace.start_lock, flags); +- if (--global_trace.stop_count) { +- if (global_trace.stop_count < 0) { ++ raw_spin_lock_irqsave(&tr->start_lock, flags); ++ if (--tr->stop_count) { ++ if (WARN_ON_ONCE(tr->stop_count < 0)) { + /* Someone screwed up their debugging */ +- WARN_ON_ONCE(1); +- global_trace.stop_count = 0; ++ tr->stop_count = 0; + } + goto out; + } + + /* Prevent the buffers from switching */ +- arch_spin_lock(&global_trace.max_lock); ++ arch_spin_lock(&tr->max_lock); + +- buffer = global_trace.array_buffer.buffer; ++ buffer = tr->array_buffer.buffer; + if (buffer) + ring_buffer_record_enable(buffer); + + #ifdef CONFIG_TRACER_MAX_TRACE +- buffer = global_trace.max_buffer.buffer; ++ buffer = tr->max_buffer.buffer; + if (buffer) + ring_buffer_record_enable(buffer); + #endif + +- arch_spin_unlock(&global_trace.max_lock); +- +- out: +- raw_spin_unlock_irqrestore(&global_trace.start_lock, flags); +-} +- +-static void tracing_start_tr(struct trace_array *tr) +-{ +- struct trace_buffer *buffer; +- unsigned long flags; +- +- if (tracing_disabled) +- return; +- +- /* If global, we need to also start the max tracer */ +- if (tr->flags & TRACE_ARRAY_FL_GLOBAL) +- return tracing_start(); +- +- raw_spin_lock_irqsave(&tr->start_lock, flags); +- +- if (--tr->stop_count) { +- if (tr->stop_count < 0) { +- /* Someone screwed up their debugging */ +- WARN_ON_ONCE(1); +- tr->stop_count = 0; +- } +- goto out; +- } +- +- buffer = tr->array_buffer.buffer; +- if (buffer) +- ring_buffer_record_enable(buffer); ++ arch_spin_unlock(&tr->max_lock); + + out: + raw_spin_unlock_irqrestore(&tr->start_lock, flags); + } + + /** +- * tracing_stop - quick stop of the tracer ++ * tracing_start - quick start of the tracer + * +- * Light weight way to stop tracing. Use in conjunction with +- * tracing_start. ++ * If tracing is enabled but was stopped by tracing_stop, ++ * this will start the tracer back up. + */ +-void tracing_stop(void) ++void tracing_start(void) ++ ++{ ++ return tracing_start_tr(&global_trace); ++} ++ ++static void tracing_stop_tr(struct trace_array *tr) + { + struct trace_buffer *buffer; + unsigned long flags; + +- raw_spin_lock_irqsave(&global_trace.start_lock, flags); +- if (global_trace.stop_count++) ++ raw_spin_lock_irqsave(&tr->start_lock, flags); ++ if (tr->stop_count++) + goto out; + + /* Prevent the buffers from switching */ +- arch_spin_lock(&global_trace.max_lock); ++ arch_spin_lock(&tr->max_lock); + +- buffer = global_trace.array_buffer.buffer; ++ buffer = tr->array_buffer.buffer; + if (buffer) + ring_buffer_record_disable(buffer); + + #ifdef CONFIG_TRACER_MAX_TRACE +- buffer = global_trace.max_buffer.buffer; ++ buffer = tr->max_buffer.buffer; + if (buffer) + ring_buffer_record_disable(buffer); + #endif + +- arch_spin_unlock(&global_trace.max_lock); ++ arch_spin_unlock(&tr->max_lock); + + out: +- raw_spin_unlock_irqrestore(&global_trace.start_lock, flags); ++ raw_spin_unlock_irqrestore(&tr->start_lock, flags); + } + +-static void tracing_stop_tr(struct trace_array *tr) ++/** ++ * tracing_stop - quick stop of the tracer ++ * ++ * Light weight way to stop tracing. Use in conjunction with ++ * tracing_start. ++ */ ++void tracing_stop(void) + { +- struct trace_buffer *buffer; +- unsigned long flags; +- +- /* If global, we need to also stop the max tracer */ +- if (tr->flags & TRACE_ARRAY_FL_GLOBAL) +- return tracing_stop(); +- +- raw_spin_lock_irqsave(&tr->start_lock, flags); +- if (tr->stop_count++) +- goto out; +- +- buffer = tr->array_buffer.buffer; +- if (buffer) +- ring_buffer_record_disable(buffer); +- +- out: +- raw_spin_unlock_irqrestore(&tr->start_lock, flags); ++ return tracing_stop_tr(&global_trace); + } + + static int trace_save_cmdline(struct task_struct *tsk) +@@ -2707,8 +2665,11 @@ void trace_buffered_event_enable(void) + for_each_tracing_cpu(cpu) { + page = alloc_pages_node(cpu_to_node(cpu), + GFP_KERNEL | __GFP_NORETRY, 0); +- if (!page) +- goto failed; ++ /* This is just an optimization and can handle failures */ ++ if (!page) { ++ pr_err("Failed to allocate event buffer\n"); ++ break; ++ } + + event = page_address(page); + memset(event, 0, sizeof(*event)); +@@ -2722,10 +2683,6 @@ void trace_buffered_event_enable(void) + WARN_ON_ONCE(1); + preempt_enable(); + } +- +- return; +- failed: +- trace_buffered_event_disable(); + } + + static void enable_trace_buffered_event(void *data) +@@ -2760,11 +2717,9 @@ void trace_buffered_event_disable(void) + if (--trace_buffered_event_ref) + return; + +- preempt_disable(); + /* For each CPU, set the buffer as used. */ +- smp_call_function_many(tracing_buffer_mask, +- disable_trace_buffered_event, NULL, 1); +- preempt_enable(); ++ on_each_cpu_mask(tracing_buffer_mask, disable_trace_buffered_event, ++ NULL, true); + + /* Wait for all current users to finish */ + synchronize_rcu(); +@@ -2773,17 +2728,19 @@ void trace_buffered_event_disable(void) + free_page((unsigned long)per_cpu(trace_buffered_event, cpu)); + per_cpu(trace_buffered_event, cpu) = NULL; + } ++ + /* +- * Make sure trace_buffered_event is NULL before clearing +- * trace_buffered_event_cnt. ++ * Wait for all CPUs that potentially started checking if they can use ++ * their event buffer only after the previous synchronize_rcu() call and ++ * they still read a valid pointer from trace_buffered_event. It must be ++ * ensured they don't see cleared trace_buffered_event_cnt else they ++ * could wrongly decide to use the pointed-to buffer which is now freed. + */ +- smp_wmb(); ++ synchronize_rcu(); + +- preempt_disable(); +- /* Do the work on each cpu */ +- smp_call_function_many(tracing_buffer_mask, +- enable_trace_buffered_event, NULL, 1); +- preempt_enable(); ++ /* For each CPU, relinquish the buffer */ ++ on_each_cpu_mask(tracing_buffer_mask, enable_trace_buffered_event, NULL, ++ true); + } + + static struct trace_buffer *temp_buffer; +@@ -6258,6 +6215,15 @@ static void set_buffer_entries(struct array_buffer *buf, unsigned long val) + per_cpu_ptr(buf->data, cpu)->entries = val; + } + ++static void update_buffer_entries(struct array_buffer *buf, int cpu) ++{ ++ if (cpu == RING_BUFFER_ALL_CPUS) { ++ set_buffer_entries(buf, ring_buffer_size(buf->buffer, 0)); ++ } else { ++ per_cpu_ptr(buf->data, cpu)->entries = ring_buffer_size(buf->buffer, cpu); ++ } ++} ++ + #ifdef CONFIG_TRACER_MAX_TRACE + /* resize @tr's buffer to the size of @size_tr's entries */ + static int resize_buffer_duplicate_size(struct array_buffer *trace_buf, +@@ -6302,13 +6268,15 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, + if (!tr->array_buffer.buffer) + return 0; + ++ /* Do not allow tracing while resizng ring buffer */ ++ tracing_stop_tr(tr); ++ + ret = ring_buffer_resize(tr->array_buffer.buffer, size, cpu); + if (ret < 0) +- return ret; ++ goto out_start; + + #ifdef CONFIG_TRACER_MAX_TRACE +- if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL) || +- !tr->current_trace->use_max_tr) ++ if (!tr->current_trace->use_max_tr) + goto out; + + ret = ring_buffer_resize(tr->max_buffer.buffer, size, cpu); +@@ -6333,22 +6301,17 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, + WARN_ON(1); + tracing_disabled = 1; + } +- return ret; ++ goto out_start; + } + +- if (cpu == RING_BUFFER_ALL_CPUS) +- set_buffer_entries(&tr->max_buffer, size); +- else +- per_cpu_ptr(tr->max_buffer.data, cpu)->entries = size; ++ update_buffer_entries(&tr->max_buffer, cpu); + + out: + #endif /* CONFIG_TRACER_MAX_TRACE */ + +- if (cpu == RING_BUFFER_ALL_CPUS) +- set_buffer_entries(&tr->array_buffer, size); +- else +- per_cpu_ptr(tr->array_buffer.data, cpu)->entries = size; +- ++ update_buffer_entries(&tr->array_buffer, cpu); ++ out_start: ++ tracing_start_tr(tr); + return ret; + } + +diff --git a/lib/zstd/common/fse_decompress.c b/lib/zstd/common/fse_decompress.c +index 2c8bbe3e4c148..f37b7aec088ec 100644 +--- a/lib/zstd/common/fse_decompress.c ++++ b/lib/zstd/common/fse_decompress.c +@@ -312,7 +312,7 @@ size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size + + typedef struct { + short ncount[FSE_MAX_SYMBOL_VALUE + 1]; +- FSE_DTable dtable[1]; /* Dynamically sized */ ++ FSE_DTable dtable[]; /* Dynamically sized */ + } FSE_DecompressWksp; + + +diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c +index dbf5e4de97a0f..9ea21b6d266be 100644 +--- a/mm/damon/sysfs.c ++++ b/mm/damon/sysfs.c +@@ -2210,7 +2210,7 @@ static int damon_sysfs_update_target(struct damon_target *target, + struct damon_ctx *ctx, + struct damon_sysfs_target *sys_target) + { +- int err; ++ int err = 0; + + if (damon_target_has_pid(ctx)) { + err = damon_sysfs_update_target_pid(target, sys_target->pid); +diff --git a/mm/filemap.c b/mm/filemap.c +index 2d930470aacaa..d633ab8cd56f1 100644 +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -3319,7 +3319,7 @@ static bool filemap_map_pmd(struct vm_fault *vmf, struct page *page) + } + } + +- if (pmd_none(*vmf->pmd)) ++ if (pmd_none(*vmf->pmd) && vmf->prealloc_pte) + pmd_install(mm, vmf->pmd, &vmf->prealloc_pte); + + /* See comment in handle_pte_fault() */ +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index aa4a68dfb3b92..37288a7f0fa65 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -1189,6 +1189,13 @@ static int is_vma_resv_set(struct vm_area_struct *vma, unsigned long flag) + return (get_vma_private_data(vma) & flag) != 0; + } + ++bool __vma_private_lock(struct vm_area_struct *vma) ++{ ++ return !(vma->vm_flags & VM_MAYSHARE) && ++ get_vma_private_data(vma) & ~HPAGE_RESV_MASK && ++ is_vma_resv_set(vma, HPAGE_RESV_OWNER); ++} ++ + void hugetlb_dup_vma_private(struct vm_area_struct *vma) + { + VM_BUG_ON_VMA(!is_vm_hugetlb_page(vma), vma); +diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c +index f084a4a6b7ab2..8e0a90b45df22 100644 +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -181,7 +181,7 @@ out: + } + + static const struct genl_multicast_group dropmon_mcgrps[] = { +- { .name = "events", }, ++ { .name = "events", .cap_sys_admin = 1 }, + }; + + static void send_dm_alert(struct work_struct *work) +@@ -1604,11 +1604,13 @@ static const struct genl_small_ops dropmon_ops[] = { + .cmd = NET_DM_CMD_START, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = net_dm_cmd_trace, ++ .flags = GENL_ADMIN_PERM, + }, + { + .cmd = NET_DM_CMD_STOP, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = net_dm_cmd_trace, ++ .flags = GENL_ADMIN_PERM, + }, + { + .cmd = NET_DM_CMD_CONFIG_GET, +diff --git a/net/core/filter.c b/net/core/filter.c +index adc327f4af1e9..3a6110ea4009f 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2582,6 +2582,22 @@ BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg *, msg, u32, bytes) + return 0; + } + ++static void sk_msg_reset_curr(struct sk_msg *msg) ++{ ++ u32 i = msg->sg.start; ++ u32 len = 0; ++ ++ do { ++ len += sk_msg_elem(msg, i)->length; ++ sk_msg_iter_var_next(i); ++ if (len >= msg->sg.size) ++ break; ++ } while (i != msg->sg.end); ++ ++ msg->sg.curr = i; ++ msg->sg.copybreak = 0; ++} ++ + static const struct bpf_func_proto bpf_msg_cork_bytes_proto = { + .func = bpf_msg_cork_bytes, + .gpl_only = false, +@@ -2701,6 +2717,7 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_msg *, msg, u32, start, + msg->sg.end - shift + NR_MSG_FRAG_IDS : + msg->sg.end - shift; + out: ++ sk_msg_reset_curr(msg); + msg->data = sg_virt(&msg->sg.data[first_sge]) + start - offset; + msg->data_end = msg->data + bytes; + return 0; +@@ -2837,6 +2854,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start, + msg->sg.data[new] = rsge; + } + ++ sk_msg_reset_curr(msg); + sk_msg_compute_data_pointers(msg); + return 0; + } +@@ -3005,6 +3023,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, + + sk_mem_uncharge(msg->sk, len - pop); + msg->sg.size -= (len - pop); ++ sk_msg_reset_curr(msg); + sk_msg_compute_data_pointers(msg); + return 0; + } +diff --git a/net/core/scm.c b/net/core/scm.c +index acb7d776fa6ec..e762a4b8a1d22 100644 +--- a/net/core/scm.c ++++ b/net/core/scm.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include + +@@ -103,6 +104,11 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) + + if (fd < 0 || !(file = fget_raw(fd))) + return -EBADF; ++ /* don't allow io_uring files */ ++ if (io_uring_get_socket(file)) { ++ fput(file); ++ return -EINVAL; ++ } + *fpp++ = file; + fpl->count++; + } +diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c +index 5b8242265617d..d67d026d7f975 100644 +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -634,15 +634,18 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, + } + + if (dev->header_ops) { ++ int pull_len = tunnel->hlen + sizeof(struct iphdr); ++ + if (skb_cow_head(skb, 0)) + goto free_skb; + + tnl_params = (const struct iphdr *)skb->data; + +- /* Pull skb since ip_tunnel_xmit() needs skb->data pointing +- * to gre header. +- */ +- skb_pull(skb, tunnel->hlen + sizeof(struct iphdr)); ++ if (!pskb_network_may_pull(skb, pull_len)) ++ goto free_skb; ++ ++ /* ip_tunnel_xmit() needs skb->data pointing to gre header. */ ++ skb_pull(skb, pull_len); + skb_reset_mac_header(skb); + + if (skb->ip_summed == CHECKSUM_PARTIAL && +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 288678f17ccaf..58409ea2da0af 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3473,9 +3473,25 @@ int tcp_set_window_clamp(struct sock *sk, int val) + return -EINVAL; + tp->window_clamp = 0; + } else { +- tp->window_clamp = val < SOCK_MIN_RCVBUF / 2 ? +- SOCK_MIN_RCVBUF / 2 : val; +- tp->rcv_ssthresh = min(tp->rcv_wnd, tp->window_clamp); ++ u32 new_rcv_ssthresh, old_window_clamp = tp->window_clamp; ++ u32 new_window_clamp = val < SOCK_MIN_RCVBUF / 2 ? ++ SOCK_MIN_RCVBUF / 2 : val; ++ ++ if (new_window_clamp == old_window_clamp) ++ return 0; ++ ++ tp->window_clamp = new_window_clamp; ++ if (new_window_clamp < old_window_clamp) { ++ /* need to apply the reserved mem provisioning only ++ * when shrinking the window clamp ++ */ ++ __tcp_adjust_rcv_ssthresh(sk, tp->window_clamp); ++ ++ } else { ++ new_rcv_ssthresh = min(tp->rcv_wnd, tp->window_clamp); ++ tp->rcv_ssthresh = max(new_rcv_ssthresh, ++ tp->rcv_ssthresh); ++ } + } + return 0; + } +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 65dae3d43684f..34460c9b37ae2 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -3803,8 +3803,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + * then we can probably ignore it. + */ + if (before(ack, prior_snd_una)) { ++ u32 max_window; ++ ++ /* do not accept ACK for bytes we never sent. */ ++ max_window = min_t(u64, tp->max_window, tp->bytes_acked); + /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */ +- if (before(ack, prior_snd_una - tp->max_window)) { ++ if (before(ack, prior_snd_una - max_window)) { + if (!(flag & FLAG_NO_CHALLENGE_ACK)) + tcp_send_challenge_ack(sk); + return -SKB_DROP_REASON_TCP_TOO_OLD_ACK; +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index eb6640f9a7921..1840735e9cb07 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1502,13 +1502,9 @@ out: + if (!pn_leaf && !(pn->fn_flags & RTN_RTINFO)) { + pn_leaf = fib6_find_prefix(info->nl_net, table, + pn); +-#if RT6_DEBUG >= 2 +- if (!pn_leaf) { +- WARN_ON(!pn_leaf); ++ if (!pn_leaf) + pn_leaf = + info->nl_net->ipv6.fib6_null_entry; +- } +-#endif + fib6_info_hold(pn_leaf); + rcu_assign_pointer(pn->leaf, pn_leaf); + } +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index 20eede37d5228..d47dfdcb899b0 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -61,6 +61,8 @@ MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET); + ip_set_dereference((inst)->ip_set_list)[id] + #define ip_set_ref_netlink(inst,id) \ + rcu_dereference_raw((inst)->ip_set_list)[id] ++#define ip_set_dereference_nfnl(p) \ ++ rcu_dereference_check(p, lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET)) + + /* The set types are implemented in modules and registered set types + * can be found in ip_set_type_list. Adding/deleting types is +@@ -708,15 +710,10 @@ __ip_set_put_netlink(struct ip_set *set) + static struct ip_set * + ip_set_rcu_get(struct net *net, ip_set_id_t index) + { +- struct ip_set *set; + struct ip_set_net *inst = ip_set_pernet(net); + +- rcu_read_lock(); +- /* ip_set_list itself needs to be protected */ +- set = rcu_dereference(inst->ip_set_list)[index]; +- rcu_read_unlock(); +- +- return set; ++ /* ip_set_list and the set pointer need to be protected */ ++ return ip_set_dereference_nfnl(inst->ip_set_list)[index]; + } + + static inline void +@@ -1399,6 +1396,9 @@ static int ip_set_swap(struct sk_buff *skb, const struct nfnl_info *info, + ip_set(inst, to_id) = from; + write_unlock_bh(&ip_set_ref_lock); + ++ /* Make sure all readers of the old set pointers are completed. */ ++ synchronize_rcu(); ++ + return 0; + } + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 421211eba838b..05fa5141af516 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -805,7 +805,7 @@ static struct nft_table *nft_table_lookup(const struct net *net, + + static struct nft_table *nft_table_lookup_byhandle(const struct net *net, + const struct nlattr *nla, +- u8 genmask, u32 nlpid) ++ int family, u8 genmask, u32 nlpid) + { + struct nftables_pernet *nft_net; + struct nft_table *table; +@@ -813,6 +813,7 @@ static struct nft_table *nft_table_lookup_byhandle(const struct net *net, + nft_net = nft_pernet(net); + list_for_each_entry(table, &nft_net->tables, list) { + if (be64_to_cpu(nla_get_be64(nla)) == table->handle && ++ table->family == family && + nft_active_genmask(table, genmask)) { + if (nft_table_has_owner(table) && + nlpid && table->nlpid != nlpid) +@@ -1537,7 +1538,7 @@ static int nf_tables_deltable(struct sk_buff *skb, const struct nfnl_info *info, + + if (nla[NFTA_TABLE_HANDLE]) { + attr = nla[NFTA_TABLE_HANDLE]; +- table = nft_table_lookup_byhandle(net, attr, genmask, ++ table = nft_table_lookup_byhandle(net, attr, family, genmask, + NETLINK_CB(skb).portid); + } else { + attr = nla[NFTA_TABLE_NAME]; +diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c +index cf9a1ae87d9b1..a470e5f612843 100644 +--- a/net/netfilter/nft_dynset.c ++++ b/net/netfilter/nft_dynset.c +@@ -279,10 +279,15 @@ static int nft_dynset_init(const struct nft_ctx *ctx, + priv->expr_array[i] = dynset_expr; + priv->num_exprs++; + +- if (set->num_exprs && +- dynset_expr->ops != set->exprs[i]->ops) { +- err = -EOPNOTSUPP; +- goto err_expr_free; ++ if (set->num_exprs) { ++ if (i >= set->num_exprs) { ++ err = -EINVAL; ++ goto err_expr_free; ++ } ++ if (dynset_expr->ops != set->exprs[i]->ops) { ++ err = -EOPNOTSUPP; ++ goto err_expr_free; ++ } + } + i++; + } +diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c +index efb50c2b41f32..de588f7b69c45 100644 +--- a/net/netfilter/nft_exthdr.c ++++ b/net/netfilter/nft_exthdr.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -214,7 +215,7 @@ static void nft_exthdr_tcp_eval(const struct nft_expr *expr, + + offset = i + priv->offset; + if (priv->flags & NFT_EXTHDR_F_PRESENT) { +- *dest = 1; ++ nft_reg_store8(dest, 1); + } else { + if (priv->len % NFT_REG32_SIZE) + dest[priv->len / NFT_REG32_SIZE] = 0; +@@ -409,6 +410,82 @@ err: + regs->verdict.code = NFT_BREAK; + } + ++static void nft_exthdr_dccp_eval(const struct nft_expr *expr, ++ struct nft_regs *regs, ++ const struct nft_pktinfo *pkt) ++{ ++ struct nft_exthdr *priv = nft_expr_priv(expr); ++ unsigned int thoff, dataoff, optoff, optlen, i; ++ u32 *dest = ®s->data[priv->dreg]; ++ const struct dccp_hdr *dh; ++ struct dccp_hdr _dh; ++ ++ if (pkt->tprot != IPPROTO_DCCP || pkt->fragoff) ++ goto err; ++ ++ thoff = nft_thoff(pkt); ++ ++ dh = skb_header_pointer(pkt->skb, thoff, sizeof(_dh), &_dh); ++ if (!dh) ++ goto err; ++ ++ dataoff = dh->dccph_doff * sizeof(u32); ++ optoff = __dccp_hdr_len(dh); ++ if (dataoff <= optoff) ++ goto err; ++ ++ optlen = dataoff - optoff; ++ ++ for (i = 0; i < optlen; ) { ++ /* Options 0 (DCCPO_PADDING) - 31 (DCCPO_MAX_RESERVED) are 1B in ++ * the length; the remaining options are at least 2B long. In ++ * all cases, the first byte contains the option type. In ++ * multi-byte options, the second byte contains the option ++ * length, which must be at least two: 1 for the type plus 1 for ++ * the length plus 0-253 for any following option data. We ++ * aren't interested in the option data, only the type and the ++ * length, so we don't need to read more than two bytes at a ++ * time. ++ */ ++ unsigned int buflen = optlen - i; ++ u8 buf[2], *bufp; ++ u8 type, len; ++ ++ if (buflen > sizeof(buf)) ++ buflen = sizeof(buf); ++ ++ bufp = skb_header_pointer(pkt->skb, thoff + optoff + i, buflen, ++ &buf); ++ if (!bufp) ++ goto err; ++ ++ type = bufp[0]; ++ ++ if (type == priv->type) { ++ nft_reg_store8(dest, 1); ++ return; ++ } ++ ++ if (type <= DCCPO_MAX_RESERVED) { ++ i++; ++ continue; ++ } ++ ++ if (buflen < 2) ++ goto err; ++ ++ len = bufp[1]; ++ ++ if (len < 2) ++ goto err; ++ ++ i += len; ++ } ++ ++err: ++ *dest = 0; ++} ++ + static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = { + [NFTA_EXTHDR_DREG] = { .type = NLA_U32 }, + [NFTA_EXTHDR_TYPE] = { .type = NLA_U8 }, +@@ -560,6 +637,22 @@ static int nft_exthdr_ipv4_init(const struct nft_ctx *ctx, + return 0; + } + ++static int nft_exthdr_dccp_init(const struct nft_ctx *ctx, ++ const struct nft_expr *expr, ++ const struct nlattr * const tb[]) ++{ ++ struct nft_exthdr *priv = nft_expr_priv(expr); ++ int err = nft_exthdr_init(ctx, expr, tb); ++ ++ if (err < 0) ++ return err; ++ ++ if (!(priv->flags & NFT_EXTHDR_F_PRESENT)) ++ return -EOPNOTSUPP; ++ ++ return 0; ++} ++ + static int nft_exthdr_dump_common(struct sk_buff *skb, const struct nft_exthdr *priv) + { + if (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type)) +@@ -686,6 +779,15 @@ static const struct nft_expr_ops nft_exthdr_sctp_ops = { + .reduce = nft_exthdr_reduce, + }; + ++static const struct nft_expr_ops nft_exthdr_dccp_ops = { ++ .type = &nft_exthdr_type, ++ .size = NFT_EXPR_SIZE(sizeof(struct nft_exthdr)), ++ .eval = nft_exthdr_dccp_eval, ++ .init = nft_exthdr_dccp_init, ++ .dump = nft_exthdr_dump, ++ .reduce = nft_exthdr_reduce, ++}; ++ + static const struct nft_expr_ops * + nft_exthdr_select_ops(const struct nft_ctx *ctx, + const struct nlattr * const tb[]) +@@ -720,6 +822,10 @@ nft_exthdr_select_ops(const struct nft_ctx *ctx, + if (tb[NFTA_EXTHDR_DREG]) + return &nft_exthdr_sctp_ops; + break; ++ case NFT_EXTHDR_OP_DCCP: ++ if (tb[NFTA_EXTHDR_DREG]) ++ return &nft_exthdr_dccp_ops; ++ break; + } + + return ERR_PTR(-EOPNOTSUPP); +diff --git a/net/netfilter/nft_fib.c b/net/netfilter/nft_fib.c +index 1f12d7ade606c..5748415f74d0b 100644 +--- a/net/netfilter/nft_fib.c ++++ b/net/netfilter/nft_fib.c +@@ -144,11 +144,15 @@ void nft_fib_store_result(void *reg, const struct nft_fib *priv, + switch (priv->result) { + case NFT_FIB_RESULT_OIF: + index = dev ? dev->ifindex : 0; +- *dreg = (priv->flags & NFTA_FIB_F_PRESENT) ? !!index : index; ++ if (priv->flags & NFTA_FIB_F_PRESENT) ++ nft_reg_store8(dreg, !!index); ++ else ++ *dreg = index; ++ + break; + case NFT_FIB_RESULT_OIFNAME: + if (priv->flags & NFTA_FIB_F_PRESENT) +- *dreg = !!dev; ++ nft_reg_store8(dreg, !!dev); + else + strncpy(reg, dev ? dev->name : "", IFNAMSIZ); + break; +diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c +index deea6196d9925..4e1cc31729b80 100644 +--- a/net/netfilter/nft_set_pipapo.c ++++ b/net/netfilter/nft_set_pipapo.c +@@ -2042,6 +2042,9 @@ static void nft_pipapo_walk(const struct nft_ctx *ctx, struct nft_set *set, + + e = f->mt[r].e; + ++ if (!nft_set_elem_active(&e->ext, iter->genmask)) ++ goto cont; ++ + elem.priv = e; + + iter->err = iter->fn(ctx, set, iter, &elem); +diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c +index e85ce69924aee..50332888c8d23 100644 +--- a/net/netfilter/xt_owner.c ++++ b/net/netfilter/xt_owner.c +@@ -76,18 +76,23 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) + */ + return false; + +- filp = sk->sk_socket->file; +- if (filp == NULL) ++ read_lock_bh(&sk->sk_callback_lock); ++ filp = sk->sk_socket ? sk->sk_socket->file : NULL; ++ if (filp == NULL) { ++ read_unlock_bh(&sk->sk_callback_lock); + return ((info->match ^ info->invert) & + (XT_OWNER_UID | XT_OWNER_GID)) == 0; ++ } + + if (info->match & XT_OWNER_UID) { + kuid_t uid_min = make_kuid(net->user_ns, info->uid_min); + kuid_t uid_max = make_kuid(net->user_ns, info->uid_max); + if ((uid_gte(filp->f_cred->fsuid, uid_min) && + uid_lte(filp->f_cred->fsuid, uid_max)) ^ +- !(info->invert & XT_OWNER_UID)) ++ !(info->invert & XT_OWNER_UID)) { ++ read_unlock_bh(&sk->sk_callback_lock); + return false; ++ } + } + + if (info->match & XT_OWNER_GID) { +@@ -112,10 +117,13 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) + } + } + +- if (match ^ !(info->invert & XT_OWNER_GID)) ++ if (match ^ !(info->invert & XT_OWNER_GID)) { ++ read_unlock_bh(&sk->sk_callback_lock); + return false; ++ } + } + ++ read_unlock_bh(&sk->sk_callback_lock); + return true; + } + +diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c +index 3e16527beb914..505d3b910cc29 100644 +--- a/net/netlink/genetlink.c ++++ b/net/netlink/genetlink.c +@@ -1438,6 +1438,9 @@ static int genl_bind(struct net *net, int group) + if ((grp->flags & GENL_UNS_ADMIN_PERM) && + !ns_capable(net->user_ns, CAP_NET_ADMIN)) + ret = -EPERM; ++ if (grp->cap_sys_admin && ++ !ns_capable(net->user_ns, CAP_SYS_ADMIN)) ++ ret = -EPERM; + + break; + } +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 451bd8bfafd23..51882f07ef70c 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -4275,7 +4275,7 @@ static void packet_mm_open(struct vm_area_struct *vma) + struct sock *sk = sock->sk; + + if (sk) +- atomic_inc(&pkt_sk(sk)->mapped); ++ atomic_long_inc(&pkt_sk(sk)->mapped); + } + + static void packet_mm_close(struct vm_area_struct *vma) +@@ -4285,7 +4285,7 @@ static void packet_mm_close(struct vm_area_struct *vma) + struct sock *sk = sock->sk; + + if (sk) +- atomic_dec(&pkt_sk(sk)->mapped); ++ atomic_long_dec(&pkt_sk(sk)->mapped); + } + + static const struct vm_operations_struct packet_mmap_ops = { +@@ -4380,7 +4380,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + + err = -EBUSY; + if (!closing) { +- if (atomic_read(&po->mapped)) ++ if (atomic_long_read(&po->mapped)) + goto out; + if (packet_read_pending(rb)) + goto out; +@@ -4483,7 +4483,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + + err = -EBUSY; + mutex_lock(&po->pg_vec_lock); +- if (closing || atomic_read(&po->mapped) == 0) { ++ if (closing || atomic_long_read(&po->mapped) == 0) { + err = 0; + spin_lock_bh(&rb_queue->lock); + swap(rb->pg_vec, pg_vec); +@@ -4501,9 +4501,9 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + po->prot_hook.func = (po->rx_ring.pg_vec) ? + tpacket_rcv : packet_rcv; + skb_queue_purge(rb_queue); +- if (atomic_read(&po->mapped)) +- pr_err("packet_mmap: vma is busy: %d\n", +- atomic_read(&po->mapped)); ++ if (atomic_long_read(&po->mapped)) ++ pr_err("packet_mmap: vma is busy: %ld\n", ++ atomic_long_read(&po->mapped)); + } + mutex_unlock(&po->pg_vec_lock); + +@@ -4581,7 +4581,7 @@ static int packet_mmap(struct file *file, struct socket *sock, + } + } + +- atomic_inc(&po->mapped); ++ atomic_long_inc(&po->mapped); + vma->vm_ops = &packet_mmap_ops; + err = 0; + +diff --git a/net/packet/internal.h b/net/packet/internal.h +index 3bae8ea7a36f5..b2edfe6fc8e77 100644 +--- a/net/packet/internal.h ++++ b/net/packet/internal.h +@@ -126,7 +126,7 @@ struct packet_sock { + __be16 num; + struct packet_rollover *rollover; + struct packet_mclist *mclist; +- atomic_t mapped; ++ atomic_long_t mapped; + enum tpacket_versions tp_version; + unsigned int tp_hdrlen; + unsigned int tp_reserve; +diff --git a/net/psample/psample.c b/net/psample/psample.c +index 81a794e36f535..c34e902855dbe 100644 +--- a/net/psample/psample.c ++++ b/net/psample/psample.c +@@ -31,7 +31,8 @@ enum psample_nl_multicast_groups { + + static const struct genl_multicast_group psample_nl_mcgrps[] = { + [PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME }, +- [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME }, ++ [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME, ++ .flags = GENL_UNS_ADMIN_PERM }, + }; + + static struct genl_family psample_nl_family __ro_after_init; +diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c +index f7592638e61d3..5c8e02d56fd43 100644 +--- a/net/xdp/xsk.c ++++ b/net/xdp/xsk.c +@@ -722,7 +722,7 @@ static __poll_t xsk_poll(struct file *file, struct socket *sock, + + rcu_read_lock(); + if (xsk_check_common(xs)) +- goto skip_tx; ++ goto out; + + pool = xs->pool; + +@@ -734,12 +734,11 @@ static __poll_t xsk_poll(struct file *file, struct socket *sock, + xsk_generic_xmit(sk); + } + +-skip_tx: + if (xs->rx && !xskq_prod_is_empty(xs->rx)) + mask |= EPOLLIN | EPOLLRDNORM; + if (xs->tx && xsk_tx_writeable(xs)) + mask |= EPOLLOUT | EPOLLWRNORM; +- ++out: + rcu_read_unlock(); + return mask; + } +diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl +index d48dfed6d3dba..a0f9101d5fd44 100755 +--- a/scripts/checkstack.pl ++++ b/scripts/checkstack.pl +@@ -146,15 +146,11 @@ $total_size = 0; + while (my $line = ) { + if ($line =~ m/$funcre/) { + $func = $1; +- next if $line !~ m/^($xs*)/; ++ next if $line !~ m/^($x*)/; + if ($total_size > $min_stack) { + push @stack, "$intro$total_size\n"; + } +- +- $addr = $1; +- $addr =~ s/ /0/g; +- $addr = "0x$addr"; +- ++ $addr = "0x$1"; + $intro = "$addr $func [$file]:"; + my $padlen = 56 - length($intro); + while ($padlen > 0) { +diff --git a/scripts/dtc/dt-extract-compatibles b/scripts/dtc/dt-extract-compatibles +index a1119762ed086..9686a1cf85498 100755 +--- a/scripts/dtc/dt-extract-compatibles ++++ b/scripts/dtc/dt-extract-compatibles +@@ -1,8 +1,8 @@ + #!/usr/bin/env python3 + # SPDX-License-Identifier: GPL-2.0-only + ++import fnmatch + import os +-import glob + import re + import argparse + +@@ -49,6 +49,24 @@ def print_compat(filename, compatibles): + else: + print(*compatibles, sep='\n') + ++def glob_without_symlinks(root, glob): ++ for path, dirs, files in os.walk(root): ++ # Ignore hidden directories ++ for d in dirs: ++ if fnmatch.fnmatch(d, ".*"): ++ dirs.remove(d) ++ for f in files: ++ if fnmatch.fnmatch(f, glob): ++ yield os.path.join(path, f) ++ ++def files_to_parse(path_args): ++ for f in path_args: ++ if os.path.isdir(f): ++ for filename in glob_without_symlinks(f, "*.c"): ++ yield filename ++ else: ++ yield f ++ + show_filename = False + + if __name__ == "__main__": +@@ -59,11 +77,6 @@ if __name__ == "__main__": + + show_filename = args.with_filename + +- for f in args.cfile: +- if os.path.isdir(f): +- for filename in glob.iglob(f + "/**/*.c", recursive=True): +- compat_list = parse_compatibles(filename) +- print_compat(filename, compat_list) +- else: +- compat_list = parse_compatibles(f) +- print_compat(f, compat_list) ++ for f in files_to_parse(args.cfile): ++ compat_list = parse_compatibles(f) ++ print_compat(f, compat_list) +diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c +index 0572330bf8a78..a76925b46ce63 100644 +--- a/scripts/kconfig/symbol.c ++++ b/scripts/kconfig/symbol.c +@@ -122,9 +122,9 @@ static long long sym_get_range_val(struct symbol *sym, int base) + static void sym_validate_range(struct symbol *sym) + { + struct property *prop; ++ struct symbol *range_sym; + int base; + long long val, val2; +- char str[64]; + + switch (sym->type) { + case S_INT: +@@ -140,17 +140,15 @@ static void sym_validate_range(struct symbol *sym) + if (!prop) + return; + val = strtoll(sym->curr.val, NULL, base); +- val2 = sym_get_range_val(prop->expr->left.sym, base); ++ range_sym = prop->expr->left.sym; ++ val2 = sym_get_range_val(range_sym, base); + if (val >= val2) { +- val2 = sym_get_range_val(prop->expr->right.sym, base); ++ range_sym = prop->expr->right.sym; ++ val2 = sym_get_range_val(range_sym, base); + if (val <= val2) + return; + } +- if (sym->type == S_INT) +- sprintf(str, "%lld", val2); +- else +- sprintf(str, "0x%llx", val2); +- sym->curr.val = xstrdup(str); ++ sym->curr.val = range_sym->curr.val; + } + + static void sym_set_changed(struct symbol *sym) +diff --git a/sound/core/pcm.c b/sound/core/pcm.c +index 9d95e37311230..2415a3c3ac6c9 100644 +--- a/sound/core/pcm.c ++++ b/sound/core/pcm.c +@@ -253,6 +253,7 @@ static const char * const snd_pcm_state_names[] = { + STATE(DRAINING), + STATE(PAUSED), + STATE(SUSPENDED), ++ STATE(DISCONNECTED), + }; + + static const char * const snd_pcm_access_names[] = { +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index d1944c83b03a2..c6cae3369a6a1 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10031,6 +10031,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10), + SND_PCI_QUIRK(0x8086, 0x3038, "Intel NUC 13", ALC295_FIXUP_CHROME_BOOK), + SND_PCI_QUIRK(0xf111, 0x0001, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0xf111, 0x0005, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0xf111, 0x0006, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), + + #if 0 + /* Below is a quirk table taken from the old code. +@@ -11952,6 +11954,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN), + SND_PCI_QUIRK(0x17aa, 0x3321, "Lenovo ThinkCentre M70 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN), + SND_PCI_QUIRK(0x17aa, 0x331b, "Lenovo ThinkCentre M90 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN), ++ SND_PCI_QUIRK(0x17aa, 0x3364, "Lenovo ThinkCentre M90 Gen5", ALC897_FIXUP_HEADSET_MIC_PIN), + SND_PCI_QUIRK(0x17aa, 0x3742, "Lenovo TianYi510Pro-14IOB", ALC897_FIXUP_HEADSET_MIC_PIN2), + SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), + SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), +diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c +index c494de5f5c066..1dde1f3196acc 100644 +--- a/sound/soc/amd/yc/acp6x-mach.c ++++ b/sound/soc/amd/yc/acp6x-mach.c +@@ -283,6 +283,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"), + } + }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "E1504FA"), ++ } ++ }, + { + .driver_data = &acp6x_card, + .matches = { +diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c +index 9f59518005a5f..840bbe991cd3a 100644 +--- a/sound/soc/codecs/lpass-tx-macro.c ++++ b/sound/soc/codecs/lpass-tx-macro.c +@@ -1871,6 +1871,11 @@ static int tx_macro_probe(struct platform_device *pdev) + + tx->dev = dev; + ++ /* Set active_decimator default value */ ++ tx->active_decimator[TX_MACRO_AIF1_CAP] = -1; ++ tx->active_decimator[TX_MACRO_AIF2_CAP] = -1; ++ tx->active_decimator[TX_MACRO_AIF3_CAP] = -1; ++ + /* set MCLK and NPL rates */ + clk_set_rate(tx->mclk, MCLK_FREQ); + clk_set_rate(tx->npl, MCLK_FREQ); +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 8a2e9771bb50e..2cfca78f0401f 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -1401,12 +1401,12 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) + ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset, + ®ion->base_addr); + if (ret < 0) +- return ret; ++ goto err; + + ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset, + &offset); + if (ret < 0) +- return ret; ++ goto err; + + region->cumulative_size = offset; + +@@ -1417,6 +1417,10 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) + } + + return 0; ++ ++err: ++ kfree(buf->regions); ++ return ret; + } + + static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf) +diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c +index 96fd9095e544b..6364d9be28fbb 100644 +--- a/sound/soc/fsl/fsl_sai.c ++++ b/sound/soc/fsl/fsl_sai.c +@@ -674,6 +674,20 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, + FSL_SAI_CR3_TRCE_MASK, + FSL_SAI_CR3_TRCE((dl_cfg[dl_cfg_idx].mask[tx] & trce_mask))); + ++ /* ++ * When the TERE and FSD_MSTR enabled before configuring the word width ++ * There will be no frame sync clock issue, because word width impact ++ * the generation of frame sync clock. ++ * ++ * TERE enabled earlier only for i.MX8MP case for the hardware limitation, ++ * We need to disable FSD_MSTR before configuring word width, then enable ++ * FSD_MSTR bit for this specific case. ++ */ ++ if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output && ++ !sai->is_consumer_mode) ++ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), ++ FSL_SAI_CR4_FSD_MSTR, 0); ++ + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), + FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | + FSL_SAI_CR4_CHMOD_MASK, +@@ -681,6 +695,13 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, + regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs), + FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | + FSL_SAI_CR5_FBT_MASK, val_cr5); ++ ++ /* Enable FSD_MSTR after configuring word width */ ++ if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output && ++ !sai->is_consumer_mode) ++ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), ++ FSL_SAI_CR4_FSD_MSTR, FSL_SAI_CR4_FSD_MSTR); ++ + regmap_write(sai->regmap, FSL_SAI_xMR(tx), + ~0UL - ((1 << min(channels, slots)) - 1)); + +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index ab0d459f42715..1f32e3ae3aa31 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -2978,6 +2978,7 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer) + #define SND_DJM_850_IDX 0x2 + #define SND_DJM_900NXS2_IDX 0x3 + #define SND_DJM_750MK2_IDX 0x4 ++#define SND_DJM_450_IDX 0x5 + + + #define SND_DJM_CTL(_name, suffix, _default_value, _windex) { \ +@@ -3108,6 +3109,31 @@ static const struct snd_djm_ctl snd_djm_ctls_250mk2[] = { + }; + + ++// DJM-450 ++static const u16 snd_djm_opts_450_cap1[] = { ++ 0x0103, 0x0100, 0x0106, 0x0107, 0x0108, 0x0109, 0x010d, 0x010a }; ++ ++static const u16 snd_djm_opts_450_cap2[] = { ++ 0x0203, 0x0200, 0x0206, 0x0207, 0x0208, 0x0209, 0x020d, 0x020a }; ++ ++static const u16 snd_djm_opts_450_cap3[] = { ++ 0x030a, 0x0311, 0x0312, 0x0307, 0x0308, 0x0309, 0x030d }; ++ ++static const u16 snd_djm_opts_450_pb1[] = { 0x0100, 0x0101, 0x0104 }; ++static const u16 snd_djm_opts_450_pb2[] = { 0x0200, 0x0201, 0x0204 }; ++static const u16 snd_djm_opts_450_pb3[] = { 0x0300, 0x0301, 0x0304 }; ++ ++static const struct snd_djm_ctl snd_djm_ctls_450[] = { ++ SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL), ++ SND_DJM_CTL("Ch1 Input", 450_cap1, 2, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch2 Input", 450_cap2, 2, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch3 Input", 450_cap3, 0, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch1 Output", 450_pb1, 0, SND_DJM_WINDEX_PB), ++ SND_DJM_CTL("Ch2 Output", 450_pb2, 1, SND_DJM_WINDEX_PB), ++ SND_DJM_CTL("Ch3 Output", 450_pb3, 2, SND_DJM_WINDEX_PB) ++}; ++ ++ + // DJM-750 + static const u16 snd_djm_opts_750_cap1[] = { + 0x0101, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a, 0x010f }; +@@ -3203,6 +3229,7 @@ static const struct snd_djm_device snd_djm_devices[] = { + [SND_DJM_850_IDX] = SND_DJM_DEVICE(850), + [SND_DJM_900NXS2_IDX] = SND_DJM_DEVICE(900nxs2), + [SND_DJM_750MK2_IDX] = SND_DJM_DEVICE(750mk2), ++ [SND_DJM_450_IDX] = SND_DJM_DEVICE(450), + }; + + +@@ -3449,6 +3476,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) + case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */ + err = snd_djm_controls_create(mixer, SND_DJM_250MK2_IDX); + break; ++ case USB_ID(0x2b73, 0x0013): /* Pioneer DJ DJM-450 */ ++ err = snd_djm_controls_create(mixer, SND_DJM_450_IDX); ++ break; + case USB_ID(0x08e4, 0x017f): /* Pioneer DJ DJM-750 */ + err = snd_djm_controls_create(mixer, SND_DJM_750_IDX); + break; diff --git a/patch/kernel/odroidxu4-current/patch-6.1.68-69.patch b/patch/kernel/odroidxu4-current/patch-6.1.68-69.patch new file mode 100644 index 0000000000..fd8d28e168 --- /dev/null +++ b/patch/kernel/odroidxu4-current/patch-6.1.68-69.patch @@ -0,0 +1,4110 @@ +diff --git a/Makefile b/Makefile +index 2a8ad0cec2f1c..9a3b34d2387fa 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 1 +-SUBLEVEL = 68 ++SUBLEVEL = 69 + EXTRAVERSION = + NAME = Curry Ramen + +diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile +index 5e56d26a22398..c9496539c3351 100644 +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -157,7 +157,7 @@ endif + + all: $(notdir $(KBUILD_IMAGE)) + +- ++vmlinuz.efi: Image + Image vmlinuz.efi: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + +diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h +index 5d0f1f7b76004..56c7df4c65325 100644 +--- a/arch/arm64/include/asm/pgtable.h ++++ b/arch/arm64/include/asm/pgtable.h +@@ -822,6 +822,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) + if (pte_hw_dirty(pte)) + pte = pte_mkdirty(pte); + pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); ++ /* ++ * If we end up clearing hw dirtiness for a sw-dirty PTE, set hardware ++ * dirtiness again. ++ */ ++ if (pte_sw_dirty(pte)) ++ pte = pte_mkdirty(pte); + return pte; + } + +diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile +index 01b57b7263225..ed47a3a87768e 100644 +--- a/arch/loongarch/Makefile ++++ b/arch/loongarch/Makefile +@@ -116,6 +116,8 @@ vdso_install: + + all: $(notdir $(KBUILD_IMAGE)) + ++vmlinuz.efi: vmlinux.efi ++ + vmlinux.elf vmlinux.efi vmlinuz.efi: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $(boot)/$@ + +diff --git a/arch/loongarch/kernel/time.c b/arch/loongarch/kernel/time.c +index d2b7d5df132a9..150df6e17bb6a 100644 +--- a/arch/loongarch/kernel/time.c ++++ b/arch/loongarch/kernel/time.c +@@ -58,14 +58,16 @@ static int constant_set_state_oneshot(struct clock_event_device *evt) + return 0; + } + +-static int constant_set_state_oneshot_stopped(struct clock_event_device *evt) ++static int constant_set_state_periodic(struct clock_event_device *evt) + { ++ unsigned long period; + unsigned long timer_config; + + raw_spin_lock(&state_lock); + +- timer_config = csr_read64(LOONGARCH_CSR_TCFG); +- timer_config &= ~CSR_TCFG_EN; ++ period = const_clock_freq / HZ; ++ timer_config = period & CSR_TCFG_VAL; ++ timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN); + csr_write64(timer_config, LOONGARCH_CSR_TCFG); + + raw_spin_unlock(&state_lock); +@@ -73,16 +75,14 @@ static int constant_set_state_oneshot_stopped(struct clock_event_device *evt) + return 0; + } + +-static int constant_set_state_periodic(struct clock_event_device *evt) ++static int constant_set_state_shutdown(struct clock_event_device *evt) + { +- unsigned long period; + unsigned long timer_config; + + raw_spin_lock(&state_lock); + +- period = const_clock_freq / HZ; +- timer_config = period & CSR_TCFG_VAL; +- timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN); ++ timer_config = csr_read64(LOONGARCH_CSR_TCFG); ++ timer_config &= ~CSR_TCFG_EN; + csr_write64(timer_config, LOONGARCH_CSR_TCFG); + + raw_spin_unlock(&state_lock); +@@ -90,11 +90,6 @@ static int constant_set_state_periodic(struct clock_event_device *evt) + return 0; + } + +-static int constant_set_state_shutdown(struct clock_event_device *evt) +-{ +- return 0; +-} +- + static int constant_timer_next_event(unsigned long delta, struct clock_event_device *evt) + { + unsigned long timer_config; +@@ -156,7 +151,7 @@ int constant_clockevent_init(void) + cd->rating = 320; + cd->cpumask = cpumask_of(cpu); + cd->set_state_oneshot = constant_set_state_oneshot; +- cd->set_state_oneshot_stopped = constant_set_state_oneshot_stopped; ++ cd->set_state_oneshot_stopped = constant_set_state_shutdown; + cd->set_state_periodic = constant_set_state_periodic; + cd->set_state_shutdown = constant_set_state_shutdown; + cd->set_next_event = constant_timer_next_event; +diff --git a/arch/powerpc/kernel/trace/ftrace_mprofile.S b/arch/powerpc/kernel/trace/ftrace_mprofile.S +index 6f9c2dea905b7..f4a72b38488f7 100644 +--- a/arch/powerpc/kernel/trace/ftrace_mprofile.S ++++ b/arch/powerpc/kernel/trace/ftrace_mprofile.S +@@ -62,7 +62,7 @@ + .endif + + /* Save previous stack pointer (r1) */ +- addi r8, r1, SWITCH_FRAME_SIZE ++ addi r8, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE + PPC_STL r8, GPR1(r1) + + .if \allregs == 1 +@@ -182,7 +182,7 @@ ftrace_no_trace: + mflr r3 + mtctr r3 + REST_GPR(3, r1) +- addi r1, r1, SWITCH_FRAME_SIZE ++ addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE + mtlr r0 + bctr + #endif +diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c +index 5fd72d4b8bbb0..7d454141433c8 100644 +--- a/arch/x86/events/intel/uncore_discovery.c ++++ b/arch/x86/events/intel/uncore_discovery.c +@@ -140,13 +140,21 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit, + unsigned int *box_offset, *ids; + int i; + +- if (WARN_ON_ONCE(!unit->ctl || !unit->ctl_offset || !unit->ctr_offset)) ++ if (!unit->ctl || !unit->ctl_offset || !unit->ctr_offset) { ++ pr_info("Invalid address is detected for uncore type %d box %d, " ++ "Disable the uncore unit.\n", ++ unit->box_type, unit->box_id); + return; ++ } + + if (parsed) { + type = search_uncore_discovery_type(unit->box_type); +- if (WARN_ON_ONCE(!type)) ++ if (!type) { ++ pr_info("A spurious uncore type %d is detected, " ++ "Disable the uncore type.\n", ++ unit->box_type); + return; ++ } + /* Store the first box of each die */ + if (!type->box_ctrl_die[die]) + type->box_ctrl_die[die] = unit->ctl; +@@ -181,8 +189,12 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit, + ids[i] = type->ids[i]; + box_offset[i] = type->box_offset[i]; + +- if (WARN_ON_ONCE(unit->box_id == ids[i])) ++ if (unit->box_id == ids[i]) { ++ pr_info("Duplicate uncore type %d box ID %d is detected, " ++ "Drop the duplicate uncore unit.\n", ++ unit->box_type, unit->box_id); + goto free_ids; ++ } + } + ids[i] = unit->box_id; + box_offset[i] = unit->ctl - type->box_ctrl; +diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c +index 189ae92de4d06..c18e5c764643b 100644 +--- a/arch/x86/hyperv/hv_init.c ++++ b/arch/x86/hyperv/hv_init.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -267,15 +268,31 @@ static int hv_cpu_die(unsigned int cpu) + + static int __init hv_pci_init(void) + { +- int gen2vm = efi_enabled(EFI_BOOT); ++ bool gen2vm = efi_enabled(EFI_BOOT); + + /* +- * For Generation-2 VM, we exit from pci_arch_init() by returning 0. +- * The purpose is to suppress the harmless warning: ++ * A Generation-2 VM doesn't support legacy PCI/PCIe, so both ++ * raw_pci_ops and raw_pci_ext_ops are NULL, and pci_subsys_init() -> ++ * pcibios_init() doesn't call pcibios_resource_survey() -> ++ * e820__reserve_resources_late(); as a result, any emulated persistent ++ * memory of E820_TYPE_PRAM (12) via the kernel parameter ++ * memmap=nn[KMG]!ss is not added into iomem_resource and hence can't be ++ * detected by register_e820_pmem(). Fix this by directly calling ++ * e820__reserve_resources_late() here: e820__reserve_resources_late() ++ * depends on e820__reserve_resources(), which has been called earlier ++ * from setup_arch(). Note: e820__reserve_resources_late() also adds ++ * any memory of E820_TYPE_PMEM (7) into iomem_resource, and ++ * acpi_nfit_register_region() -> acpi_nfit_insert_resource() -> ++ * region_intersects() returns REGION_INTERSECTS, so the memory of ++ * E820_TYPE_PMEM won't get added twice. ++ * ++ * We return 0 here so that pci_arch_init() won't print the warning: + * "PCI: Fatal: No config space access function found" + */ +- if (gen2vm) ++ if (gen2vm) { ++ e820__reserve_resources_late(); + return 0; ++ } + + /* For Generation-1 VM, we'll proceed in pci_arch_init(). */ + return 1; +diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c +index 60f366f98fa2b..1b7fd1fc2f337 100644 +--- a/block/blk-cgroup.c ++++ b/block/blk-cgroup.c +@@ -462,6 +462,7 @@ static void blkg_destroy_all(struct gendisk *disk) + struct request_queue *q = disk->queue; + struct blkcg_gq *blkg, *n; + int count = BLKG_DESTROY_BATCH_SIZE; ++ int i; + + restart: + spin_lock_irq(&q->queue_lock); +@@ -487,6 +488,18 @@ restart: + } + } + ++ /* ++ * Mark policy deactivated since policy offline has been done, and ++ * the free is scheduled, so future blkcg_deactivate_policy() can ++ * be bypassed ++ */ ++ for (i = 0; i < BLKCG_MAX_POLS; i++) { ++ struct blkcg_policy *pol = blkcg_policy[i]; ++ ++ if (pol) ++ __clear_bit(pol->plid, q->blkcg_pols); ++ } ++ + q->root_blkg = NULL; + spin_unlock_irq(&q->queue_lock); + } +diff --git a/block/blk-throttle.c b/block/blk-throttle.c +index 009b0d76bf036..62a3f62316df1 100644 +--- a/block/blk-throttle.c ++++ b/block/blk-throttle.c +@@ -1333,6 +1333,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global) + tg_bps_limit(tg, READ), tg_bps_limit(tg, WRITE), + tg_iops_limit(tg, READ), tg_iops_limit(tg, WRITE)); + ++ rcu_read_lock(); + /* + * Update has_rules[] flags for the updated tg's subtree. A tg is + * considered to have rules if either the tg itself or any of its +@@ -1360,6 +1361,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global) + this_tg->latency_target = max(this_tg->latency_target, + parent_tg->latency_target); + } ++ rcu_read_unlock(); + + /* + * We're already holding queue_lock and know @tg is valid. Let's +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index 94fbc3abe60e6..d3c30a28c410e 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -449,9 +449,9 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, + struct sk_buff *skb; + unsigned int len; + +- spin_lock(&card->cli_queue_lock); ++ spin_lock_bh(&card->cli_queue_lock); + skb = skb_dequeue(&card->cli_queue[SOLOS_CHAN(atmdev)]); +- spin_unlock(&card->cli_queue_lock); ++ spin_unlock_bh(&card->cli_queue_lock); + if(skb == NULL) + return sprintf(buf, "No data.\n"); + +@@ -956,14 +956,14 @@ static void pclose(struct atm_vcc *vcc) + struct pkt_hdr *header; + + /* Remove any yet-to-be-transmitted packets from the pending queue */ +- spin_lock(&card->tx_queue_lock); ++ spin_lock_bh(&card->tx_queue_lock); + skb_queue_walk_safe(&card->tx_queue[port], skb, tmpskb) { + if (SKB_CB(skb)->vcc == vcc) { + skb_unlink(skb, &card->tx_queue[port]); + solos_pop(vcc, skb); + } + } +- spin_unlock(&card->tx_queue_lock); ++ spin_unlock_bh(&card->tx_queue_lock); + + skb = alloc_skb(sizeof(*header), GFP_KERNEL); + if (!skb) { +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index e94d2ff6b1223..8037aaefeb2ed 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -67,6 +67,7 @@ struct nbd_sock { + struct recv_thread_args { + struct work_struct work; + struct nbd_device *nbd; ++ struct nbd_sock *nsock; + int index; + }; + +@@ -489,15 +490,9 @@ done: + return BLK_EH_DONE; + } + +-/* +- * Send or receive packet. Return a positive value on success and +- * negtive value on failue, and never return 0. +- */ +-static int sock_xmit(struct nbd_device *nbd, int index, int send, +- struct iov_iter *iter, int msg_flags, int *sent) ++static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, ++ struct iov_iter *iter, int msg_flags, int *sent) + { +- struct nbd_config *config = nbd->config; +- struct socket *sock = config->socks[index]->sock; + int result; + struct msghdr msg; + unsigned int noreclaim_flag; +@@ -539,6 +534,19 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send, + return result; + } + ++/* ++ * Send or receive packet. Return a positive value on success and ++ * negtive value on failure, and never return 0. ++ */ ++static int sock_xmit(struct nbd_device *nbd, int index, int send, ++ struct iov_iter *iter, int msg_flags, int *sent) ++{ ++ struct nbd_config *config = nbd->config; ++ struct socket *sock = config->socks[index]->sock; ++ ++ return __sock_xmit(nbd, sock, send, iter, msg_flags, sent); ++} ++ + /* + * Different settings for sk->sk_sndtimeo can result in different return values + * if there is a signal pending when we enter sendmsg, because reasons? +@@ -695,7 +703,7 @@ out: + return 0; + } + +-static int nbd_read_reply(struct nbd_device *nbd, int index, ++static int nbd_read_reply(struct nbd_device *nbd, struct socket *sock, + struct nbd_reply *reply) + { + struct kvec iov = {.iov_base = reply, .iov_len = sizeof(*reply)}; +@@ -704,7 +712,7 @@ static int nbd_read_reply(struct nbd_device *nbd, int index, + + reply->magic = 0; + iov_iter_kvec(&to, ITER_DEST, &iov, 1, sizeof(*reply)); +- result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); ++ result = __sock_xmit(nbd, sock, 0, &to, MSG_WAITALL, NULL); + if (result < 0) { + if (!nbd_disconnected(nbd->config)) + dev_err(disk_to_dev(nbd->disk), +@@ -828,14 +836,14 @@ static void recv_work(struct work_struct *work) + struct nbd_device *nbd = args->nbd; + struct nbd_config *config = nbd->config; + struct request_queue *q = nbd->disk->queue; +- struct nbd_sock *nsock; ++ struct nbd_sock *nsock = args->nsock; + struct nbd_cmd *cmd; + struct request *rq; + + while (1) { + struct nbd_reply reply; + +- if (nbd_read_reply(nbd, args->index, &reply)) ++ if (nbd_read_reply(nbd, nsock->sock, &reply)) + break; + + /* +@@ -870,7 +878,6 @@ static void recv_work(struct work_struct *work) + percpu_ref_put(&q->q_usage_counter); + } + +- nsock = config->socks[args->index]; + mutex_lock(&nsock->tx_lock); + nbd_mark_nsock_dead(nbd, nsock, 1); + mutex_unlock(&nsock->tx_lock); +@@ -1214,6 +1221,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg) + INIT_WORK(&args->work, recv_work); + args->index = i; + args->nbd = nbd; ++ args->nsock = nsock; + nsock->cookie++; + mutex_unlock(&nsock->tx_lock); + sockfd_put(old); +@@ -1396,6 +1404,7 @@ static int nbd_start_device(struct nbd_device *nbd) + refcount_inc(&nbd->config_refs); + INIT_WORK(&args->work, recv_work); + args->nbd = nbd; ++ args->nsock = config->socks[i]; + args->index = i; + queue_work(nbd->recv_workq, &args->work); + } +@@ -1530,17 +1539,20 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode, + return error; + } + +-static struct nbd_config *nbd_alloc_config(void) ++static int nbd_alloc_and_init_config(struct nbd_device *nbd) + { + struct nbd_config *config; + ++ if (WARN_ON(nbd->config)) ++ return -EINVAL; ++ + if (!try_module_get(THIS_MODULE)) +- return ERR_PTR(-ENODEV); ++ return -ENODEV; + + config = kzalloc(sizeof(struct nbd_config), GFP_NOFS); + if (!config) { + module_put(THIS_MODULE); +- return ERR_PTR(-ENOMEM); ++ return -ENOMEM; + } + + atomic_set(&config->recv_threads, 0); +@@ -1548,7 +1560,10 @@ static struct nbd_config *nbd_alloc_config(void) + init_waitqueue_head(&config->conn_wait); + config->blksize_bits = NBD_DEF_BLKSIZE_BITS; + atomic_set(&config->live_connections, 0); +- return config; ++ nbd->config = config; ++ refcount_set(&nbd->config_refs, 1); ++ ++ return 0; + } + + static int nbd_open(struct block_device *bdev, fmode_t mode) +@@ -1567,21 +1582,17 @@ static int nbd_open(struct block_device *bdev, fmode_t mode) + goto out; + } + if (!refcount_inc_not_zero(&nbd->config_refs)) { +- struct nbd_config *config; +- + mutex_lock(&nbd->config_lock); + if (refcount_inc_not_zero(&nbd->config_refs)) { + mutex_unlock(&nbd->config_lock); + goto out; + } +- config = nbd_alloc_config(); +- if (IS_ERR(config)) { +- ret = PTR_ERR(config); ++ ret = nbd_alloc_and_init_config(nbd); ++ if (ret) { + mutex_unlock(&nbd->config_lock); + goto out; + } +- nbd->config = config; +- refcount_set(&nbd->config_refs, 1); ++ + refcount_inc(&nbd->refs); + mutex_unlock(&nbd->config_lock); + if (max_part) +@@ -1990,22 +2001,17 @@ again: + pr_err("nbd%d already in use\n", index); + return -EBUSY; + } +- if (WARN_ON(nbd->config)) { +- mutex_unlock(&nbd->config_lock); +- nbd_put(nbd); +- return -EINVAL; +- } +- config = nbd_alloc_config(); +- if (IS_ERR(config)) { ++ ++ ret = nbd_alloc_and_init_config(nbd); ++ if (ret) { + mutex_unlock(&nbd->config_lock); + nbd_put(nbd); + pr_err("couldn't allocate config\n"); +- return PTR_ERR(config); ++ return ret; + } +- nbd->config = config; +- refcount_set(&nbd->config_refs, 1); +- set_bit(NBD_RT_BOUND, &config->runtime_flags); + ++ config = nbd->config; ++ set_bit(NBD_RT_BOUND, &config->runtime_flags); + ret = nbd_genl_size_set(info, nbd); + if (ret) + goto out; +diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c +index 592d48ecf241f..7abcd7f2848ee 100644 +--- a/drivers/dma/stm32-dma.c ++++ b/drivers/dma/stm32-dma.c +@@ -1249,8 +1249,8 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy( + enum dma_slave_buswidth max_width; + struct stm32_dma_desc *desc; + size_t xfer_count, offset; +- u32 num_sgs, best_burst, dma_burst, threshold; +- int i; ++ u32 num_sgs, best_burst, threshold; ++ int dma_burst, i; + + num_sgs = DIV_ROUND_UP(len, STM32_DMA_ALIGNED_MAX_DATA_ITEMS); + desc = kzalloc(struct_size(desc, sg_req, num_sgs), GFP_NOWAIT); +@@ -1268,6 +1268,10 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy( + best_burst = stm32_dma_get_best_burst(len, STM32_DMA_MAX_BURST, + threshold, max_width); + dma_burst = stm32_dma_get_burst(chan, best_burst); ++ if (dma_burst < 0) { ++ kfree(desc); ++ return NULL; ++ } + + stm32_dma_clear_reg(&desc->sg_req[i].chan_reg); + desc->sg_req[i].chan_reg.dma_scr = +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c +index 4642cff0e1a4f..69b3829bbe53f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c +@@ -631,13 +631,14 @@ static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry) + + if (!entry->bo) + return; ++ ++ entry->bo->vm_bo = NULL; + shadow = amdgpu_bo_shadowed(entry->bo); + if (shadow) { + ttm_bo_set_bulk_move(&shadow->tbo, NULL); + amdgpu_bo_unref(&shadow); + } + ttm_bo_set_bulk_move(&entry->bo->tbo, NULL); +- entry->bo->vm_bo = NULL; + + spin_lock(&entry->vm->status_lock); + list_del(&entry->vm_status); +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +index 809eca54fc617..856db876af141 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +@@ -1690,6 +1690,32 @@ static void sdma_v5_2_get_clockgating_state(void *handle, u64 *flags) + *flags |= AMD_CG_SUPPORT_SDMA_LS; + } + ++static void sdma_v5_2_ring_begin_use(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ ++ /* SDMA 5.2.3 (RMB) FW doesn't seem to properly ++ * disallow GFXOFF in some cases leading to ++ * hangs in SDMA. Disallow GFXOFF while SDMA is active. ++ * We can probably just limit this to 5.2.3, ++ * but it shouldn't hurt for other parts since ++ * this GFXOFF will be disallowed anyway when SDMA is ++ * active, this just makes it explicit. ++ */ ++ amdgpu_gfx_off_ctrl(adev, false); ++} ++ ++static void sdma_v5_2_ring_end_use(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ ++ /* SDMA 5.2.3 (RMB) FW doesn't seem to properly ++ * disallow GFXOFF in some cases leading to ++ * hangs in SDMA. Allow GFXOFF when SDMA is complete. ++ */ ++ amdgpu_gfx_off_ctrl(adev, true); ++} ++ + const struct amd_ip_funcs sdma_v5_2_ip_funcs = { + .name = "sdma_v5_2", + .early_init = sdma_v5_2_early_init, +@@ -1738,6 +1764,8 @@ static const struct amdgpu_ring_funcs sdma_v5_2_ring_funcs = { + .test_ib = sdma_v5_2_ring_test_ib, + .insert_nop = sdma_v5_2_ring_insert_nop, + .pad_ib = sdma_v5_2_ring_pad_ib, ++ .begin_use = sdma_v5_2_ring_begin_use, ++ .end_use = sdma_v5_2_ring_end_use, + .emit_wreg = sdma_v5_2_ring_emit_wreg, + .emit_reg_wait = sdma_v5_2_ring_emit_reg_wait, + .emit_reg_write_reg_wait = sdma_v5_2_ring_emit_reg_write_reg_wait, +diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +index 9edd39322c822..67287ad07226c 100644 +--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c ++++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +@@ -816,6 +816,8 @@ bool is_psr_su_specific_panel(struct dc_link *link) + ((dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x08) || + (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x07))) + isPSRSUSupported = false; ++ else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x03) ++ isPSRSUSupported = false; + else if (dpcd_caps->psr_info.force_psrsu_cap == 0x1) + isPSRSUSupported = true; + } +diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c +index eefa33c555aca..23d854bd73b77 100644 +--- a/drivers/gpu/drm/i915/display/intel_fb.c ++++ b/drivers/gpu/drm/i915/display/intel_fb.c +@@ -1441,8 +1441,20 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p + + size += remap_info->size; + } else { +- unsigned int dst_stride = plane_view_dst_stride_tiles(fb, color_plane, +- remap_info->width); ++ unsigned int dst_stride; ++ ++ /* ++ * The hardware automagically calculates the CCS AUX surface ++ * stride from the main surface stride so can't really remap a ++ * smaller subset (unless we'd remap in whole AUX page units). ++ */ ++ if (intel_fb_needs_pot_stride_remap(fb) && ++ intel_fb_is_ccs_modifier(fb->base.modifier)) ++ dst_stride = remap_info->src_stride; ++ else ++ dst_stride = remap_info->width; ++ ++ dst_stride = plane_view_dst_stride_tiles(fb, color_plane, dst_stride); + + assign_chk_ovf(i915, remap_info->dst_stride, dst_stride); + color_plane_info->mapping_stride = dst_stride * +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +index 7fb52a573436e..558000db4a100 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +@@ -736,6 +736,7 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc, + crtc); + struct mtk_crtc_state *mtk_crtc_state = to_mtk_crtc_state(crtc_state); + struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); ++ unsigned long flags; + + if (mtk_crtc->event && mtk_crtc_state->base.event) + DRM_ERROR("new event while there is still a pending event\n"); +@@ -743,7 +744,11 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc, + if (mtk_crtc_state->base.event) { + mtk_crtc_state->base.event->pipe = drm_crtc_index(crtc); + WARN_ON(drm_crtc_vblank_get(crtc) != 0); ++ ++ spin_lock_irqsave(&crtc->dev->event_lock, flags); + mtk_crtc->event = mtk_crtc_state->base.event; ++ spin_unlock_irqrestore(&crtc->dev->event_lock, flags); ++ + mtk_crtc_state->base.event = NULL; + } + } +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index d1094bb1aa429..220d6b2af4d3f 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -380,7 +380,7 @@ static int asus_raw_event(struct hid_device *hdev, + return 0; + } + +-static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size) ++static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size) + { + unsigned char *dmabuf; + int ret; +@@ -403,7 +403,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size + + static int asus_kbd_init(struct hid_device *hdev) + { +- u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, ++ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; + int ret; + +@@ -417,7 +417,7 @@ static int asus_kbd_init(struct hid_device *hdev) + static int asus_kbd_get_functions(struct hid_device *hdev, + unsigned char *kbd_func) + { +- u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; ++ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; + u8 *readbuf; + int ret; + +@@ -448,7 +448,7 @@ static int asus_kbd_get_functions(struct hid_device *hdev, + + static int rog_nkey_led_init(struct hid_device *hdev) + { +- u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 }; ++ const u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 }; + u8 buf_init2[] = { FEATURE_KBD_LED_REPORT_ID1, 0x41, 0x53, 0x55, 0x53, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; + u8 buf_init3[] = { FEATURE_KBD_LED_REPORT_ID1, +@@ -1012,6 +1012,24 @@ static int asus_start_multitouch(struct hid_device *hdev) + return 0; + } + ++static int __maybe_unused asus_resume(struct hid_device *hdev) { ++ struct asus_drvdata *drvdata = hid_get_drvdata(hdev); ++ int ret = 0; ++ ++ if (drvdata->kbd_backlight) { ++ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, ++ drvdata->kbd_backlight->cdev.brightness }; ++ ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); ++ if (ret < 0) { ++ hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret); ++ goto asus_resume_err; ++ } ++ } ++ ++asus_resume_err: ++ return ret; ++} ++ + static int __maybe_unused asus_reset_resume(struct hid_device *hdev) + { + struct asus_drvdata *drvdata = hid_get_drvdata(hdev); +@@ -1303,6 +1321,7 @@ static struct hid_driver asus_driver = { + .input_configured = asus_input_configured, + #ifdef CONFIG_PM + .reset_resume = asus_reset_resume, ++ .resume = asus_resume, + #endif + .event = asus_event, + .raw_event = asus_raw_event +diff --git a/drivers/hid/hid-glorious.c b/drivers/hid/hid-glorious.c +index 558eb08c19ef9..281b3a7187cec 100644 +--- a/drivers/hid/hid-glorious.c ++++ b/drivers/hid/hid-glorious.c +@@ -21,6 +21,10 @@ MODULE_DESCRIPTION("HID driver for Glorious PC Gaming Race mice"); + * Glorious Model O and O- specify the const flag in the consumer input + * report descriptor, which leads to inputs being ignored. Fix this + * by patching the descriptor. ++ * ++ * Glorious Model I incorrectly specifes the Usage Minimum for its ++ * keyboard HID report, causing keycodes to be misinterpreted. ++ * Fix this by setting Usage Minimum to 0 in that report. + */ + static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) +@@ -32,6 +36,10 @@ static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc, + rdesc[85] = rdesc[113] = rdesc[141] = \ + HID_MAIN_ITEM_VARIABLE | HID_MAIN_ITEM_RELATIVE; + } ++ if (*rsize == 156 && rdesc[41] == 1) { ++ hid_info(hdev, "patching Glorious Model I keyboard report descriptor\n"); ++ rdesc[41] = 0; ++ } + return rdesc; + } + +@@ -44,6 +52,8 @@ static void glorious_update_name(struct hid_device *hdev) + model = "Model O"; break; + case USB_DEVICE_ID_GLORIOUS_MODEL_D: + model = "Model D"; break; ++ case USB_DEVICE_ID_GLORIOUS_MODEL_I: ++ model = "Model I"; break; + } + + snprintf(hdev->name, sizeof(hdev->name), "%s %s", "Glorious", model); +@@ -66,10 +76,12 @@ static int glorious_probe(struct hid_device *hdev, + } + + static const struct hid_device_id glorious_devices[] = { +- { HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH, + USB_DEVICE_ID_GLORIOUS_MODEL_O) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH, + USB_DEVICE_ID_GLORIOUS_MODEL_D) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LAVIEW, ++ USB_DEVICE_ID_GLORIOUS_MODEL_I) }, + { } + }; + MODULE_DEVICE_TABLE(hid, glorious_devices); +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 130fc5f341422..1be454bafcb91 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -503,10 +503,6 @@ + #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a + #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100 + +-#define USB_VENDOR_ID_GLORIOUS 0x258a +-#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033 +-#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036 +- + #define I2C_VENDOR_ID_GOODIX 0x27c6 + #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0 + +@@ -729,6 +725,9 @@ + #define USB_VENDOR_ID_LABTEC 0x1020 + #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 + ++#define USB_VENDOR_ID_LAVIEW 0x22D4 ++#define USB_DEVICE_ID_GLORIOUS_MODEL_I 0x1503 ++ + #define USB_VENDOR_ID_LCPOWER 0x1241 + #define USB_DEVICE_ID_LCPOWER_LC1000 0xf767 + +@@ -1131,6 +1130,10 @@ + #define USB_VENDOR_ID_SIGMATEL 0x066F + #define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780 + ++#define USB_VENDOR_ID_SINOWEALTH 0x258a ++#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033 ++#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036 ++ + #define USB_VENDOR_ID_SIS_TOUCH 0x0457 + #define USB_DEVICE_ID_SIS9200_TOUCH 0x9200 + #define USB_DEVICE_ID_SIS817_TOUCH 0x0817 +diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c +index 7c1b33be9d134..149a3c74346b4 100644 +--- a/drivers/hid/hid-lenovo.c ++++ b/drivers/hid/hid-lenovo.c +@@ -692,7 +692,8 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, + * so set middlebutton_state to 3 + * to never apply workaround anymore + */ +- if (cptkbd_data->middlebutton_state == 1 && ++ if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD && ++ cptkbd_data->middlebutton_state == 1 && + usage->type == EV_REL && + (usage->code == REL_X || usage->code == REL_Y)) { + cptkbd_data->middlebutton_state = 3; +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 8db4ae05febc8..5ec1f174127a3 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -2048,6 +2048,11 @@ static const struct hid_device_id mt_devices[] = { + MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, + USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) }, + ++ /* HONOR GLO-GXXX panel */ ++ { .driver_data = MT_CLS_VTL, ++ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, ++ 0x347d, 0x7853) }, ++ + /* Ilitek dual touch panel */ + { .driver_data = MT_CLS_NSMU, + MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 056bb32091285..60884066362a1 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -33,6 +33,7 @@ static const struct hid_device_id hid_quirks[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS }, + { HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD }, + { HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET }, +diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h +index aebb7ef10e631..e86fa736dc4ee 100644 +--- a/drivers/md/bcache/bcache.h ++++ b/drivers/md/bcache/bcache.h +@@ -265,6 +265,7 @@ struct bcache_device { + #define BCACHE_DEV_WB_RUNNING 3 + #define BCACHE_DEV_RATE_DW_RUNNING 4 + int nr_stripes; ++#define BCH_MIN_STRIPE_SZ ((4 << 20) >> SECTOR_SHIFT) + unsigned int stripe_size; + atomic_t *stripe_sectors_dirty; + unsigned long *full_dirty_stripes; +diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c +index 05e3157fc7b4e..6a2f57ae0f3c2 100644 +--- a/drivers/md/bcache/btree.c ++++ b/drivers/md/bcache/btree.c +@@ -974,6 +974,9 @@ err: + * + * The btree node will have either a read or a write lock held, depending on + * level and op->lock. ++ * ++ * Note: Only error code or btree pointer will be returned, it is unncessary ++ * for callers to check NULL pointer. + */ + struct btree *bch_btree_node_get(struct cache_set *c, struct btree_op *op, + struct bkey *k, int level, bool write, +@@ -1085,6 +1088,10 @@ retry: + mutex_unlock(&b->c->bucket_lock); + } + ++/* ++ * Only error code or btree pointer will be returned, it is unncessary for ++ * callers to check NULL pointer. ++ */ + struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, + int level, bool wait, + struct btree *parent) +diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c +index 7660962e7b8b4..70e5bd8961d2f 100644 +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -905,6 +905,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size, + + if (!d->stripe_size) + d->stripe_size = 1 << 31; ++ else if (d->stripe_size < BCH_MIN_STRIPE_SZ) ++ d->stripe_size = roundup(BCH_MIN_STRIPE_SZ, d->stripe_size); + + n = DIV_ROUND_UP_ULL(sectors, d->stripe_size); + if (!n || n > max_stripes) { +@@ -2017,7 +2019,7 @@ static int run_cache_set(struct cache_set *c) + c->root = bch_btree_node_get(c, NULL, k, + j->btree_level, + true, NULL); +- if (IS_ERR_OR_NULL(c->root)) ++ if (IS_ERR(c->root)) + goto err; + + list_del_init(&c->root->list); +diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c +index 01c7c6ca4789f..18c6e0d2877b5 100644 +--- a/drivers/md/bcache/writeback.c ++++ b/drivers/md/bcache/writeback.c +@@ -913,7 +913,7 @@ static int bch_dirty_init_thread(void *arg) + int cur_idx, prev_idx, skip_nr; + + k = p = NULL; +- cur_idx = prev_idx = 0; ++ prev_idx = 0; + + bch_btree_iter_init(&c->root->keys, &iter, NULL); + k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad); +diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.c b/drivers/net/ethernet/amazon/ena/ena_eth_com.c +index 3d6f0a466a9ed..f9f886289b970 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.c ++++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.c +@@ -328,9 +328,6 @@ static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq, + * compare it to the stored version, just create the meta + */ + if (io_sq->disable_meta_caching) { +- if (unlikely(!ena_tx_ctx->meta_valid)) +- return -EINVAL; +- + *have_meta = true; + return ena_com_create_meta(io_sq, ena_meta); + } +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c +index 42a66b74c1e5b..044b8afde69a0 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -74,6 +74,8 @@ static void ena_unmap_tx_buff(struct ena_ring *tx_ring, + struct ena_tx_buffer *tx_info); + static int ena_create_io_tx_queues_in_range(struct ena_adapter *adapter, + int first_index, int count); ++static void ena_free_all_io_tx_resources_in_range(struct ena_adapter *adapter, ++ int first_index, int count); + + /* Increase a stat by cnt while holding syncp seqlock on 32bit machines */ + static void ena_increase_stat(u64 *statp, u64 cnt, +@@ -457,23 +459,22 @@ static void ena_init_all_xdp_queues(struct ena_adapter *adapter) + + static int ena_setup_and_create_all_xdp_queues(struct ena_adapter *adapter) + { ++ u32 xdp_first_ring = adapter->xdp_first_ring; ++ u32 xdp_num_queues = adapter->xdp_num_queues; + int rc = 0; + +- rc = ena_setup_tx_resources_in_range(adapter, adapter->xdp_first_ring, +- adapter->xdp_num_queues); ++ rc = ena_setup_tx_resources_in_range(adapter, xdp_first_ring, xdp_num_queues); + if (rc) + goto setup_err; + +- rc = ena_create_io_tx_queues_in_range(adapter, +- adapter->xdp_first_ring, +- adapter->xdp_num_queues); ++ rc = ena_create_io_tx_queues_in_range(adapter, xdp_first_ring, xdp_num_queues); + if (rc) + goto create_err; + + return 0; + + create_err: +- ena_free_all_io_tx_resources(adapter); ++ ena_free_all_io_tx_resources_in_range(adapter, xdp_first_ring, xdp_num_queues); + setup_err: + return rc; + } +@@ -1617,20 +1618,23 @@ static void ena_set_rx_hash(struct ena_ring *rx_ring, + } + } + +-static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp) ++static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp, u16 num_descs) + { + struct ena_rx_buffer *rx_info; + int ret; + ++ /* XDP multi-buffer packets not supported */ ++ if (unlikely(num_descs > 1)) { ++ netdev_err_once(rx_ring->adapter->netdev, ++ "xdp: dropped unsupported multi-buffer packets\n"); ++ ena_increase_stat(&rx_ring->rx_stats.xdp_drop, 1, &rx_ring->syncp); ++ return ENA_XDP_DROP; ++ } ++ + rx_info = &rx_ring->rx_buffer_info[rx_ring->ena_bufs[0].req_id]; + xdp_prepare_buff(xdp, page_address(rx_info->page), + rx_info->page_offset, + rx_ring->ena_bufs[0].len, false); +- /* If for some reason we received a bigger packet than +- * we expect, then we simply drop it +- */ +- if (unlikely(rx_ring->ena_bufs[0].len > ENA_XDP_MAX_MTU)) +- return ENA_XDP_DROP; + + ret = ena_xdp_execute(rx_ring, xdp); + +@@ -1699,7 +1703,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, + ena_rx_ctx.l4_proto, ena_rx_ctx.hash); + + if (ena_xdp_present_ring(rx_ring)) +- xdp_verdict = ena_xdp_handle_buff(rx_ring, &xdp); ++ xdp_verdict = ena_xdp_handle_buff(rx_ring, &xdp, ena_rx_ctx.descs); + + /* allocate skb and fill it */ + if (xdp_verdict == ENA_XDP_PASS) +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +index b5a49166fa972..4d9d7d1edb9b3 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +@@ -938,11 +938,14 @@ void aq_ring_free(struct aq_ring_s *self) + return; + + kfree(self->buff_ring); ++ self->buff_ring = NULL; + +- if (self->dx_ring) ++ if (self->dx_ring) { + dma_free_coherent(aq_nic_get_dev(self->aq_nic), + self->size * self->dx_size, self->dx_ring, + self->dx_ring_pa); ++ self->dx_ring = NULL; ++ } + } + + unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data) +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +index 16c490692f422..4950fde82d175 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -1923,8 +1923,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, + + /* Skip VLAN tag if present */ + if (ether_type == ETH_P_8021Q) { +- struct vlan_ethhdr *vhdr = +- (struct vlan_ethhdr *)skb->data; ++ struct vlan_ethhdr *vhdr = skb_vlan_eth_hdr(skb); + + ether_type = ntohs(vhdr->h_vlan_encapsulated_proto); + } +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index e81cb825dff4c..623cdeb29ed90 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -1796,6 +1796,21 @@ static void bnxt_deliver_skb(struct bnxt *bp, struct bnxt_napi *bnapi, + napi_gro_receive(&bnapi->napi, skb); + } + ++static bool bnxt_rx_ts_valid(struct bnxt *bp, u32 flags, ++ struct rx_cmp_ext *rxcmp1, u32 *cmpl_ts) ++{ ++ u32 ts = le32_to_cpu(rxcmp1->rx_cmp_timestamp); ++ ++ if (BNXT_PTP_RX_TS_VALID(flags)) ++ goto ts_valid; ++ if (!bp->ptp_all_rx_tstamp || !ts || !BNXT_ALL_RX_TS_VALID(flags)) ++ return false; ++ ++ts_valid: ++ *cmpl_ts = ts; ++ return true; ++} ++ + /* returns the following: + * 1 - 1 packet successfully received + * 0 - successful TPA_START, packet not completed yet +@@ -1821,6 +1836,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, + struct sk_buff *skb; + struct xdp_buff xdp; + u32 flags, misc; ++ u32 cmpl_ts; + void *data; + int rc = 0; + +@@ -2043,10 +2059,8 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, + } + } + +- if (unlikely((flags & RX_CMP_FLAGS_ITYPES_MASK) == +- RX_CMP_FLAGS_ITYPE_PTP_W_TS) || bp->ptp_all_rx_tstamp) { ++ if (bnxt_rx_ts_valid(bp, flags, rxcmp1, &cmpl_ts)) { + if (bp->flags & BNXT_FLAG_CHIP_P5) { +- u32 cmpl_ts = le32_to_cpu(rxcmp1->rx_cmp_timestamp); + u64 ns, ts; + + if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) { +@@ -10708,8 +10722,10 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init, + bnxt_free_skbs(bp); + + /* Save ring stats before shutdown */ +- if (bp->bnapi && irq_re_init) ++ if (bp->bnapi && irq_re_init) { + bnxt_get_ring_stats(bp, &bp->net_stats_prev); ++ bnxt_get_ring_err_stats(bp, &bp->ring_err_stats_prev); ++ } + if (irq_re_init) { + bnxt_free_irq(bp); + bnxt_del_napi(bp); +@@ -10717,10 +10733,8 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init, + bnxt_free_mem(bp, irq_re_init); + } + +-int bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) ++void bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) + { +- int rc = 0; +- + if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { + /* If we get here, it means firmware reset is in progress + * while we are trying to close. We can safely proceed with +@@ -10735,15 +10749,18 @@ int bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) + + #ifdef CONFIG_BNXT_SRIOV + if (bp->sriov_cfg) { ++ int rc; ++ + rc = wait_event_interruptible_timeout(bp->sriov_cfg_wait, + !bp->sriov_cfg, + BNXT_SRIOV_CFG_WAIT_TMO); +- if (rc) +- netdev_warn(bp->dev, "timeout waiting for SRIOV config operation to complete!\n"); ++ if (!rc) ++ netdev_warn(bp->dev, "timeout waiting for SRIOV config operation to complete, proceeding to close!\n"); ++ else if (rc < 0) ++ netdev_warn(bp->dev, "SRIOV config operation interrupted, proceeding to close!\n"); + } + #endif + __bnxt_close_nic(bp, irq_re_init, link_re_init); +- return rc; + } + + static int bnxt_close(struct net_device *dev) +@@ -10958,6 +10975,34 @@ bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) + clear_bit(BNXT_STATE_READ_STATS, &bp->state); + } + ++static void bnxt_get_one_ring_err_stats(struct bnxt *bp, ++ struct bnxt_total_ring_err_stats *stats, ++ struct bnxt_cp_ring_info *cpr) ++{ ++ struct bnxt_sw_stats *sw_stats = &cpr->sw_stats; ++ u64 *hw_stats = cpr->stats.sw_stats; ++ ++ stats->rx_total_l4_csum_errors += sw_stats->rx.rx_l4_csum_errors; ++ stats->rx_total_resets += sw_stats->rx.rx_resets; ++ stats->rx_total_buf_errors += sw_stats->rx.rx_buf_errors; ++ stats->rx_total_oom_discards += sw_stats->rx.rx_oom_discards; ++ stats->rx_total_netpoll_discards += sw_stats->rx.rx_netpoll_discards; ++ stats->rx_total_ring_discards += ++ BNXT_GET_RING_STATS64(hw_stats, rx_discard_pkts); ++ stats->tx_total_ring_discards += ++ BNXT_GET_RING_STATS64(hw_stats, tx_discard_pkts); ++ stats->total_missed_irqs += sw_stats->cmn.missed_irqs; ++} ++ ++void bnxt_get_ring_err_stats(struct bnxt *bp, ++ struct bnxt_total_ring_err_stats *stats) ++{ ++ int i; ++ ++ for (i = 0; i < bp->cp_nr_rings; i++) ++ bnxt_get_one_ring_err_stats(bp, stats, &bp->bnapi[i]->cp_ring); ++} ++ + static bool bnxt_mc_list_updated(struct bnxt *bp, u32 *rx_mask) + { + struct net_device *dev = bp->dev; +@@ -13882,6 +13927,8 @@ static int bnxt_resume(struct device *device) + if (rc) + goto resume_exit; + ++ bnxt_clear_reservations(bp, true); ++ + if (bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, false)) { + rc = -ENODEV; + goto resume_exit; +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h +index 1d2588c92977e..111098b4b6062 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h +@@ -160,7 +160,7 @@ struct rx_cmp { + #define RX_CMP_FLAGS_ERROR (1 << 6) + #define RX_CMP_FLAGS_PLACEMENT (7 << 7) + #define RX_CMP_FLAGS_RSS_VALID (1 << 10) +- #define RX_CMP_FLAGS_UNUSED (1 << 11) ++ #define RX_CMP_FLAGS_PKT_METADATA_PRESENT (1 << 11) + #define RX_CMP_FLAGS_ITYPES_SHIFT 12 + #define RX_CMP_FLAGS_ITYPES_MASK 0xf000 + #define RX_CMP_FLAGS_ITYPE_UNKNOWN (0 << 12) +@@ -187,6 +187,12 @@ struct rx_cmp { + __le32 rx_cmp_rss_hash; + }; + ++#define BNXT_PTP_RX_TS_VALID(flags) \ ++ (((flags) & RX_CMP_FLAGS_ITYPES_MASK) == RX_CMP_FLAGS_ITYPE_PTP_W_TS) ++ ++#define BNXT_ALL_RX_TS_VALID(flags) \ ++ !((flags) & RX_CMP_FLAGS_PKT_METADATA_PRESENT) ++ + #define RX_CMP_HASH_VALID(rxcmp) \ + ((rxcmp)->rx_cmp_len_flags_type & cpu_to_le32(RX_CMP_FLAGS_RSS_VALID)) + +@@ -950,6 +956,17 @@ struct bnxt_sw_stats { + struct bnxt_cmn_sw_stats cmn; + }; + ++struct bnxt_total_ring_err_stats { ++ u64 rx_total_l4_csum_errors; ++ u64 rx_total_resets; ++ u64 rx_total_buf_errors; ++ u64 rx_total_oom_discards; ++ u64 rx_total_netpoll_discards; ++ u64 rx_total_ring_discards; ++ u64 tx_total_ring_discards; ++ u64 total_missed_irqs; ++}; ++ + struct bnxt_stats_mem { + u64 *sw_stats; + u64 *hw_masks; +@@ -2007,6 +2024,8 @@ struct bnxt { + u8 pri2cos_idx[8]; + u8 pri2cos_valid; + ++ struct bnxt_total_ring_err_stats ring_err_stats_prev; ++ + u16 hwrm_max_req_len; + u16 hwrm_max_ext_req_len; + unsigned int hwrm_cmd_timeout; +@@ -2330,7 +2349,9 @@ int bnxt_open_nic(struct bnxt *, bool, bool); + int bnxt_half_open_nic(struct bnxt *bp); + void bnxt_half_close_nic(struct bnxt *bp); + void bnxt_reenable_sriov(struct bnxt *bp); +-int bnxt_close_nic(struct bnxt *, bool, bool); ++void bnxt_close_nic(struct bnxt *, bool, bool); ++void bnxt_get_ring_err_stats(struct bnxt *bp, ++ struct bnxt_total_ring_err_stats *stats); + int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words, + u32 *reg_buf); + void bnxt_fw_exception(struct bnxt *bp); +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +index 8a6f788f62944..2bdebd9c069d8 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +@@ -478,15 +478,8 @@ static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change, + return -ENODEV; + } + bnxt_ulp_stop(bp); +- if (netif_running(bp->dev)) { +- rc = bnxt_close_nic(bp, true, true); +- if (rc) { +- NL_SET_ERR_MSG_MOD(extack, "Failed to close"); +- dev_close(bp->dev); +- rtnl_unlock(); +- break; +- } +- } ++ if (netif_running(bp->dev)) ++ bnxt_close_nic(bp, true, true); + bnxt_vf_reps_free(bp); + rc = bnxt_hwrm_func_drv_unrgtr(bp); + if (rc) { +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +index 89f046ce1373c..7260b4671ecca 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +@@ -164,9 +164,8 @@ static int bnxt_set_coalesce(struct net_device *dev, + reset_coalesce: + if (test_bit(BNXT_STATE_OPEN, &bp->state)) { + if (update_stats) { +- rc = bnxt_close_nic(bp, true, false); +- if (!rc) +- rc = bnxt_open_nic(bp, true, false); ++ bnxt_close_nic(bp, true, false); ++ rc = bnxt_open_nic(bp, true, false); + } else { + rc = bnxt_hwrm_set_coal(bp); + } +@@ -956,12 +955,7 @@ static int bnxt_set_channels(struct net_device *dev, + * before PF unload + */ + } +- rc = bnxt_close_nic(bp, true, false); +- if (rc) { +- netdev_err(bp->dev, "Set channel failure rc :%x\n", +- rc); +- return rc; +- } ++ bnxt_close_nic(bp, true, false); + } + + if (sh) { +@@ -3634,12 +3628,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, + bnxt_run_fw_tests(bp, test_mask, &test_results); + } else { + bnxt_ulp_stop(bp); +- rc = bnxt_close_nic(bp, true, false); +- if (rc) { +- etest->flags |= ETH_TEST_FL_FAILED; +- bnxt_ulp_start(bp, rc); +- return; +- } ++ bnxt_close_nic(bp, true, false); + bnxt_run_fw_tests(bp, test_mask, &test_results); + + buf[BNXT_MACLPBK_TEST_IDX] = 1; +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +index 4faaa9a50f4bc..ae734314f8de5 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +@@ -506,9 +506,8 @@ static int bnxt_hwrm_ptp_cfg(struct bnxt *bp) + + if (netif_running(bp->dev)) { + if (ptp->rx_filter == HWTSTAMP_FILTER_ALL) { +- rc = bnxt_close_nic(bp, false, false); +- if (!rc) +- rc = bnxt_open_nic(bp, false, false); ++ bnxt_close_nic(bp, false, false); ++ rc = bnxt_open_nic(bp, false, false); + } else { + bnxt_ptp_cfg_tstamp_filters(bp); + } +diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c +index b12152e2fca0a..a9e4e6464a04c 100644 +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -1125,7 +1125,7 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, + struct be_wrb_params + *wrb_params) + { +- struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; ++ struct vlan_ethhdr *veh = skb_vlan_eth_hdr(skb); + unsigned int eth_hdr_len; + struct iphdr *ip; + +diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c +index c39b866e2582d..16d3c3610720b 100644 +--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c ++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c +@@ -139,7 +139,8 @@ int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *filter_block, + err = dpsw_acl_add_entry(ethsw->mc_io, 0, ethsw->dpsw_handle, + filter_block->acl_id, acl_entry_cfg); + +- dma_unmap_single(dev, acl_entry_cfg->key_iova, sizeof(cmd_buff), ++ dma_unmap_single(dev, acl_entry_cfg->key_iova, ++ DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, + DMA_TO_DEVICE); + if (err) { + dev_err(dev, "dpsw_acl_add_entry() failed %d\n", err); +@@ -181,8 +182,8 @@ dpaa2_switch_acl_entry_remove(struct dpaa2_switch_filter_block *block, + err = dpsw_acl_remove_entry(ethsw->mc_io, 0, ethsw->dpsw_handle, + block->acl_id, acl_entry_cfg); + +- dma_unmap_single(dev, acl_entry_cfg->key_iova, sizeof(cmd_buff), +- DMA_TO_DEVICE); ++ dma_unmap_single(dev, acl_entry_cfg->key_iova, ++ DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, DMA_TO_DEVICE); + if (err) { + dev_err(dev, "dpsw_acl_remove_entry() failed %d\n", err); + kfree(cmd_buff); +diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +index 2b5909fa93cfa..b98ef4ba172f6 100644 +--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c ++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +@@ -1978,9 +1978,6 @@ static int dpaa2_switch_port_attr_set_event(struct net_device *netdev, + return notifier_from_errno(err); + } + +-static struct notifier_block dpaa2_switch_port_switchdev_nb; +-static struct notifier_block dpaa2_switch_port_switchdev_blocking_nb; +- + static int dpaa2_switch_port_bridge_join(struct net_device *netdev, + struct net_device *upper_dev, + struct netlink_ext_ack *extack) +@@ -2023,9 +2020,7 @@ static int dpaa2_switch_port_bridge_join(struct net_device *netdev, + goto err_egress_flood; + + err = switchdev_bridge_port_offload(netdev, netdev, NULL, +- &dpaa2_switch_port_switchdev_nb, +- &dpaa2_switch_port_switchdev_blocking_nb, +- false, extack); ++ NULL, NULL, false, extack); + if (err) + goto err_switchdev_offload; + +@@ -2059,9 +2054,7 @@ static int dpaa2_switch_port_restore_rxvlan(struct net_device *vdev, int vid, vo + + static void dpaa2_switch_port_pre_bridge_leave(struct net_device *netdev) + { +- switchdev_bridge_port_unoffload(netdev, NULL, +- &dpaa2_switch_port_switchdev_nb, +- &dpaa2_switch_port_switchdev_blocking_nb); ++ switchdev_bridge_port_unoffload(netdev, NULL, NULL, NULL); + } + + static int dpaa2_switch_port_bridge_leave(struct net_device *netdev) +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 33226a22d8a4a..6d1b760022821 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -3541,31 +3541,26 @@ static int fec_set_features(struct net_device *netdev, + return 0; + } + +-static u16 fec_enet_get_raw_vlan_tci(struct sk_buff *skb) +-{ +- struct vlan_ethhdr *vhdr; +- unsigned short vlan_TCI = 0; +- +- if (skb->protocol == htons(ETH_P_ALL)) { +- vhdr = (struct vlan_ethhdr *)(skb->data); +- vlan_TCI = ntohs(vhdr->h_vlan_TCI); +- } +- +- return vlan_TCI; +-} +- + static u16 fec_enet_select_queue(struct net_device *ndev, struct sk_buff *skb, + struct net_device *sb_dev) + { + struct fec_enet_private *fep = netdev_priv(ndev); +- u16 vlan_tag; ++ u16 vlan_tag = 0; + + if (!(fep->quirks & FEC_QUIRK_HAS_AVB)) + return netdev_pick_tx(ndev, skb, NULL); + +- vlan_tag = fec_enet_get_raw_vlan_tci(skb); +- if (!vlan_tag) ++ /* VLAN is present in the payload.*/ ++ if (eth_type_vlan(skb->protocol)) { ++ struct vlan_ethhdr *vhdr = skb_vlan_eth_hdr(skb); ++ ++ vlan_tag = ntohs(vhdr->h_vlan_TCI); ++ /* VLAN is present in the skb but not yet pushed in the payload.*/ ++ } else if (skb_vlan_tag_present(skb)) { ++ vlan_tag = skb->vlan_tci; ++ } else { + return vlan_tag; ++ } + + return fec_enet_vlan_pri_to_queue[vlan_tag >> 13]; + } +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index 5ad22b815b2f0..78d6752fe0519 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -1532,7 +1532,7 @@ static int hns3_handle_vtags(struct hns3_enet_ring *tx_ring, + if (unlikely(rc < 0)) + return rc; + +- vhdr = (struct vlan_ethhdr *)skb->data; ++ vhdr = skb_vlan_eth_hdr(skb); + vhdr->h_vlan_TCI |= cpu_to_be16((skb->priority << VLAN_PRIO_SHIFT) + & VLAN_PRIO_MASK); + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c +index 6d26ee8eefae9..94cf82668efaa 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c +@@ -2986,7 +2986,7 @@ static inline int i40e_tx_prepare_vlan_flags(struct sk_buff *skb, + rc = skb_cow_head(skb, 0); + if (rc < 0) + return rc; +- vhdr = (struct vlan_ethhdr *)skb->data; ++ vhdr = skb_vlan_eth_hdr(skb); + vhdr->h_vlan_TCI = htons(tx_flags >> + I40E_TX_FLAGS_VLAN_SHIFT); + } else { +diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h +index 7389855fa307a..ee0871d929302 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf.h ++++ b/drivers/net/ethernet/intel/iavf/iavf.h +@@ -303,6 +303,7 @@ struct iavf_adapter { + #define IAVF_FLAG_QUEUES_DISABLED BIT(17) + #define IAVF_FLAG_SETUP_NETDEV_FEATURES BIT(18) + #define IAVF_FLAG_REINIT_MSIX_NEEDED BIT(20) ++#define IAVF_FLAG_FDIR_ENABLED BIT(21) + /* duplicates for common code */ + #define IAVF_FLAG_DCB_ENABLED 0 + /* flags for admin queue service task */ +diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +index 31e02624aca48..f4ac2b164b3e9 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +@@ -1063,7 +1063,7 @@ iavf_get_ethtool_fdir_entry(struct iavf_adapter *adapter, + struct iavf_fdir_fltr *rule = NULL; + int ret = 0; + +- if (!FDIR_FLTR_SUPPORT(adapter)) ++ if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED)) + return -EOPNOTSUPP; + + spin_lock_bh(&adapter->fdir_fltr_lock); +@@ -1205,7 +1205,7 @@ iavf_get_fdir_fltr_ids(struct iavf_adapter *adapter, struct ethtool_rxnfc *cmd, + unsigned int cnt = 0; + int val = 0; + +- if (!FDIR_FLTR_SUPPORT(adapter)) ++ if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED)) + return -EOPNOTSUPP; + + cmd->data = IAVF_MAX_FDIR_FILTERS; +@@ -1397,7 +1397,7 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx + int count = 50; + int err; + +- if (!FDIR_FLTR_SUPPORT(adapter)) ++ if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED)) + return -EOPNOTSUPP; + + if (fsp->flow_type & FLOW_MAC_EXT) +@@ -1438,12 +1438,16 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx + spin_lock_bh(&adapter->fdir_fltr_lock); + iavf_fdir_list_add_fltr(adapter, fltr); + adapter->fdir_active_fltr++; +- fltr->state = IAVF_FDIR_FLTR_ADD_REQUEST; +- adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER; ++ if (adapter->link_up) { ++ fltr->state = IAVF_FDIR_FLTR_ADD_REQUEST; ++ adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER; ++ } else { ++ fltr->state = IAVF_FDIR_FLTR_INACTIVE; ++ } + spin_unlock_bh(&adapter->fdir_fltr_lock); + +- mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); +- ++ if (adapter->link_up) ++ mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); + ret: + if (err && fltr) + kfree(fltr); +@@ -1465,7 +1469,7 @@ static int iavf_del_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx + struct iavf_fdir_fltr *fltr = NULL; + int err = 0; + +- if (!FDIR_FLTR_SUPPORT(adapter)) ++ if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED)) + return -EOPNOTSUPP; + + spin_lock_bh(&adapter->fdir_fltr_lock); +@@ -1474,6 +1478,11 @@ static int iavf_del_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx + if (fltr->state == IAVF_FDIR_FLTR_ACTIVE) { + fltr->state = IAVF_FDIR_FLTR_DEL_REQUEST; + adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER; ++ } else if (fltr->state == IAVF_FDIR_FLTR_INACTIVE) { ++ list_del(&fltr->list); ++ kfree(fltr); ++ adapter->fdir_active_fltr--; ++ fltr = NULL; + } else { + err = -EBUSY; + } +@@ -1782,7 +1791,7 @@ static int iavf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd, + ret = 0; + break; + case ETHTOOL_GRXCLSRLCNT: +- if (!FDIR_FLTR_SUPPORT(adapter)) ++ if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED)) + break; + spin_lock_bh(&adapter->fdir_fltr_lock); + cmd->rule_cnt = adapter->fdir_active_fltr; +diff --git a/drivers/net/ethernet/intel/iavf/iavf_fdir.h b/drivers/net/ethernet/intel/iavf/iavf_fdir.h +index 9eb9f73f6adf3..d31bd923ba8cb 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_fdir.h ++++ b/drivers/net/ethernet/intel/iavf/iavf_fdir.h +@@ -6,12 +6,25 @@ + + struct iavf_adapter; + +-/* State of Flow Director filter */ ++/* State of Flow Director filter ++ * ++ * *_REQUEST states are used to mark filter to be sent to PF driver to perform ++ * an action (either add or delete filter). *_PENDING states are an indication ++ * that request was sent to PF and the driver is waiting for response. ++ * ++ * Both DELETE and DISABLE states are being used to delete a filter in PF. ++ * The difference is that after a successful response filter in DEL_PENDING ++ * state is being deleted from VF driver as well and filter in DIS_PENDING state ++ * is being changed to INACTIVE state. ++ */ + enum iavf_fdir_fltr_state_t { + IAVF_FDIR_FLTR_ADD_REQUEST, /* User requests to add filter */ + IAVF_FDIR_FLTR_ADD_PENDING, /* Filter pending add by the PF */ + IAVF_FDIR_FLTR_DEL_REQUEST, /* User requests to delete filter */ + IAVF_FDIR_FLTR_DEL_PENDING, /* Filter pending delete by the PF */ ++ IAVF_FDIR_FLTR_DIS_REQUEST, /* Filter scheduled to be disabled */ ++ IAVF_FDIR_FLTR_DIS_PENDING, /* Filter pending disable by the PF */ ++ IAVF_FDIR_FLTR_INACTIVE, /* Filter inactive on link down */ + IAVF_FDIR_FLTR_ACTIVE, /* Filter is active */ + }; + +diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c +index 4836bac2bd09d..b9c4b311cd625 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_main.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c +@@ -1368,18 +1368,20 @@ static void iavf_clear_cloud_filters(struct iavf_adapter *adapter) + **/ + static void iavf_clear_fdir_filters(struct iavf_adapter *adapter) + { +- struct iavf_fdir_fltr *fdir, *fdirtmp; ++ struct iavf_fdir_fltr *fdir; + + /* remove all Flow Director filters */ + spin_lock_bh(&adapter->fdir_fltr_lock); +- list_for_each_entry_safe(fdir, fdirtmp, &adapter->fdir_list_head, +- list) { ++ list_for_each_entry(fdir, &adapter->fdir_list_head, list) { + if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST) { +- list_del(&fdir->list); +- kfree(fdir); +- adapter->fdir_active_fltr--; +- } else { +- fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST; ++ /* Cancel a request, keep filter as inactive */ ++ fdir->state = IAVF_FDIR_FLTR_INACTIVE; ++ } else if (fdir->state == IAVF_FDIR_FLTR_ADD_PENDING || ++ fdir->state == IAVF_FDIR_FLTR_ACTIVE) { ++ /* Disable filters which are active or have a pending ++ * request to PF to be added ++ */ ++ fdir->state = IAVF_FDIR_FLTR_DIS_REQUEST; + } + } + spin_unlock_bh(&adapter->fdir_fltr_lock); +@@ -4210,6 +4212,33 @@ static int iavf_setup_tc(struct net_device *netdev, enum tc_setup_type type, + } + } + ++/** ++ * iavf_restore_fdir_filters ++ * @adapter: board private structure ++ * ++ * Restore existing FDIR filters when VF netdev comes back up. ++ **/ ++static void iavf_restore_fdir_filters(struct iavf_adapter *adapter) ++{ ++ struct iavf_fdir_fltr *f; ++ ++ spin_lock_bh(&adapter->fdir_fltr_lock); ++ list_for_each_entry(f, &adapter->fdir_list_head, list) { ++ if (f->state == IAVF_FDIR_FLTR_DIS_REQUEST) { ++ /* Cancel a request, keep filter as active */ ++ f->state = IAVF_FDIR_FLTR_ACTIVE; ++ } else if (f->state == IAVF_FDIR_FLTR_DIS_PENDING || ++ f->state == IAVF_FDIR_FLTR_INACTIVE) { ++ /* Add filters which are inactive or have a pending ++ * request to PF to be deleted ++ */ ++ f->state = IAVF_FDIR_FLTR_ADD_REQUEST; ++ adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER; ++ } ++ } ++ spin_unlock_bh(&adapter->fdir_fltr_lock); ++} ++ + /** + * iavf_open - Called when a network interface is made active + * @netdev: network interface device structure +@@ -4277,8 +4306,9 @@ static int iavf_open(struct net_device *netdev) + + spin_unlock_bh(&adapter->mac_vlan_list_lock); + +- /* Restore VLAN filters that were removed with IFF_DOWN */ ++ /* Restore filters that were removed with IFF_DOWN */ + iavf_restore_filters(adapter); ++ iavf_restore_fdir_filters(adapter); + + iavf_configure(adapter); + +@@ -4415,6 +4445,49 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu) + return ret; + } + ++/** ++ * iavf_disable_fdir - disable Flow Director and clear existing filters ++ * @adapter: board private structure ++ **/ ++static void iavf_disable_fdir(struct iavf_adapter *adapter) ++{ ++ struct iavf_fdir_fltr *fdir, *fdirtmp; ++ bool del_filters = false; ++ ++ adapter->flags &= ~IAVF_FLAG_FDIR_ENABLED; ++ ++ /* remove all Flow Director filters */ ++ spin_lock_bh(&adapter->fdir_fltr_lock); ++ list_for_each_entry_safe(fdir, fdirtmp, &adapter->fdir_list_head, ++ list) { ++ if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST || ++ fdir->state == IAVF_FDIR_FLTR_INACTIVE) { ++ /* Delete filters not registered in PF */ ++ list_del(&fdir->list); ++ kfree(fdir); ++ adapter->fdir_active_fltr--; ++ } else if (fdir->state == IAVF_FDIR_FLTR_ADD_PENDING || ++ fdir->state == IAVF_FDIR_FLTR_DIS_REQUEST || ++ fdir->state == IAVF_FDIR_FLTR_ACTIVE) { ++ /* Filters registered in PF, schedule their deletion */ ++ fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST; ++ del_filters = true; ++ } else if (fdir->state == IAVF_FDIR_FLTR_DIS_PENDING) { ++ /* Request to delete filter already sent to PF, change ++ * state to DEL_PENDING to delete filter after PF's ++ * response, not set as INACTIVE ++ */ ++ fdir->state = IAVF_FDIR_FLTR_DEL_PENDING; ++ } ++ } ++ spin_unlock_bh(&adapter->fdir_fltr_lock); ++ ++ if (del_filters) { ++ adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER; ++ mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); ++ } ++} ++ + #define NETIF_VLAN_OFFLOAD_FEATURES (NETIF_F_HW_VLAN_CTAG_RX | \ + NETIF_F_HW_VLAN_CTAG_TX | \ + NETIF_F_HW_VLAN_STAG_RX | \ +@@ -4437,6 +4510,13 @@ static int iavf_set_features(struct net_device *netdev, + iavf_set_vlan_offload_features(adapter, netdev->features, + features); + ++ if ((netdev->features & NETIF_F_NTUPLE) ^ (features & NETIF_F_NTUPLE)) { ++ if (features & NETIF_F_NTUPLE) ++ adapter->flags |= IAVF_FLAG_FDIR_ENABLED; ++ else ++ iavf_disable_fdir(adapter); ++ } ++ + return 0; + } + +@@ -4732,6 +4812,9 @@ static netdev_features_t iavf_fix_features(struct net_device *netdev, + { + struct iavf_adapter *adapter = netdev_priv(netdev); + ++ if (!FDIR_FLTR_SUPPORT(adapter)) ++ features &= ~NETIF_F_NTUPLE; ++ + return iavf_fix_netdev_vlan_features(adapter, features); + } + +@@ -4849,6 +4932,12 @@ int iavf_process_config(struct iavf_adapter *adapter) + if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) + netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; + ++ if (FDIR_FLTR_SUPPORT(adapter)) { ++ netdev->hw_features |= NETIF_F_NTUPLE; ++ netdev->features |= NETIF_F_NTUPLE; ++ adapter->flags |= IAVF_FLAG_FDIR_ENABLED; ++ } ++ + netdev->priv_flags |= IFF_UNICAST_FLT; + + /* Do not turn on offloads when they are requested to be turned off. +diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +index 5a66b05c03222..951ef350323a2 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +@@ -1752,8 +1752,8 @@ void iavf_add_fdir_filter(struct iavf_adapter *adapter) + **/ + void iavf_del_fdir_filter(struct iavf_adapter *adapter) + { ++ struct virtchnl_fdir_del f = {}; + struct iavf_fdir_fltr *fdir; +- struct virtchnl_fdir_del f; + bool process_fltr = false; + int len; + +@@ -1770,11 +1770,16 @@ void iavf_del_fdir_filter(struct iavf_adapter *adapter) + list_for_each_entry(fdir, &adapter->fdir_list_head, list) { + if (fdir->state == IAVF_FDIR_FLTR_DEL_REQUEST) { + process_fltr = true; +- memset(&f, 0, len); + f.vsi_id = fdir->vc_add_msg.vsi_id; + f.flow_id = fdir->flow_id; + fdir->state = IAVF_FDIR_FLTR_DEL_PENDING; + break; ++ } else if (fdir->state == IAVF_FDIR_FLTR_DIS_REQUEST) { ++ process_fltr = true; ++ f.vsi_id = fdir->vc_add_msg.vsi_id; ++ f.flow_id = fdir->flow_id; ++ fdir->state = IAVF_FDIR_FLTR_DIS_PENDING; ++ break; + } + } + spin_unlock_bh(&adapter->fdir_fltr_lock); +@@ -1918,6 +1923,48 @@ static void iavf_netdev_features_vlan_strip_set(struct net_device *netdev, + netdev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; + } + ++/** ++ * iavf_activate_fdir_filters - Reactivate all FDIR filters after a reset ++ * @adapter: private adapter structure ++ * ++ * Called after a reset to re-add all FDIR filters and delete some of them ++ * if they were pending to be deleted. ++ */ ++static void iavf_activate_fdir_filters(struct iavf_adapter *adapter) ++{ ++ struct iavf_fdir_fltr *f, *ftmp; ++ bool add_filters = false; ++ ++ spin_lock_bh(&adapter->fdir_fltr_lock); ++ list_for_each_entry_safe(f, ftmp, &adapter->fdir_list_head, list) { ++ if (f->state == IAVF_FDIR_FLTR_ADD_REQUEST || ++ f->state == IAVF_FDIR_FLTR_ADD_PENDING || ++ f->state == IAVF_FDIR_FLTR_ACTIVE) { ++ /* All filters and requests have been removed in PF, ++ * restore them ++ */ ++ f->state = IAVF_FDIR_FLTR_ADD_REQUEST; ++ add_filters = true; ++ } else if (f->state == IAVF_FDIR_FLTR_DIS_REQUEST || ++ f->state == IAVF_FDIR_FLTR_DIS_PENDING) { ++ /* Link down state, leave filters as inactive */ ++ f->state = IAVF_FDIR_FLTR_INACTIVE; ++ } else if (f->state == IAVF_FDIR_FLTR_DEL_REQUEST || ++ f->state == IAVF_FDIR_FLTR_DEL_PENDING) { ++ /* Delete filters that were pending to be deleted, the ++ * list on PF is already cleared after a reset ++ */ ++ list_del(&f->list); ++ kfree(f); ++ adapter->fdir_active_fltr--; ++ } ++ } ++ spin_unlock_bh(&adapter->fdir_fltr_lock); ++ ++ if (add_filters) ++ adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER; ++} ++ + /** + * iavf_virtchnl_completion + * @adapter: adapter structure +@@ -2095,7 +2142,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, + spin_lock_bh(&adapter->fdir_fltr_lock); + list_for_each_entry(fdir, &adapter->fdir_list_head, + list) { +- if (fdir->state == IAVF_FDIR_FLTR_DEL_PENDING) { ++ if (fdir->state == IAVF_FDIR_FLTR_DEL_PENDING || ++ fdir->state == IAVF_FDIR_FLTR_DIS_PENDING) { + fdir->state = IAVF_FDIR_FLTR_ACTIVE; + dev_info(&adapter->pdev->dev, "Failed to del Flow Director filter, error %s\n", + iavf_stat_str(&adapter->hw, +@@ -2232,6 +2280,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, + + spin_unlock_bh(&adapter->mac_vlan_list_lock); + ++ iavf_activate_fdir_filters(adapter); ++ + iavf_parse_vf_resource_msg(adapter); + + /* negotiated VIRTCHNL_VF_OFFLOAD_VLAN_V2, so wait for the +@@ -2421,7 +2471,9 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, + list_for_each_entry_safe(fdir, fdir_tmp, &adapter->fdir_list_head, + list) { + if (fdir->state == IAVF_FDIR_FLTR_DEL_PENDING) { +- if (del_fltr->status == VIRTCHNL_FDIR_SUCCESS) { ++ if (del_fltr->status == VIRTCHNL_FDIR_SUCCESS || ++ del_fltr->status == ++ VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST) { + dev_info(&adapter->pdev->dev, "Flow Director filter with location %u is deleted\n", + fdir->loc); + list_del(&fdir->list); +@@ -2433,6 +2485,17 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, + del_fltr->status); + iavf_print_fdir_fltr(adapter, fdir); + } ++ } else if (fdir->state == IAVF_FDIR_FLTR_DIS_PENDING) { ++ if (del_fltr->status == VIRTCHNL_FDIR_SUCCESS || ++ del_fltr->status == ++ VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST) { ++ fdir->state = IAVF_FDIR_FLTR_INACTIVE; ++ } else { ++ fdir->state = IAVF_FDIR_FLTR_ACTIVE; ++ dev_info(&adapter->pdev->dev, "Failed to disable Flow Director filter with status: %d\n", ++ del_fltr->status); ++ iavf_print_fdir_fltr(adapter, fdir); ++ } + } + } + spin_unlock_bh(&adapter->fdir_fltr_lock); +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +index 6105419ae2d5f..9e0e13638c463 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +@@ -8822,7 +8822,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, + + if (skb_cow_head(skb, 0)) + goto out_drop; +- vhdr = (struct vlan_ethhdr *)skb->data; ++ vhdr = skb_vlan_eth_hdr(skb); + vhdr->h_vlan_TCI = htons(tx_flags >> + IXGBE_TX_FLAGS_VLAN_SHIFT); + } else { +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +index d609512998992..b9a4efb955333 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +@@ -642,7 +642,7 @@ static int rvu_nix_register_reporters(struct rvu_devlink *rvu_dl) + + rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq"); + if (!rvu_dl->devlink_wq) +- goto err; ++ return -ENOMEM; + + INIT_WORK(&rvu_reporters->intr_work, rvu_nix_intr_work); + INIT_WORK(&rvu_reporters->gen_work, rvu_nix_gen_work); +@@ -650,9 +650,6 @@ static int rvu_nix_register_reporters(struct rvu_devlink *rvu_dl) + INIT_WORK(&rvu_reporters->ras_work, rvu_nix_ras_work); + + return 0; +-err: +- rvu_nix_health_reporters_destroy(rvu_dl); +- return -ENOMEM; + } + + static int rvu_nix_health_reporters_create(struct rvu_devlink *rvu_dl) +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index f65805860c8d4..0bcf3e5592806 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -671,6 +671,7 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc, + int blkaddr, ucast_idx, index; + struct nix_rx_action action = { 0 }; + u64 relaxed_mask; ++ u8 flow_key_alg; + + if (!hw->cap.nix_rx_multicast && is_cgx_vf(rvu, pcifunc)) + return; +@@ -701,6 +702,8 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc, + action.op = NIX_RX_ACTIONOP_UCAST; + } + ++ flow_key_alg = action.flow_key_alg; ++ + /* RX_ACTION set to MCAST for CGX PF's */ + if (hw->cap.nix_rx_multicast && pfvf->use_mce_list && + is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc))) { +@@ -740,7 +743,7 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc, + req.vf = pcifunc; + req.index = action.index; + req.match_id = action.match_id; +- req.flow_key_alg = action.flow_key_alg; ++ req.flow_key_alg = flow_key_alg; + + rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); + } +@@ -854,6 +857,7 @@ void rvu_npc_install_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf, + u8 mac_addr[ETH_ALEN] = { 0 }; + struct nix_rx_action action = { 0 }; + struct rvu_pfvf *pfvf; ++ u8 flow_key_alg; + u16 vf_func; + + /* Only CGX PF/VF can add allmulticast entry */ +@@ -888,6 +892,7 @@ void rvu_npc_install_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf, + *(u64 *)&action = npc_get_mcam_action(rvu, mcam, + blkaddr, ucast_idx); + ++ flow_key_alg = action.flow_key_alg; + if (action.op != NIX_RX_ACTIONOP_RSS) { + *(u64 *)&action = 0; + action.op = NIX_RX_ACTIONOP_UCAST; +@@ -924,7 +929,7 @@ void rvu_npc_install_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf, + req.vf = pcifunc | vf_func; + req.index = action.index; + req.match_id = action.match_id; +- req.flow_key_alg = action.flow_key_alg; ++ req.flow_key_alg = flow_key_alg; + + rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); + } +@@ -990,11 +995,38 @@ static void npc_update_vf_flow_entry(struct rvu *rvu, struct npc_mcam *mcam, + mutex_unlock(&mcam->lock); + } + ++static void npc_update_rx_action_with_alg_idx(struct rvu *rvu, struct nix_rx_action action, ++ struct rvu_pfvf *pfvf, int mcam_index, int blkaddr, ++ int alg_idx) ++ ++{ ++ struct npc_mcam *mcam = &rvu->hw->mcam; ++ struct rvu_hwinfo *hw = rvu->hw; ++ int bank, op_rss; ++ ++ if (!is_mcam_entry_enabled(rvu, mcam, blkaddr, mcam_index)) ++ return; ++ ++ op_rss = (!hw->cap.nix_rx_multicast || !pfvf->use_mce_list); ++ ++ bank = npc_get_bank(mcam, mcam_index); ++ mcam_index &= (mcam->banksize - 1); ++ ++ /* If Rx action is MCAST update only RSS algorithm index */ ++ if (!op_rss) { ++ *(u64 *)&action = rvu_read64(rvu, blkaddr, ++ NPC_AF_MCAMEX_BANKX_ACTION(mcam_index, bank)); ++ ++ action.flow_key_alg = alg_idx; ++ } ++ rvu_write64(rvu, blkaddr, ++ NPC_AF_MCAMEX_BANKX_ACTION(mcam_index, bank), *(u64 *)&action); ++} ++ + void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, + int group, int alg_idx, int mcam_index) + { + struct npc_mcam *mcam = &rvu->hw->mcam; +- struct rvu_hwinfo *hw = rvu->hw; + struct nix_rx_action action; + int blkaddr, index, bank; + struct rvu_pfvf *pfvf; +@@ -1050,15 +1082,16 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, + /* If PF's promiscuous entry is enabled, + * Set RSS action for that entry as well + */ +- if ((!hw->cap.nix_rx_multicast || !pfvf->use_mce_list) && +- is_mcam_entry_enabled(rvu, mcam, blkaddr, index)) { +- bank = npc_get_bank(mcam, index); +- index &= (mcam->banksize - 1); ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, ++ alg_idx); + +- rvu_write64(rvu, blkaddr, +- NPC_AF_MCAMEX_BANKX_ACTION(index, bank), +- *(u64 *)&action); +- } ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_ALLMULTI_ENTRY); ++ /* If PF's allmulti entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, ++ alg_idx); + } + + void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc, +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +index 55807e2043edf..a2d8ac6204054 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +@@ -1638,6 +1638,21 @@ static void otx2_free_hw_resources(struct otx2_nic *pf) + mutex_unlock(&mbox->lock); + } + ++static bool otx2_promisc_use_mce_list(struct otx2_nic *pfvf) ++{ ++ int vf; ++ ++ /* The AF driver will determine whether to allow the VF netdev or not */ ++ if (is_otx2_vf(pfvf->pcifunc)) ++ return true; ++ ++ /* check if there are any trusted VFs associated with the PF netdev */ ++ for (vf = 0; vf < pci_num_vf(pfvf->pdev); vf++) ++ if (pfvf->vf_configs[vf].trusted) ++ return true; ++ return false; ++} ++ + static void otx2_do_set_rx_mode(struct otx2_nic *pf) + { + struct net_device *netdev = pf->netdev; +@@ -1670,7 +1685,8 @@ static void otx2_do_set_rx_mode(struct otx2_nic *pf) + if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST)) + req->mode |= NIX_RX_MODE_ALLMULTI; + +- req->mode |= NIX_RX_MODE_USE_MCE; ++ if (otx2_promisc_use_mce_list(pf)) ++ req->mode |= NIX_RX_MODE_USE_MCE; + + otx2_sync_mbox_msg(&pf->mbox); + mutex_unlock(&pf->mbox.lock); +@@ -2634,11 +2650,14 @@ static int otx2_ndo_set_vf_trust(struct net_device *netdev, int vf, + pf->vf_configs[vf].trusted = enable; + rc = otx2_set_vf_permissions(pf, vf, OTX2_TRUSTED_VF); + +- if (rc) ++ if (rc) { + pf->vf_configs[vf].trusted = !enable; +- else ++ } else { + netdev_info(pf->netdev, "VF %d is %strusted\n", + vf, enable ? "" : "not "); ++ otx2_set_rx_mode(netdev); ++ } ++ + return rc; + } + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h +index bc76fe6b06230..0ee456480a488 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h +@@ -847,6 +847,7 @@ enum { + MLX5E_STATE_DESTROYING, + MLX5E_STATE_XDP_TX_ENABLED, + MLX5E_STATE_XDP_ACTIVE, ++ MLX5E_STATE_CHANNELS_ACTIVE, + }; + + struct mlx5e_modify_sq_param { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 42e6f2fcf5f59..9910a0480f589 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -2586,6 +2586,7 @@ void mlx5e_close_channels(struct mlx5e_channels *chs) + { + int i; + ++ ASSERT_RTNL(); + if (chs->ptp) { + mlx5e_ptp_close(chs->ptp); + chs->ptp = NULL; +@@ -2865,17 +2866,29 @@ void mlx5e_activate_priv_channels(struct mlx5e_priv *priv) + if (mlx5e_is_vport_rep(priv)) + mlx5e_rep_activate_channels(priv); + ++ set_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state); ++ + mlx5e_wait_channels_min_rx_wqes(&priv->channels); + + if (priv->rx_res) + mlx5e_rx_res_channels_activate(priv->rx_res, &priv->channels); + } + ++static void mlx5e_cancel_tx_timeout_work(struct mlx5e_priv *priv) ++{ ++ WARN_ON_ONCE(test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state)); ++ if (current_work() != &priv->tx_timeout_work) ++ cancel_work_sync(&priv->tx_timeout_work); ++} ++ + void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv) + { + if (priv->rx_res) + mlx5e_rx_res_channels_deactivate(priv->rx_res); + ++ clear_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state); ++ mlx5e_cancel_tx_timeout_work(priv); ++ + if (mlx5e_is_vport_rep(priv)) + mlx5e_rep_deactivate_channels(priv); + +@@ -4617,8 +4630,17 @@ static void mlx5e_tx_timeout_work(struct work_struct *work) + struct net_device *netdev = priv->netdev; + int i; + +- rtnl_lock(); +- mutex_lock(&priv->state_lock); ++ /* Take rtnl_lock to ensure no change in netdev->real_num_tx_queues ++ * through this flow. However, channel closing flows have to wait for ++ * this work to finish while holding rtnl lock too. So either get the ++ * lock or find that channels are being closed for other reason and ++ * this work is not relevant anymore. ++ */ ++ while (!rtnl_trylock()) { ++ if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state)) ++ return; ++ msleep(20); ++ } + + if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) + goto unlock; +@@ -4637,7 +4659,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work) + } + + unlock: +- mutex_unlock(&priv->state_lock); + rtnl_unlock(); + } + +diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +index de8d54b23f738..c005a9df59d1c 100644 +--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c ++++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +@@ -1862,7 +1862,7 @@ netxen_tso_check(struct net_device *netdev, + + if (protocol == cpu_to_be16(ETH_P_8021Q)) { + +- vh = (struct vlan_ethhdr *)skb->data; ++ vh = skb_vlan_eth_hdr(skb); + protocol = vh->h_vlan_encapsulated_proto; + flags = FLAGS_VLAN_TAGGED; + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c +index 65e20693c549e..33f4f58ee51c6 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c +@@ -933,6 +933,7 @@ static void qed_ilt_shadow_free(struct qed_hwfn *p_hwfn) + p_dma->virt_addr = NULL; + } + kfree(p_mngr->ilt_shadow); ++ p_mngr->ilt_shadow = NULL; + } + + static int qed_ilt_blk_alloc(struct qed_hwfn *p_hwfn, +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +index 92930a055cbcc..41894d154013b 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +@@ -318,7 +318,7 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, + + if (adapter->flags & QLCNIC_VLAN_FILTERING) { + if (protocol == ETH_P_8021Q) { +- vh = (struct vlan_ethhdr *)skb->data; ++ vh = skb_vlan_eth_hdr(skb); + vlan_id = ntohs(vh->h_vlan_TCI); + } else if (skb_vlan_tag_present(skb)) { + vlan_id = skb_vlan_tag_get(skb); +@@ -468,7 +468,7 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter, + u32 producer = tx_ring->producer; + + if (protocol == ETH_P_8021Q) { +- vh = (struct vlan_ethhdr *)skb->data; ++ vh = skb_vlan_eth_hdr(skb); + flags = QLCNIC_FLAGS_VLAN_TAGGED; + vlan_tci = ntohs(vh->h_vlan_TCI); + protocol = ntohs(vh->h_vlan_encapsulated_proto); +diff --git a/drivers/net/ethernet/qualcomm/qca_debug.c b/drivers/net/ethernet/qualcomm/qca_debug.c +index f62c39544e086..a739c06ede4e7 100644 +--- a/drivers/net/ethernet/qualcomm/qca_debug.c ++++ b/drivers/net/ethernet/qualcomm/qca_debug.c +@@ -30,6 +30,8 @@ + + #define QCASPI_MAX_REGS 0x20 + ++#define QCASPI_RX_MAX_FRAMES 4 ++ + static const u16 qcaspi_spi_regs[] = { + SPI_REG_BFR_SIZE, + SPI_REG_WRBUF_SPC_AVA, +@@ -252,9 +254,9 @@ qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring, + { + struct qcaspi *qca = netdev_priv(dev); + +- ring->rx_max_pending = 4; ++ ring->rx_max_pending = QCASPI_RX_MAX_FRAMES; + ring->tx_max_pending = TX_RING_MAX_LEN; +- ring->rx_pending = 4; ++ ring->rx_pending = QCASPI_RX_MAX_FRAMES; + ring->tx_pending = qca->txr.count; + } + +@@ -263,22 +265,21 @@ qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam *kernel_ring, + struct netlink_ext_ack *extack) + { +- const struct net_device_ops *ops = dev->netdev_ops; + struct qcaspi *qca = netdev_priv(dev); + +- if ((ring->rx_pending) || ++ if (ring->rx_pending != QCASPI_RX_MAX_FRAMES || + (ring->rx_mini_pending) || + (ring->rx_jumbo_pending)) + return -EINVAL; + +- if (netif_running(dev)) +- ops->ndo_stop(dev); ++ if (qca->spi_thread) ++ kthread_park(qca->spi_thread); + + qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN); + qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN); + +- if (netif_running(dev)) +- ops->ndo_open(dev); ++ if (qca->spi_thread) ++ kthread_unpark(qca->spi_thread); + + return 0; + } +diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c +index 4a1b94e5a8ea9..82f5173a2cfd5 100644 +--- a/drivers/net/ethernet/qualcomm/qca_spi.c ++++ b/drivers/net/ethernet/qualcomm/qca_spi.c +@@ -581,6 +581,18 @@ qcaspi_spi_thread(void *data) + netdev_info(qca->net_dev, "SPI thread created\n"); + while (!kthread_should_stop()) { + set_current_state(TASK_INTERRUPTIBLE); ++ if (kthread_should_park()) { ++ netif_tx_disable(qca->net_dev); ++ netif_carrier_off(qca->net_dev); ++ qcaspi_flush_tx_ring(qca); ++ kthread_parkme(); ++ if (qca->sync == QCASPI_SYNC_READY) { ++ netif_carrier_on(qca->net_dev); ++ netif_wake_queue(qca->net_dev); ++ } ++ continue; ++ } ++ + if ((qca->intr_req == qca->intr_svc) && + !qca->txr.skb[qca->txr.head]) + schedule(); +@@ -609,11 +621,17 @@ qcaspi_spi_thread(void *data) + if (intr_cause & SPI_INT_CPU_ON) { + qcaspi_qca7k_sync(qca, QCASPI_EVENT_CPUON); + ++ /* Frame decoding in progress */ ++ if (qca->frm_handle.state != qca->frm_handle.init) ++ qca->net_dev->stats.rx_dropped++; ++ ++ qcafrm_fsm_init_spi(&qca->frm_handle); ++ qca->stats.device_reset++; ++ + /* not synced. */ + if (qca->sync != QCASPI_SYNC_READY) + continue; + +- qca->stats.device_reset++; + netif_wake_queue(qca->net_dev); + netif_carrier_on(qca->net_dev); + } +diff --git a/drivers/net/ethernet/sfc/tx_tso.c b/drivers/net/ethernet/sfc/tx_tso.c +index 898e5c61d9086..d381d8164f07c 100644 +--- a/drivers/net/ethernet/sfc/tx_tso.c ++++ b/drivers/net/ethernet/sfc/tx_tso.c +@@ -147,7 +147,7 @@ static __be16 efx_tso_check_protocol(struct sk_buff *skb) + EFX_WARN_ON_ONCE_PARANOID(((struct ethhdr *)skb->data)->h_proto != + protocol); + if (protocol == htons(ETH_P_8021Q)) { +- struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; ++ struct vlan_ethhdr *veh = skb_vlan_eth_hdr(skb); + + protocol = veh->h_vlan_encapsulated_proto; + } +diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig +index 31ff351740342..58091ee2bfe60 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig ++++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig +@@ -256,7 +256,7 @@ config DWMAC_INTEL + config DWMAC_LOONGSON + tristate "Loongson PCI DWMAC support" + default MACH_LOONGSON64 +- depends on STMMAC_ETH && PCI ++ depends on (MACH_LOONGSON64 || COMPILE_TEST) && STMMAC_ETH && PCI + depends on COMMON_CLK + help + This selects the LOONGSON PCI bus support for the stmmac driver, +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +index a25c187d31853..49c7aa86faaa8 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +@@ -68,17 +68,15 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id + if (!plat) + return -ENOMEM; + ++ plat->mdio_bus_data = devm_kzalloc(&pdev->dev, ++ sizeof(*plat->mdio_bus_data), ++ GFP_KERNEL); ++ if (!plat->mdio_bus_data) ++ return -ENOMEM; ++ + plat->mdio_node = of_get_child_by_name(np, "mdio"); + if (plat->mdio_node) { + dev_info(&pdev->dev, "Found MDIO subnode\n"); +- +- plat->mdio_bus_data = devm_kzalloc(&pdev->dev, +- sizeof(*plat->mdio_bus_data), +- GFP_KERNEL); +- if (!plat->mdio_bus_data) { +- ret = -ENOMEM; +- goto err_put_node; +- } + plat->mdio_bus_data->needs_reset = true; + } + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 69aac8ed84f67..deb6e95a1bca6 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -4566,13 +4566,10 @@ dma_map_err: + + static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb) + { +- struct vlan_ethhdr *veth; +- __be16 vlan_proto; ++ struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb); ++ __be16 vlan_proto = veth->h_vlan_proto; + u16 vlanid; + +- veth = (struct vlan_ethhdr *)skb->data; +- vlan_proto = veth->h_vlan_proto; +- + if ((vlan_proto == htons(ETH_P_8021Q) && + dev->features & NETIF_F_HW_VLAN_CTAG_RX) || + (vlan_proto == htons(ETH_P_8021AD) && +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +index 5f177ea807258..379fc887ddf46 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +@@ -483,7 +483,11 @@ int stmmac_mdio_register(struct net_device *ndev) + new_bus->parent = priv->device; + + err = of_mdiobus_register(new_bus, mdio_node); +- if (err != 0) { ++ if (err == -ENODEV) { ++ err = 0; ++ dev_info(dev, "MDIO bus is disabled\n"); ++ goto bus_register_fail; ++ } else if (err) { + dev_err_probe(dev, err, "Cannot register the MDIO bus\n"); + goto bus_register_fail; + } +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index 556b2d1cd2aca..293eaf6b3ec9e 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -285,8 +285,10 @@ static int __team_options_register(struct team *team, + return 0; + + inst_rollback: +- for (i--; i >= 0; i--) ++ for (i--; i >= 0; i--) { + __team_option_inst_del_option(team, dst_opts[i]); ++ list_del(&dst_opts[i]->list); ++ } + + i = option_count; + alloc_rollback: +diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c +index a017e9de2119d..7b8afa589a53c 100644 +--- a/drivers/net/usb/aqc111.c ++++ b/drivers/net/usb/aqc111.c +@@ -1079,17 +1079,17 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + u16 pkt_count = 0; + u64 desc_hdr = 0; + u16 vlan_tag = 0; +- u32 skb_len = 0; ++ u32 skb_len; + + if (!skb) + goto err; + +- if (skb->len == 0) ++ skb_len = skb->len; ++ if (skb_len < sizeof(desc_hdr)) + goto err; + +- skb_len = skb->len; + /* RX Descriptor Header */ +- skb_trim(skb, skb->len - sizeof(desc_hdr)); ++ skb_trim(skb, skb_len - sizeof(desc_hdr)); + desc_hdr = le64_to_cpup((u64 *)skb_tail_pointer(skb)); + + /* Check these packets */ +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 4fb981b8732ef..2d82481d34e6b 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1288,6 +1288,7 @@ static const struct usb_device_id products[] = { + {QMI_FIXED_INTF(0x19d2, 0x0168, 4)}, + {QMI_FIXED_INTF(0x19d2, 0x0176, 3)}, + {QMI_FIXED_INTF(0x19d2, 0x0178, 3)}, ++ {QMI_FIXED_INTF(0x19d2, 0x0189, 4)}, /* ZTE MF290 */ + {QMI_FIXED_INTF(0x19d2, 0x0191, 4)}, /* ZTE EuFi890 */ + {QMI_FIXED_INTF(0x19d2, 0x0199, 1)}, /* ZTE MF820S */ + {QMI_FIXED_INTF(0x19d2, 0x0200, 1)}, +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index 4d833781294a4..958a02b19554d 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -8288,43 +8288,6 @@ static bool rtl_check_vendor_ok(struct usb_interface *intf) + return true; + } + +-static bool rtl_vendor_mode(struct usb_interface *intf) +-{ +- struct usb_host_interface *alt = intf->cur_altsetting; +- struct usb_device *udev; +- struct usb_host_config *c; +- int i, num_configs; +- +- if (alt->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) +- return rtl_check_vendor_ok(intf); +- +- /* The vendor mode is not always config #1, so to find it out. */ +- udev = interface_to_usbdev(intf); +- c = udev->config; +- num_configs = udev->descriptor.bNumConfigurations; +- if (num_configs < 2) +- return false; +- +- for (i = 0; i < num_configs; (i++, c++)) { +- struct usb_interface_descriptor *desc = NULL; +- +- if (c->desc.bNumInterfaces > 0) +- desc = &c->intf_cache[0]->altsetting->desc; +- else +- continue; +- +- if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) { +- usb_driver_set_configuration(udev, c->desc.bConfigurationValue); +- break; +- } +- } +- +- if (i == num_configs) +- dev_err(&intf->dev, "Unexpected Device\n"); +- +- return false; +-} +- + static int rtl8152_pre_reset(struct usb_interface *intf) + { + struct r8152 *tp = usb_get_intfdata(intf); +@@ -9556,9 +9519,8 @@ static int rtl_fw_init(struct r8152 *tp) + return 0; + } + +-u8 rtl8152_get_version(struct usb_interface *intf) ++static u8 __rtl_get_hw_ver(struct usb_device *udev) + { +- struct usb_device *udev = interface_to_usbdev(intf); + u32 ocp_data = 0; + __le32 *tmp; + u8 version; +@@ -9628,10 +9590,19 @@ u8 rtl8152_get_version(struct usb_interface *intf) + break; + default: + version = RTL_VER_UNKNOWN; +- dev_info(&intf->dev, "Unknown version 0x%04x\n", ocp_data); ++ dev_info(&udev->dev, "Unknown version 0x%04x\n", ocp_data); + break; + } + ++ return version; ++} ++ ++u8 rtl8152_get_version(struct usb_interface *intf) ++{ ++ u8 version; ++ ++ version = __rtl_get_hw_ver(interface_to_usbdev(intf)); ++ + dev_dbg(&intf->dev, "Detected version 0x%04x\n", version); + + return version; +@@ -9675,7 +9646,10 @@ static int rtl8152_probe(struct usb_interface *intf, + if (version == RTL_VER_UNKNOWN) + return -ENODEV; + +- if (!rtl_vendor_mode(intf)) ++ if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) ++ return -ENODEV; ++ ++ if (!rtl_check_vendor_ok(intf)) + return -ENODEV; + + usb_reset_device(udev); +@@ -9875,43 +9849,37 @@ static void rtl8152_disconnect(struct usb_interface *intf) + } + } + +-#define REALTEK_USB_DEVICE(vend, prod) { \ +- USB_DEVICE_INTERFACE_CLASS(vend, prod, USB_CLASS_VENDOR_SPEC), \ +-}, \ +-{ \ +- USB_DEVICE_AND_INTERFACE_INFO(vend, prod, USB_CLASS_COMM, \ +- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), \ +-} +- + /* table of devices that work with this driver */ + static const struct usb_device_id rtl8152_table[] = { + /* Realtek */ +- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8050), +- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8053), +- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8152), +- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153), +- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8155), +- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8156), ++ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8050) }, ++ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8053) }, ++ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8152) }, ++ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8153) }, ++ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8155) }, ++ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8156) }, + + /* Microsoft */ +- REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab), +- REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07c6), +- REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0927), +- REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0c5e), +- REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101), +- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f), +- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3054), +- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3062), +- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3069), +- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3082), +- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205), +- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c), +- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214), +- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x721e), +- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0xa387), +- REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041), +- REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff), +- REALTEK_USB_DEVICE(VENDOR_ID_TPLINK, 0x0601), ++ { USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab) }, ++ { USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07c6) }, ++ { USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0927) }, ++ { USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0c5e) }, ++ { USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101) }, ++ { USB_DEVICE(VENDOR_ID_LENOVO, 0x304f) }, ++ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3054) }, ++ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3062) }, ++ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3069) }, ++ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3082) }, ++ { USB_DEVICE(VENDOR_ID_LENOVO, 0x7205) }, ++ { USB_DEVICE(VENDOR_ID_LENOVO, 0x720c) }, ++ { USB_DEVICE(VENDOR_ID_LENOVO, 0x7214) }, ++ { USB_DEVICE(VENDOR_ID_LENOVO, 0x721e) }, ++ { USB_DEVICE(VENDOR_ID_LENOVO, 0xa387) }, ++ { USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041) }, ++ { USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff) }, ++ { USB_DEVICE(VENDOR_ID_TPLINK, 0x0601) }, ++ { USB_DEVICE(VENDOR_ID_DLINK, 0xb301) }, ++ { USB_DEVICE(VENDOR_ID_ASUS, 0x1976) }, + {} + }; + +@@ -9931,7 +9899,68 @@ static struct usb_driver rtl8152_driver = { + .disable_hub_initiated_lpm = 1, + }; + +-module_usb_driver(rtl8152_driver); ++static int rtl8152_cfgselector_probe(struct usb_device *udev) ++{ ++ struct usb_host_config *c; ++ int i, num_configs; ++ ++ /* Switch the device to vendor mode, if and only if the vendor mode ++ * driver supports it. ++ */ ++ if (__rtl_get_hw_ver(udev) == RTL_VER_UNKNOWN) ++ return 0; ++ ++ /* The vendor mode is not always config #1, so to find it out. */ ++ c = udev->config; ++ num_configs = udev->descriptor.bNumConfigurations; ++ for (i = 0; i < num_configs; (i++, c++)) { ++ struct usb_interface_descriptor *desc = NULL; ++ ++ if (!c->desc.bNumInterfaces) ++ continue; ++ desc = &c->intf_cache[0]->altsetting->desc; ++ if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) ++ break; ++ } ++ ++ if (i == num_configs) ++ return -ENODEV; ++ ++ if (usb_set_configuration(udev, c->desc.bConfigurationValue)) { ++ dev_err(&udev->dev, "Failed to set configuration %d\n", ++ c->desc.bConfigurationValue); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++static struct usb_device_driver rtl8152_cfgselector_driver = { ++ .name = MODULENAME "-cfgselector", ++ .probe = rtl8152_cfgselector_probe, ++ .id_table = rtl8152_table, ++ .generic_subclass = 1, ++ .supports_autosuspend = 1, ++}; ++ ++static int __init rtl8152_driver_init(void) ++{ ++ int ret; ++ ++ ret = usb_register_device_driver(&rtl8152_cfgselector_driver, THIS_MODULE); ++ if (ret) ++ return ret; ++ return usb_register(&rtl8152_driver); ++} ++ ++static void __exit rtl8152_driver_exit(void) ++{ ++ usb_deregister(&rtl8152_driver); ++ usb_deregister_device_driver(&rtl8152_cfgselector_driver); ++} ++ ++module_init(rtl8152_driver_init); ++module_exit(rtl8152_driver_exit); + + MODULE_AUTHOR(DRIVER_AUTHOR); + MODULE_DESCRIPTION(DRIVER_DESC); +diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c +index 9dfd3d0293054..69aef668f1056 100644 +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -834,6 +834,8 @@ static void nvme_queue_auth_work(struct work_struct *work) + } + + fail2: ++ if (chap->status == 0) ++ chap->status = NVME_AUTH_DHCHAP_FAILURE_FAILED; + dev_dbg(ctrl->device, "%s: qid %d send failure2, status %x\n", + __func__, chap->qid, chap->status); + tl = nvme_auth_set_dhchap_failure2_data(ctrl, chap); +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 5b156c5bc04a5..eb7c87b344b8f 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1845,16 +1845,18 @@ set_pi: + return ret; + } + +-static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) ++static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) + { + struct nvme_ctrl *ctrl = ns->ctrl; ++ int ret; + +- if (nvme_init_ms(ns, id)) +- return; ++ ret = nvme_init_ms(ns, id); ++ if (ret) ++ return ret; + + ns->features &= ~(NVME_NS_METADATA_SUPPORTED | NVME_NS_EXT_LBAS); + if (!ns->ms || !(ctrl->ops->flags & NVME_F_METADATA_SUPPORTED)) +- return; ++ return 0; + + if (ctrl->ops->flags & NVME_F_FABRICS) { + /* +@@ -1863,7 +1865,7 @@ static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) + * remap the separate metadata buffer from the block layer. + */ + if (WARN_ON_ONCE(!(id->flbas & NVME_NS_FLBAS_META_EXT))) +- return; ++ return 0; + + ns->features |= NVME_NS_EXT_LBAS; + +@@ -1890,6 +1892,7 @@ static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) + else + ns->features |= NVME_NS_METADATA_SUPPORTED; + } ++ return 0; + } + + static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, +@@ -2070,7 +2073,11 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns, + ns->lba_shift = id->lbaf[lbaf].ds; + nvme_set_queue_limits(ns->ctrl, ns->queue); + +- nvme_configure_metadata(ns, id); ++ ret = nvme_configure_metadata(ns, id); ++ if (ret < 0) { ++ blk_mq_unfreeze_queue(ns->disk->queue); ++ goto out; ++ } + nvme_set_chunk_sectors(ns, id); + nvme_update_disk_info(ns->disk, ns, id); + +diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c +index fe0f732f6e434..a860f25473df6 100644 +--- a/drivers/pci/controller/pci-loongson.c ++++ b/drivers/pci/controller/pci-loongson.c +@@ -80,13 +80,49 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_LPC, system_bus_quirk); + ++/* ++ * Some Loongson PCIe ports have hardware limitations on their Maximum Read ++ * Request Size. They can't handle anything larger than this. Sane ++ * firmware will set proper MRRS at boot, so we only need no_inc_mrrs for ++ * bridges. However, some MIPS Loongson firmware doesn't set MRRS properly, ++ * so we have to enforce maximum safe MRRS, which is 256 bytes. ++ */ ++#ifdef CONFIG_MIPS ++static void loongson_set_min_mrrs_quirk(struct pci_dev *pdev) ++{ ++ struct pci_bus *bus = pdev->bus; ++ struct pci_dev *bridge; ++ static const struct pci_device_id bridge_devids[] = { ++ { PCI_VDEVICE(LOONGSON, DEV_LS2K_PCIE_PORT0) }, ++ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT0) }, ++ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT1) }, ++ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT2) }, ++ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT3) }, ++ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT4) }, ++ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT5) }, ++ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT6) }, ++ { 0, }, ++ }; ++ ++ /* look for the matching bridge */ ++ while (!pci_is_root_bus(bus)) { ++ bridge = bus->self; ++ bus = bus->parent; ++ ++ if (pci_match_id(bridge_devids, bridge)) { ++ if (pcie_get_readrq(pdev) > 256) { ++ pci_info(pdev, "limiting MRRS to 256\n"); ++ pcie_set_readrq(pdev, 256); ++ } ++ break; ++ } ++ } ++} ++DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, loongson_set_min_mrrs_quirk); ++#endif ++ + static void loongson_mrrs_quirk(struct pci_dev *pdev) + { +- /* +- * Some Loongson PCIe ports have h/w limitations of maximum read +- * request size. They can't handle anything larger than this. So +- * force this limit on any devices attached under these ports. +- */ + struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus); + + bridge->no_inc_mrrs = 1; +diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c +index ea0195337bab9..6efa3d8db9a56 100644 +--- a/drivers/pci/hotplug/acpiphp_glue.c ++++ b/drivers/pci/hotplug/acpiphp_glue.c +@@ -504,15 +504,12 @@ static void enable_slot(struct acpiphp_slot *slot, bool bridge) + if (pass && dev->subordinate) { + check_hotplug_bridge(slot, dev); + pcibios_resource_survey_bus(dev->subordinate); +- if (pci_is_root_bus(bus)) +- __pci_bus_size_bridges(dev->subordinate, &add_list); ++ __pci_bus_size_bridges(dev->subordinate, ++ &add_list); + } + } + } +- if (pci_is_root_bus(bus)) +- __pci_bus_assign_resources(bus, &add_list, NULL); +- else +- pci_assign_unassigned_bridge_resources(bus->self); ++ __pci_bus_assign_resources(bus, &add_list, NULL); + } + + acpiphp_sanitize_bus(bus); +diff --git a/drivers/platform/x86/intel/telemetry/core.c b/drivers/platform/x86/intel/telemetry/core.c +index fdf55b5d69480..e4be40f73eebf 100644 +--- a/drivers/platform/x86/intel/telemetry/core.c ++++ b/drivers/platform/x86/intel/telemetry/core.c +@@ -102,7 +102,7 @@ static const struct telemetry_core_ops telm_defpltops = { + /** + * telemetry_update_events() - Update telemetry Configuration + * @pss_evtconfig: PSS related config. No change if num_evts = 0. +- * @pss_evtconfig: IOSS related config. No change if num_evts = 0. ++ * @ioss_evtconfig: IOSS related config. No change if num_evts = 0. + * + * This API updates the IOSS & PSS Telemetry configuration. Old config + * is overwritten. Call telemetry_reset_events when logging is over +@@ -176,7 +176,7 @@ EXPORT_SYMBOL_GPL(telemetry_reset_events); + /** + * telemetry_get_eventconfig() - Returns the pss and ioss events enabled + * @pss_evtconfig: Pointer to PSS related configuration. +- * @pss_evtconfig: Pointer to IOSS related configuration. ++ * @ioss_evtconfig: Pointer to IOSS related configuration. + * @pss_len: Number of u32 elements allocated for pss_evtconfig array + * @ioss_len: Number of u32 elements allocated for ioss_evtconfig array + * +diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c +index b10ea69a638e1..2624441d2fa92 100644 +--- a/drivers/soundwire/stream.c ++++ b/drivers/soundwire/stream.c +@@ -744,14 +744,15 @@ error_1: + * sdw_ml_sync_bank_switch: Multilink register bank switch + * + * @bus: SDW bus instance ++ * @multi_link: whether this is a multi-link stream with hardware-based sync + * + * Caller function should free the buffers on error + */ +-static int sdw_ml_sync_bank_switch(struct sdw_bus *bus) ++static int sdw_ml_sync_bank_switch(struct sdw_bus *bus, bool multi_link) + { + unsigned long time_left; + +- if (!bus->multi_link) ++ if (!multi_link) + return 0; + + /* Wait for completion of transfer */ +@@ -848,7 +849,7 @@ static int do_bank_switch(struct sdw_stream_runtime *stream) + bus->bank_switch_timeout = DEFAULT_BANK_SWITCH_TIMEOUT; + + /* Check if bank switch was successful */ +- ret = sdw_ml_sync_bank_switch(bus); ++ ret = sdw_ml_sync_bank_switch(bus, multi_link); + if (ret < 0) { + dev_err(bus->dev, + "multi link bank switch failed: %d\n", ret); +diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c +index 671ee8843c889..5703a9ddb6d0d 100644 +--- a/drivers/staging/gdm724x/gdm_lte.c ++++ b/drivers/staging/gdm724x/gdm_lte.c +@@ -349,7 +349,7 @@ static s32 gdm_lte_tx_nic_type(struct net_device *dev, struct sk_buff *skb) + /* Get ethernet protocol */ + eth = (struct ethhdr *)skb->data; + if (ntohs(eth->h_proto) == ETH_P_8021Q) { +- vlan_eth = (struct vlan_ethhdr *)skb->data; ++ vlan_eth = skb_vlan_eth_hdr(skb); + mac_proto = ntohs(vlan_eth->h_vlan_encapsulated_proto); + network_data = skb->data + VLAN_ETH_HLEN; + nic_type |= NIC_TYPE_F_VLAN; +@@ -435,7 +435,7 @@ static netdev_tx_t gdm_lte_tx(struct sk_buff *skb, struct net_device *dev) + * driver based on the NIC mac + */ + if (nic_type & NIC_TYPE_F_VLAN) { +- struct vlan_ethhdr *vlan_eth = (struct vlan_ethhdr *)skb->data; ++ struct vlan_ethhdr *vlan_eth = skb_vlan_eth_hdr(skb); + + nic->vlan_id = ntohs(vlan_eth->h_vlan_TCI) & VLAN_VID_MASK; + data_buf = skb->data + (VLAN_ETH_HLEN - ETH_HLEN); +diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c +index c62939e5ea1f0..37036db63aff3 100644 +--- a/fs/afs/rxrpc.c ++++ b/fs/afs/rxrpc.c +@@ -424,7 +424,7 @@ error_kill_call: + if (call->async) { + if (cancel_work_sync(&call->async_work)) + afs_put_call(call); +- afs_put_call(call); ++ afs_set_call_complete(call, ret, 0); + } + + ac->error = ret; +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index afcc96a1f4276..539bc9bdcb93f 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -3390,7 +3390,8 @@ static int try_release_extent_state(struct extent_io_tree *tree, + ret = 0; + } else { + u32 clear_bits = ~(EXTENT_LOCKED | EXTENT_NODATASUM | +- EXTENT_DELALLOC_NEW | EXTENT_CTLBITS); ++ EXTENT_DELALLOC_NEW | EXTENT_CTLBITS | ++ EXTENT_QGROUP_RESERVED); + + /* + * At this point we can safely clear everything except the +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index dc6e3cce747c1..e8e4781c48a50 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -2182,6 +2182,15 @@ static noinline int __btrfs_ioctl_snap_create(struct file *file, + * are limited to own subvolumes only + */ + ret = -EPERM; ++ } else if (btrfs_ino(BTRFS_I(src_inode)) != BTRFS_FIRST_FREE_OBJECTID) { ++ /* ++ * Snapshots must be made with the src_inode referring ++ * to the subvolume inode, otherwise the permission ++ * checking above is useless because we may have ++ * permission on a lower directory but not the subvol ++ * itself. ++ */ ++ ret = -EINVAL; + } else { + ret = btrfs_mksnapshot(&file->f_path, mnt_userns, + name, namelen, +diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c +index bd0c7157e3878..0321753c16b9f 100644 +--- a/fs/btrfs/ordered-data.c ++++ b/fs/btrfs/ordered-data.c +@@ -544,7 +544,9 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode, + release = entry->disk_num_bytes; + else + release = entry->num_bytes; +- btrfs_delalloc_release_metadata(btrfs_inode, release, false); ++ btrfs_delalloc_release_metadata(btrfs_inode, release, ++ test_bit(BTRFS_ORDERED_IOERR, ++ &entry->flags)); + } + + percpu_counter_add_batch(&fs_info->ordered_bytes, -entry->num_bytes, +diff --git a/fs/ext4/file.c b/fs/ext4/file.c +index 8ebe4dc7b0170..18f5fd2a163b0 100644 +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -339,9 +339,10 @@ static void ext4_inode_extension_cleanup(struct inode *inode, ssize_t count) + return; + } + /* +- * If i_disksize got extended due to writeback of delalloc blocks while +- * the DIO was running we could fail to cleanup the orphan list in +- * ext4_handle_inode_extension(). Do it now. ++ * If i_disksize got extended either due to writeback of delalloc ++ * blocks or extending truncate while the DIO was running we could fail ++ * to cleanup the orphan list in ext4_handle_inode_extension(). Do it ++ * now. + */ + if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) { + handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); +@@ -376,10 +377,11 @@ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size, + * blocks. But the code in ext4_iomap_alloc() is careful to use + * zeroed/unwritten extents if this is possible; thus we won't leave + * uninitialized blocks in a file even if we didn't succeed in writing +- * as much as we intended. ++ * as much as we intended. Also we can race with truncate or write ++ * expanding the file so we have to be a bit careful here. + */ +- WARN_ON_ONCE(i_size_read(inode) < READ_ONCE(EXT4_I(inode)->i_disksize)); +- if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize)) ++ if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize) && ++ pos + size <= i_size_read(inode)) + return size; + return ext4_handle_inode_extension(inode, pos, size); + } +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 6ea6b7105fe35..a6e41746890d4 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -4110,6 +4110,10 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, + start = max(start, rounddown(ac->ac_o_ex.fe_logical, + (ext4_lblk_t)EXT4_BLOCKS_PER_GROUP(ac->ac_sb))); + ++ /* avoid unnecessary preallocation that may trigger assertions */ ++ if (start + size > EXT_MAX_BLOCKS) ++ size = EXT_MAX_BLOCKS - start; ++ + /* don't cover already allocated blocks in selected range */ + if (ar->pleft && start <= ar->lleft) { + size -= ar->lleft + 1 - start; +diff --git a/fs/fuse/dax.c b/fs/fuse/dax.c +index e23e802a80130..6e71904c396f1 100644 +--- a/fs/fuse/dax.c ++++ b/fs/fuse/dax.c +@@ -1224,6 +1224,7 @@ void fuse_dax_conn_free(struct fuse_conn *fc) + if (fc->dax) { + fuse_free_dax_mem_ranges(&fc->dax->free_ranges); + kfree(fc->dax); ++ fc->dax = NULL; + } + } + +diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c +index eaa5bd148810a..88942b1fb4318 100644 +--- a/fs/smb/client/smb2misc.c ++++ b/fs/smb/client/smb2misc.c +@@ -313,6 +313,9 @@ static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = { + char * + smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr) + { ++ const int max_off = 4096; ++ const int max_len = 128 * 1024; ++ + *off = 0; + *len = 0; + +@@ -384,29 +387,20 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr) + * Invalid length or offset probably means data area is invalid, but + * we have little choice but to ignore the data area in this case. + */ +- if (*off > 4096) { +- cifs_dbg(VFS, "offset %d too large, data area ignored\n", *off); +- *len = 0; +- *off = 0; +- } else if (*off < 0) { +- cifs_dbg(VFS, "negative offset %d to data invalid ignore data area\n", +- *off); ++ if (unlikely(*off < 0 || *off > max_off || ++ *len < 0 || *len > max_len)) { ++ cifs_dbg(VFS, "%s: invalid data area (off=%d len=%d)\n", ++ __func__, *off, *len); + *off = 0; + *len = 0; +- } else if (*len < 0) { +- cifs_dbg(VFS, "negative data length %d invalid, data area ignored\n", +- *len); +- *len = 0; +- } else if (*len > 128 * 1024) { +- cifs_dbg(VFS, "data area larger than 128K: %d\n", *len); ++ } else if (*off == 0) { + *len = 0; + } + + /* return pointer to beginning of data area, ie offset from SMB start */ +- if ((*off != 0) && (*len != 0)) ++ if (*off > 0 && *len > 0) + return (char *)shdr + *off; +- else +- return NULL; ++ return NULL; + } + + /* +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index 6ef3c00de5ca1..1b3489a2f0db7 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -3122,7 +3122,7 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, + struct kvec close_iov[1]; + struct smb2_ioctl_rsp *ioctl_rsp; + struct reparse_data_buffer *reparse_buf; +- u32 plen; ++ u32 off, count, len; + + cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); + +@@ -3202,16 +3202,22 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, + */ + if (rc == 0) { + /* See MS-FSCC 2.3.23 */ ++ off = le32_to_cpu(ioctl_rsp->OutputOffset); ++ count = le32_to_cpu(ioctl_rsp->OutputCount); ++ if (check_add_overflow(off, count, &len) || ++ len > rsp_iov[1].iov_len) { ++ cifs_tcon_dbg(VFS, "%s: invalid ioctl: off=%d count=%d\n", ++ __func__, off, count); ++ rc = -EIO; ++ goto query_rp_exit; ++ } + +- reparse_buf = (struct reparse_data_buffer *) +- ((char *)ioctl_rsp + +- le32_to_cpu(ioctl_rsp->OutputOffset)); +- plen = le32_to_cpu(ioctl_rsp->OutputCount); +- +- if (plen + le32_to_cpu(ioctl_rsp->OutputOffset) > +- rsp_iov[1].iov_len) { +- cifs_tcon_dbg(FYI, "srv returned invalid ioctl len: %d\n", +- plen); ++ reparse_buf = (void *)((u8 *)ioctl_rsp + off); ++ len = sizeof(*reparse_buf); ++ if (count < len || ++ count < le16_to_cpu(reparse_buf->ReparseDataLength) + len) { ++ cifs_tcon_dbg(VFS, "%s: invalid ioctl: off=%d count=%d\n", ++ __func__, off, count); + rc = -EIO; + goto query_rp_exit; + } +@@ -5065,6 +5071,7 @@ receive_encrypted_standard(struct TCP_Server_Info *server, + struct smb2_hdr *shdr; + unsigned int pdu_length = server->pdu_size; + unsigned int buf_size; ++ unsigned int next_cmd; + struct mid_q_entry *mid_entry; + int next_is_large; + char *next_buffer = NULL; +@@ -5093,14 +5100,15 @@ receive_encrypted_standard(struct TCP_Server_Info *server, + next_is_large = server->large_buf; + one_more: + shdr = (struct smb2_hdr *)buf; +- if (shdr->NextCommand) { ++ next_cmd = le32_to_cpu(shdr->NextCommand); ++ if (next_cmd) { ++ if (WARN_ON_ONCE(next_cmd > pdu_length)) ++ return -1; + if (next_is_large) + next_buffer = (char *)cifs_buf_get(); + else + next_buffer = (char *)cifs_small_buf_get(); +- memcpy(next_buffer, +- buf + le32_to_cpu(shdr->NextCommand), +- pdu_length - le32_to_cpu(shdr->NextCommand)); ++ memcpy(next_buffer, buf + next_cmd, pdu_length - next_cmd); + } + + mid_entry = smb2_find_mid(server, buf); +@@ -5124,8 +5132,8 @@ one_more: + else + ret = cifs_handle_standard(server, mid_entry); + +- if (ret == 0 && shdr->NextCommand) { +- pdu_length -= le32_to_cpu(shdr->NextCommand); ++ if (ret == 0 && next_cmd) { ++ pdu_length -= next_cmd; + server->large_buf = next_is_large; + if (next_is_large) + server->bigbuf = buf = next_buffer; +diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h +index 9619015d78f29..c8a4014f9d395 100644 +--- a/fs/smb/common/smb2pdu.h ++++ b/fs/smb/common/smb2pdu.h +@@ -1116,7 +1116,7 @@ struct smb2_change_notify_rsp { + #define SMB2_CREATE_SD_BUFFER "SecD" /* security descriptor */ + #define SMB2_CREATE_DURABLE_HANDLE_REQUEST "DHnQ" + #define SMB2_CREATE_DURABLE_HANDLE_RECONNECT "DHnC" +-#define SMB2_CREATE_ALLOCATION_SIZE "AISi" ++#define SMB2_CREATE_ALLOCATION_SIZE "AlSi" + #define SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST "MxAc" + #define SMB2_CREATE_TIMEWARP_REQUEST "TWrp" + #define SMB2_CREATE_QUERY_ON_DISK_ID "QFid" +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index 683152007566c..1598ad6155fef 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -7135,6 +7135,7 @@ skip: + smb2_remove_blocked_lock, + argv); + if (rc) { ++ kfree(argv); + err = -ENOMEM; + goto out; + } +diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h +index 995513fa26904..0655aa5b57b29 100644 +--- a/include/asm-generic/qspinlock.h ++++ b/include/asm-generic/qspinlock.h +@@ -70,7 +70,7 @@ static __always_inline int queued_spin_is_locked(struct qspinlock *lock) + */ + static __always_inline int queued_spin_value_unlocked(struct qspinlock lock) + { +- return !atomic_read(&lock.val); ++ return !lock.val.counter; + } + + /** +diff --git a/include/linux/cred.h b/include/linux/cred.h +index 9ed9232af9340..09c1ed9242b4a 100644 +--- a/include/linux/cred.h ++++ b/include/linux/cred.h +@@ -108,7 +108,7 @@ static inline int groups_search(const struct group_info *group_info, kgid_t grp) + * same context as task->real_cred. + */ + struct cred { +- atomic_t usage; ++ atomic_long_t usage; + #ifdef CONFIG_DEBUG_CREDENTIALS + atomic_t subscribers; /* number of processes subscribed */ + void *put_addr; +@@ -228,7 +228,7 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred) + */ + static inline struct cred *get_new_cred(struct cred *cred) + { +- atomic_inc(&cred->usage); ++ atomic_long_inc(&cred->usage); + return cred; + } + +@@ -260,7 +260,7 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred) + struct cred *nonconst_cred = (struct cred *) cred; + if (!cred) + return NULL; +- if (!atomic_inc_not_zero(&nonconst_cred->usage)) ++ if (!atomic_long_inc_not_zero(&nonconst_cred->usage)) + return NULL; + validate_creds(cred); + nonconst_cred->non_rcu = 0; +@@ -284,7 +284,7 @@ static inline void put_cred(const struct cred *_cred) + + if (cred) { + validate_creds(cred); +- if (atomic_dec_and_test(&(cred)->usage)) ++ if (atomic_long_dec_and_test(&(cred)->usage)) + __put_cred(cred); + } + } +diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h +index 68b1c41332984..e0d0a645be7cf 100644 +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -62,6 +62,14 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb) + return (struct vlan_ethhdr *)skb_mac_header(skb); + } + ++/* Prefer this version in TX path, instead of ++ * skb_reset_mac_header() + vlan_eth_hdr() ++ */ ++static inline struct vlan_ethhdr *skb_vlan_eth_hdr(const struct sk_buff *skb) ++{ ++ return (struct vlan_ethhdr *)skb->data; ++} ++ + #define VLAN_PRIO_MASK 0xe000 /* Priority Code Point */ + #define VLAN_PRIO_SHIFT 13 + #define VLAN_CFI_MASK 0x1000 /* Canonical Format Indicator / Drop Eligible Indicator */ +@@ -531,7 +539,7 @@ static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb, + */ + static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) + { +- struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data; ++ struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb); + + if (!eth_type_vlan(veth->h_vlan_proto)) + return -EINVAL; +@@ -732,7 +740,7 @@ static inline bool skb_vlan_tagged_multi(struct sk_buff *skb) + if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN))) + return false; + +- veh = (struct vlan_ethhdr *)skb->data; ++ veh = skb_vlan_eth_hdr(skb); + protocol = veh->h_vlan_encapsulated_proto; + } + +diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h +index 4ef6c09cc2eec..c21e19a1514d1 100644 +--- a/include/linux/mm_inline.h ++++ b/include/linux/mm_inline.h +@@ -231,22 +231,27 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, + if (folio_test_unevictable(folio) || !lrugen->enabled) + return false; + /* +- * There are three common cases for this page: +- * 1. If it's hot, e.g., freshly faulted in or previously hot and +- * migrated, add it to the youngest generation. +- * 2. If it's cold but can't be evicted immediately, i.e., an anon page +- * not in swapcache or a dirty page pending writeback, add it to the +- * second oldest generation. +- * 3. Everything else (clean, cold) is added to the oldest generation. ++ * There are four common cases for this page: ++ * 1. If it's hot, i.e., freshly faulted in, add it to the youngest ++ * generation, and it's protected over the rest below. ++ * 2. If it can't be evicted immediately, i.e., a dirty page pending ++ * writeback, add it to the second youngest generation. ++ * 3. If it should be evicted first, e.g., cold and clean from ++ * folio_rotate_reclaimable(), add it to the oldest generation. ++ * 4. Everything else falls between 2 & 3 above and is added to the ++ * second oldest generation if it's considered inactive, or the ++ * oldest generation otherwise. See lru_gen_is_active(). + */ + if (folio_test_active(folio)) + seq = lrugen->max_seq; + else if ((type == LRU_GEN_ANON && !folio_test_swapcache(folio)) || + (folio_test_reclaim(folio) && + (folio_test_dirty(folio) || folio_test_writeback(folio)))) +- seq = lrugen->min_seq[type] + 1; +- else ++ seq = lrugen->max_seq - 1; ++ else if (reclaiming || lrugen->min_seq[type] + MIN_NR_GENS >= lrugen->max_seq) + seq = lrugen->min_seq[type]; ++ else ++ seq = lrugen->min_seq[type] + 1; + + gen = lru_gen_from_seq(seq); + flags = (gen + 1UL) << LRU_GEN_PGOFF; +diff --git a/include/linux/usb/r8152.h b/include/linux/usb/r8152.h +index 20d88b1defc30..33a4c146dc19c 100644 +--- a/include/linux/usb/r8152.h ++++ b/include/linux/usb/r8152.h +@@ -29,6 +29,8 @@ + #define VENDOR_ID_LINKSYS 0x13b1 + #define VENDOR_ID_NVIDIA 0x0955 + #define VENDOR_ID_TPLINK 0x2357 ++#define VENDOR_ID_DLINK 0x2001 ++#define VENDOR_ID_ASUS 0x0b05 + + #if IS_REACHABLE(CONFIG_USB_RTL8152) + extern u8 rtl8152_get_version(struct usb_interface *intf); +diff --git a/include/net/addrconf.h b/include/net/addrconf.h +index c04f359655b86..86eb2aba1479c 100644 +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -31,17 +31,22 @@ struct prefix_info { + __u8 length; + __u8 prefix_len; + ++ union __packed { ++ __u8 flags; ++ struct __packed { + #if defined(__BIG_ENDIAN_BITFIELD) +- __u8 onlink : 1, ++ __u8 onlink : 1, + autoconf : 1, + reserved : 6; + #elif defined(__LITTLE_ENDIAN_BITFIELD) +- __u8 reserved : 6, ++ __u8 reserved : 6, + autoconf : 1, + onlink : 1; + #else + #error "Please fix " + #endif ++ }; ++ }; + __be32 valid; + __be32 prefered; + __be32 reserved2; +@@ -49,6 +54,9 @@ struct prefix_info { + struct in6_addr prefix; + }; + ++/* rfc4861 4.6.2: IPv6 PIO is 32 bytes in size */ ++static_assert(sizeof(struct prefix_info) == 32); ++ + #include + #include + #include +diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h +index c8490729b4aea..31bf475eca762 100644 +--- a/include/net/if_inet6.h ++++ b/include/net/if_inet6.h +@@ -22,10 +22,6 @@ + #define IF_RS_SENT 0x10 + #define IF_READY 0x80000000 + +-/* prefix flags */ +-#define IF_PREFIX_ONLINK 0x01 +-#define IF_PREFIX_AUTOCONF 0x02 +- + enum { + INET6_IFADDR_STATE_PREDAD, + INET6_IFADDR_STATE_DAD, +diff --git a/kernel/cred.c b/kernel/cred.c +index e10c15f51c1fe..d35bc0aa98cba 100644 +--- a/kernel/cred.c ++++ b/kernel/cred.c +@@ -99,17 +99,17 @@ static void put_cred_rcu(struct rcu_head *rcu) + + #ifdef CONFIG_DEBUG_CREDENTIALS + if (cred->magic != CRED_MAGIC_DEAD || +- atomic_read(&cred->usage) != 0 || ++ atomic_long_read(&cred->usage) != 0 || + read_cred_subscribers(cred) != 0) + panic("CRED: put_cred_rcu() sees %p with" +- " mag %x, put %p, usage %d, subscr %d\n", ++ " mag %x, put %p, usage %ld, subscr %d\n", + cred, cred->magic, cred->put_addr, +- atomic_read(&cred->usage), ++ atomic_long_read(&cred->usage), + read_cred_subscribers(cred)); + #else +- if (atomic_read(&cred->usage) != 0) +- panic("CRED: put_cred_rcu() sees %p with usage %d\n", +- cred, atomic_read(&cred->usage)); ++ if (atomic_long_read(&cred->usage) != 0) ++ panic("CRED: put_cred_rcu() sees %p with usage %ld\n", ++ cred, atomic_long_read(&cred->usage)); + #endif + + security_cred_free(cred); +@@ -134,11 +134,11 @@ static void put_cred_rcu(struct rcu_head *rcu) + */ + void __put_cred(struct cred *cred) + { +- kdebug("__put_cred(%p{%d,%d})", cred, +- atomic_read(&cred->usage), ++ kdebug("__put_cred(%p{%ld,%d})", cred, ++ atomic_long_read(&cred->usage), + read_cred_subscribers(cred)); + +- BUG_ON(atomic_read(&cred->usage) != 0); ++ BUG_ON(atomic_long_read(&cred->usage) != 0); + #ifdef CONFIG_DEBUG_CREDENTIALS + BUG_ON(read_cred_subscribers(cred) != 0); + cred->magic = CRED_MAGIC_DEAD; +@@ -161,8 +161,8 @@ void exit_creds(struct task_struct *tsk) + { + struct cred *cred; + +- kdebug("exit_creds(%u,%p,%p,{%d,%d})", tsk->pid, tsk->real_cred, tsk->cred, +- atomic_read(&tsk->cred->usage), ++ kdebug("exit_creds(%u,%p,%p,{%ld,%d})", tsk->pid, tsk->real_cred, tsk->cred, ++ atomic_long_read(&tsk->cred->usage), + read_cred_subscribers(tsk->cred)); + + cred = (struct cred *) tsk->real_cred; +@@ -221,7 +221,7 @@ struct cred *cred_alloc_blank(void) + if (!new) + return NULL; + +- atomic_set(&new->usage, 1); ++ atomic_long_set(&new->usage, 1); + #ifdef CONFIG_DEBUG_CREDENTIALS + new->magic = CRED_MAGIC; + #endif +@@ -267,7 +267,7 @@ struct cred *prepare_creds(void) + memcpy(new, old, sizeof(struct cred)); + + new->non_rcu = 0; +- atomic_set(&new->usage, 1); ++ atomic_long_set(&new->usage, 1); + set_cred_subscribers(new, 0); + get_group_info(new->group_info); + get_uid(new->user); +@@ -355,8 +355,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) + p->real_cred = get_cred(p->cred); + get_cred(p->cred); + alter_cred_subscribers(p->cred, 2); +- kdebug("share_creds(%p{%d,%d})", +- p->cred, atomic_read(&p->cred->usage), ++ kdebug("share_creds(%p{%ld,%d})", ++ p->cred, atomic_long_read(&p->cred->usage), + read_cred_subscribers(p->cred)); + inc_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1); + return 0; +@@ -449,8 +449,8 @@ int commit_creds(struct cred *new) + struct task_struct *task = current; + const struct cred *old = task->real_cred; + +- kdebug("commit_creds(%p{%d,%d})", new, +- atomic_read(&new->usage), ++ kdebug("commit_creds(%p{%ld,%d})", new, ++ atomic_long_read(&new->usage), + read_cred_subscribers(new)); + + BUG_ON(task->cred != old); +@@ -459,7 +459,7 @@ int commit_creds(struct cred *new) + validate_creds(old); + validate_creds(new); + #endif +- BUG_ON(atomic_read(&new->usage) < 1); ++ BUG_ON(atomic_long_read(&new->usage) < 1); + + get_cred(new); /* we will require a ref for the subj creds too */ + +@@ -532,14 +532,14 @@ EXPORT_SYMBOL(commit_creds); + */ + void abort_creds(struct cred *new) + { +- kdebug("abort_creds(%p{%d,%d})", new, +- atomic_read(&new->usage), ++ kdebug("abort_creds(%p{%ld,%d})", new, ++ atomic_long_read(&new->usage), + read_cred_subscribers(new)); + + #ifdef CONFIG_DEBUG_CREDENTIALS + BUG_ON(read_cred_subscribers(new) != 0); + #endif +- BUG_ON(atomic_read(&new->usage) < 1); ++ BUG_ON(atomic_long_read(&new->usage) < 1); + put_cred(new); + } + EXPORT_SYMBOL(abort_creds); +@@ -555,8 +555,8 @@ const struct cred *override_creds(const struct cred *new) + { + const struct cred *old = current->cred; + +- kdebug("override_creds(%p{%d,%d})", new, +- atomic_read(&new->usage), ++ kdebug("override_creds(%p{%ld,%d})", new, ++ atomic_long_read(&new->usage), + read_cred_subscribers(new)); + + validate_creds(old); +@@ -578,8 +578,8 @@ const struct cred *override_creds(const struct cred *new) + rcu_assign_pointer(current->cred, new); + alter_cred_subscribers(old, -1); + +- kdebug("override_creds() = %p{%d,%d}", old, +- atomic_read(&old->usage), ++ kdebug("override_creds() = %p{%ld,%d}", old, ++ atomic_long_read(&old->usage), + read_cred_subscribers(old)); + return old; + } +@@ -596,8 +596,8 @@ void revert_creds(const struct cred *old) + { + const struct cred *override = current->cred; + +- kdebug("revert_creds(%p{%d,%d})", old, +- atomic_read(&old->usage), ++ kdebug("revert_creds(%p{%ld,%d})", old, ++ atomic_long_read(&old->usage), + read_cred_subscribers(old)); + + validate_creds(old); +@@ -729,7 +729,7 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) + + *new = *old; + new->non_rcu = 0; +- atomic_set(&new->usage, 1); ++ atomic_long_set(&new->usage, 1); + set_cred_subscribers(new, 0); + get_uid(new->user); + get_user_ns(new->user_ns); +@@ -843,8 +843,8 @@ static void dump_invalid_creds(const struct cred *cred, const char *label, + cred == tsk->cred ? "[eff]" : ""); + printk(KERN_ERR "CRED: ->magic=%x, put_addr=%p\n", + cred->magic, cred->put_addr); +- printk(KERN_ERR "CRED: ->usage=%d, subscr=%d\n", +- atomic_read(&cred->usage), ++ printk(KERN_ERR "CRED: ->usage=%ld, subscr=%d\n", ++ atomic_long_read(&cred->usage), + read_cred_subscribers(cred)); + printk(KERN_ERR "CRED: ->*uid = { %d,%d,%d,%d }\n", + from_kuid_munged(&init_user_ns, cred->uid), +@@ -916,9 +916,9 @@ EXPORT_SYMBOL(__validate_process_creds); + */ + void validate_creds_for_do_exit(struct task_struct *tsk) + { +- kdebug("validate_creds_for_do_exit(%p,%p{%d,%d})", ++ kdebug("validate_creds_for_do_exit(%p,%p{%ld,%d})", + tsk->real_cred, tsk->cred, +- atomic_read(&tsk->cred->usage), ++ atomic_long_read(&tsk->cred->usage), + read_cred_subscribers(tsk->cred)); + + __validate_process_creds(tsk, __FILE__, __LINE__); +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 0193243f65e5c..8c7d2f4f5fbab 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -1945,6 +1945,16 @@ static bool perf_event_validate_size(struct perf_event *event) + group_leader->nr_siblings + 1) > 16*1024) + return false; + ++ /* ++ * When creating a new group leader, group_leader->ctx is initialized ++ * after the size has been validated, but we cannot safely use ++ * for_each_sibling_event() until group_leader->ctx is set. A new group ++ * leader cannot have any siblings yet, so we can safely skip checking ++ * the non-existent siblings. ++ */ ++ if (event == group_leader) ++ return true; ++ + for_each_sibling_event(sibling, group_leader) { + if (__perf_event_read_size(sibling->attr.read_format, + group_leader->nr_siblings + 1) > 16*1024) +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index c02a4cb879913..61803208706a5 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -711,6 +711,9 @@ static int rb_time_cmpxchg(rb_time_t *t, u64 expect, u64 set) + unsigned long cnt2, top2, bottom2, msb2; + u64 val; + ++ /* Any interruptions in this function should cause a failure */ ++ cnt = local_read(&t->cnt); ++ + /* The cmpxchg always fails if it interrupted an update */ + if (!__rb_time_read(t, &val, &cnt2)) + return false; +@@ -718,17 +721,18 @@ static int rb_time_cmpxchg(rb_time_t *t, u64 expect, u64 set) + if (val != expect) + return false; + +- cnt = local_read(&t->cnt); + if ((cnt & 3) != cnt2) + return false; + + cnt2 = cnt + 1; + + rb_time_split(val, &top, &bottom, &msb); ++ msb = rb_time_val_cnt(msb, cnt); + top = rb_time_val_cnt(top, cnt); + bottom = rb_time_val_cnt(bottom, cnt); + + rb_time_split(set, &top2, &bottom2, &msb2); ++ msb2 = rb_time_val_cnt(msb2, cnt); + top2 = rb_time_val_cnt(top2, cnt2); + bottom2 = rb_time_val_cnt(bottom2, cnt2); + +@@ -1801,6 +1805,8 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer) + free_buffer_page(bpage); + } + ++ free_page((unsigned long)cpu_buffer->free_page); ++ + kfree(cpu_buffer); + } + +@@ -2401,7 +2407,7 @@ rb_iter_head_event(struct ring_buffer_iter *iter) + */ + barrier(); + +- if ((iter->head + length) > commit || length > BUF_MAX_DATA_SIZE) ++ if ((iter->head + length) > commit || length > BUF_PAGE_SIZE) + /* Writer corrupted the read? */ + goto reset; + +@@ -3576,7 +3582,10 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, + * absolute timestamp. + * Don't bother if this is the start of a new page (w == 0). + */ +- if (unlikely(!a_ok || !b_ok || (info->before != info->after && w))) { ++ if (!w) { ++ /* Use the sub-buffer timestamp */ ++ info->delta = 0; ++ } else if (unlikely(!a_ok || !b_ok || info->before != info->after)) { + info->add_timestamp |= RB_ADD_STAMP_FORCE | RB_ADD_STAMP_EXTEND; + info->length += RB_LEN_TIME_EXTEND; + } else { +@@ -3599,26 +3608,19 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, + + /* See if we shot pass the end of this buffer page */ + if (unlikely(write > BUF_PAGE_SIZE)) { +- /* before and after may now different, fix it up*/ +- b_ok = rb_time_read(&cpu_buffer->before_stamp, &info->before); +- a_ok = rb_time_read(&cpu_buffer->write_stamp, &info->after); +- if (a_ok && b_ok && info->before != info->after) +- (void)rb_time_cmpxchg(&cpu_buffer->before_stamp, +- info->before, info->after); +- if (a_ok && b_ok) +- check_buffer(cpu_buffer, info, CHECK_FULL_PAGE); ++ check_buffer(cpu_buffer, info, CHECK_FULL_PAGE); + return rb_move_tail(cpu_buffer, tail, info); + } + + if (likely(tail == w)) { +- u64 save_before; +- bool s_ok; +- + /* Nothing interrupted us between A and C */ + /*D*/ rb_time_set(&cpu_buffer->write_stamp, info->ts); +- barrier(); +- /*E*/ s_ok = rb_time_read(&cpu_buffer->before_stamp, &save_before); +- RB_WARN_ON(cpu_buffer, !s_ok); ++ /* ++ * If something came in between C and D, the write stamp ++ * may now not be in sync. But that's fine as the before_stamp ++ * will be different and then next event will just be forced ++ * to use an absolute timestamp. ++ */ + if (likely(!(info->add_timestamp & + (RB_ADD_STAMP_FORCE | RB_ADD_STAMP_ABSOLUTE)))) + /* This did not interrupt any time update */ +@@ -3626,24 +3628,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, + else + /* Just use full timestamp for interrupting event */ + info->delta = info->ts; +- barrier(); + check_buffer(cpu_buffer, info, tail); +- if (unlikely(info->ts != save_before)) { +- /* SLOW PATH - Interrupted between C and E */ +- +- a_ok = rb_time_read(&cpu_buffer->write_stamp, &info->after); +- RB_WARN_ON(cpu_buffer, !a_ok); +- +- /* Write stamp must only go forward */ +- if (save_before > info->after) { +- /* +- * We do not care about the result, only that +- * it gets updated atomically. +- */ +- (void)rb_time_cmpxchg(&cpu_buffer->write_stamp, +- info->after, save_before); +- } +- } + } else { + u64 ts; + /* SLOW PATH - Interrupted between A and C */ +@@ -3734,6 +3719,8 @@ rb_reserve_next_event(struct trace_buffer *buffer, + if (ring_buffer_time_stamp_abs(cpu_buffer->buffer)) { + add_ts_default = RB_ADD_STAMP_ABSOLUTE; + info.length += RB_LEN_TIME_EXTEND; ++ if (info.length > BUF_MAX_DATA_SIZE) ++ goto out_fail; + } else { + add_ts_default = RB_ADD_STAMP_NONE; + } +@@ -5118,7 +5105,8 @@ ring_buffer_read_prepare(struct trace_buffer *buffer, int cpu, gfp_t flags) + if (!iter) + return NULL; + +- iter->event = kmalloc(BUF_MAX_DATA_SIZE, flags); ++ /* Holds the entire event: data and meta data */ ++ iter->event = kmalloc(BUF_PAGE_SIZE, flags); + if (!iter->event) { + kfree(iter); + return NULL; +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index d2db4d6f0f2fd..87eca95b57fb3 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -6268,7 +6268,7 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, + if (!tr->array_buffer.buffer) + return 0; + +- /* Do not allow tracing while resizng ring buffer */ ++ /* Do not allow tracing while resizing ring buffer */ + tracing_stop_tr(tr); + + ret = ring_buffer_resize(tr->array_buffer.buffer, size, cpu); +@@ -6276,7 +6276,7 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, + goto out_start; + + #ifdef CONFIG_TRACER_MAX_TRACE +- if (!tr->current_trace->use_max_tr) ++ if (!tr->allocated_snapshot) + goto out; + + ret = ring_buffer_resize(tr->max_buffer.buffer, size, cpu); +diff --git a/mm/shmem.c b/mm/shmem.c +index 806741bbe4a68..f7c08e169e423 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -1024,7 +1024,24 @@ whole_folios: + } + VM_BUG_ON_FOLIO(folio_test_writeback(folio), + folio); +- truncate_inode_folio(mapping, folio); ++ ++ if (!folio_test_large(folio)) { ++ truncate_inode_folio(mapping, folio); ++ } else if (truncate_inode_partial_folio(folio, lstart, lend)) { ++ /* ++ * If we split a page, reset the loop so ++ * that we pick up the new sub pages. ++ * Otherwise the THP was entirely ++ * dropped or the target range was ++ * zeroed, so just continue the loop as ++ * is. ++ */ ++ if (!folio_test_large(folio)) { ++ folio_unlock(folio); ++ index = start; ++ break; ++ } ++ } + } + index = folio->index + folio_nr_pages(folio) - 1; + folio_unlock(folio); +diff --git a/mm/vmscan.c b/mm/vmscan.c +index 93d6f27dd40b4..3f090faa6377f 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -4770,7 +4770,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c + } + + /* protected */ +- if (tier > tier_idx) { ++ if (tier > tier_idx || refs == BIT(LRU_REFS_WIDTH)) { + int hist = lru_hist_from_seq(lrugen->min_seq[type]); + + gen = folio_inc_gen(lruvec, folio, false); +diff --git a/mm/workingset.c b/mm/workingset.c +index ae7e984b23c6b..6e4699055ed37 100644 +--- a/mm/workingset.c ++++ b/mm/workingset.c +@@ -289,10 +289,10 @@ static void lru_gen_refault(struct folio *folio, void *shadow) + * 1. For pages accessed through page tables, hotter pages pushed out + * hot pages which refaulted immediately. + * 2. For pages accessed multiple times through file descriptors, +- * numbers of accesses might have been out of the range. ++ * they would have been protected by sort_folio(). + */ +- if (lru_gen_in_fault() || refs == BIT(LRU_REFS_WIDTH)) { +- folio_set_workingset(folio); ++ if (lru_gen_in_fault() || refs >= BIT(LRU_REFS_WIDTH) - 1) { ++ set_mask_bits(&folio->flags, 0, LRU_REFS_MASK | BIT(PG_workingset)); + mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + type, delta); + } + unlock: +diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c +index a06f4d4a6f476..f67f14db16334 100644 +--- a/net/appletalk/ddp.c ++++ b/net/appletalk/ddp.c +@@ -1811,15 +1811,14 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) + break; + } + case TIOCINQ: { +- /* +- * These two are safe on a single CPU system as only +- * user tasks fiddle here +- */ +- struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); ++ struct sk_buff *skb; + long amount = 0; + ++ spin_lock_irq(&sk->sk_receive_queue.lock); ++ skb = skb_peek(&sk->sk_receive_queue); + if (skb) + amount = skb->len - sizeof(struct ddpehdr); ++ spin_unlock_irq(&sk->sk_receive_queue.lock); + rc = put_user(amount, (int __user *)argp); + break; + } +diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c +index 838ebf0cabbfb..f81f8d56f5c0c 100644 +--- a/net/atm/ioctl.c ++++ b/net/atm/ioctl.c +@@ -73,14 +73,17 @@ static int do_vcc_ioctl(struct socket *sock, unsigned int cmd, + case SIOCINQ: + { + struct sk_buff *skb; ++ int amount; + + if (sock->state != SS_CONNECTED) { + error = -EINVAL; + goto done; + } ++ spin_lock_irq(&sk->sk_receive_queue.lock); + skb = skb_peek(&sk->sk_receive_queue); +- error = put_user(skb ? skb->len : 0, +- (int __user *)argp) ? -EFAULT : 0; ++ amount = skb ? skb->len : 0; ++ spin_unlock_irq(&sk->sk_receive_queue.lock); ++ error = put_user(amount, (int __user *)argp) ? -EFAULT : 0; + goto done; + } + case ATM_SETSC: +diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c +index 38d411a52f331..d7b525a495e45 100644 +--- a/net/batman-adv/soft-interface.c ++++ b/net/batman-adv/soft-interface.c +@@ -444,7 +444,7 @@ void batadv_interface_rx(struct net_device *soft_iface, + if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) + goto dropped; + +- vhdr = (struct vlan_ethhdr *)skb->data; ++ vhdr = skb_vlan_eth_hdr(skb); + + /* drop batman-in-batman packets to prevent loops */ + if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 5b93d1ed1ed19..67087da45a1f7 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -3210,7 +3210,13 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) + if (skb_still_in_host_queue(sk, skb)) + return -EBUSY; + ++start: + if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) { ++ if (unlikely(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)) { ++ TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_SYN; ++ TCP_SKB_CB(skb)->seq++; ++ goto start; ++ } + if (unlikely(before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))) { + WARN_ON_ONCE(1); + return -EINVAL; +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index c63ccd39fc552..b8dc20fe7a4e2 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -6105,11 +6105,7 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, + pmsg->prefix_len = pinfo->prefix_len; + pmsg->prefix_type = pinfo->type; + pmsg->prefix_pad3 = 0; +- pmsg->prefix_flags = 0; +- if (pinfo->onlink) +- pmsg->prefix_flags |= IF_PREFIX_ONLINK; +- if (pinfo->autoconf) +- pmsg->prefix_flags |= IF_PREFIX_AUTOCONF; ++ pmsg->prefix_flags = pinfo->flags; + + if (nla_put(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix)) + goto nla_put_failure; +diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c +index ca2b17f32670d..674937284b8d2 100644 +--- a/net/rose/af_rose.c ++++ b/net/rose/af_rose.c +@@ -1315,9 +1315,11 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) + case TIOCINQ: { + struct sk_buff *skb; + long amount = 0L; +- /* These two are safe on a single CPU system as only user tasks fiddle here */ ++ ++ spin_lock_irq(&sk->sk_receive_queue.lock); + if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) + amount = skb->len; ++ spin_unlock_irq(&sk->sk_receive_queue.lock); + return put_user(amount, (unsigned int __user *) argp); + } + +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index 2e60bf06adff0..0323040d34bc6 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -1225,6 +1225,8 @@ alloc_payload: + } + + sk_msg_page_add(msg_pl, page, copy, offset); ++ msg_pl->sg.copybreak = 0; ++ msg_pl->sg.curr = msg_pl->sg.end; + sk_mem_charge(sk, copy); + + offset += copy; +diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c +index 79e79fd6efd19..2e25890ca52d1 100644 +--- a/net/vmw_vsock/virtio_transport_common.c ++++ b/net/vmw_vsock/virtio_transport_common.c +@@ -583,7 +583,7 @@ static s64 virtio_transport_has_space(struct vsock_sock *vsk) + struct virtio_vsock_sock *vvs = vsk->trans; + s64 bytes; + +- bytes = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); ++ bytes = (s64)vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); + if (bytes < 0) + bytes = 0; + +diff --git a/scripts/sign-file.c b/scripts/sign-file.c +index 598ef5465f825..3edb156ae52c3 100644 +--- a/scripts/sign-file.c ++++ b/scripts/sign-file.c +@@ -322,7 +322,7 @@ int main(int argc, char **argv) + CMS_NOSMIMECAP | use_keyid | + use_signed_attrs), + "CMS_add1_signer"); +- ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) < 0, ++ ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) != 1, + "CMS_final"); + + #else +@@ -341,10 +341,10 @@ int main(int argc, char **argv) + b = BIO_new_file(sig_file_name, "wb"); + ERR(!b, "%s", sig_file_name); + #ifndef USE_PKCS7 +- ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) < 0, ++ ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) != 1, + "%s", sig_file_name); + #else +- ERR(i2d_PKCS7_bio(b, pkcs7) < 0, ++ ERR(i2d_PKCS7_bio(b, pkcs7) != 1, + "%s", sig_file_name); + #endif + BIO_free(b); +@@ -374,9 +374,9 @@ int main(int argc, char **argv) + + if (!raw_sig) { + #ifndef USE_PKCS7 +- ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) < 0, "%s", dest_name); ++ ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) != 1, "%s", dest_name); + #else +- ERR(i2d_PKCS7_bio(bd, pkcs7) < 0, "%s", dest_name); ++ ERR(i2d_PKCS7_bio(bd, pkcs7) != 1, "%s", dest_name); + #endif + } else { + BIO *b; +@@ -396,7 +396,7 @@ int main(int argc, char **argv) + ERR(BIO_write(bd, &sig_info, sizeof(sig_info)) < 0, "%s", dest_name); + ERR(BIO_write(bd, magic_number, sizeof(magic_number) - 1) < 0, "%s", dest_name); + +- ERR(BIO_free(bd) < 0, "%s", dest_name); ++ ERR(BIO_free(bd) != 1, "%s", dest_name); + + /* Finally, if we're signing in place, replace the original. */ + if (replace_orig) +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index 7b5e09070ab9b..f460ac80c8e49 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -1993,7 +1993,10 @@ static const struct snd_pci_quirk force_connect_list[] = { + SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1), + SND_PCI_QUIRK(0x103c, 0x8711, "HP", 1), + SND_PCI_QUIRK(0x103c, 0x8715, "HP", 1), ++ SND_PCI_QUIRK(0x1043, 0x86ae, "ASUS", 1), /* Z170 PRO */ ++ SND_PCI_QUIRK(0x1043, 0x86c7, "ASUS", 1), /* Z170M PLUS */ + SND_PCI_QUIRK(0x1462, 0xec94, "MS-7C94", 1), ++ SND_PCI_QUIRK(0x8086, 0x2060, "Intel NUC5CPYB", 1), + SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", 1), + {} + }; +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index c6cae3369a6a1..a7c361e0daebe 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9577,6 +9577,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x841c, "HP Pavilion 15-CK0xx", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), ++ SND_PCI_QUIRK(0x103c, 0x84ae, "HP 15-db0403ng", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN), + SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360), +diff --git a/tools/testing/selftests/bpf/progs/bpf_loop_bench.c b/tools/testing/selftests/bpf/progs/bpf_loop_bench.c +index 4ce76eb064c41..d461746fd3c1e 100644 +--- a/tools/testing/selftests/bpf/progs/bpf_loop_bench.c ++++ b/tools/testing/selftests/bpf/progs/bpf_loop_bench.c +@@ -15,13 +15,16 @@ static int empty_callback(__u32 index, void *data) + return 0; + } + ++static int outer_loop(__u32 index, void *data) ++{ ++ bpf_loop(nr_loops, empty_callback, NULL, 0); ++ __sync_add_and_fetch(&hits, nr_loops); ++ return 0; ++} ++ + SEC("fentry/" SYS_PREFIX "sys_getpgid") + int benchmark(void *ctx) + { +- for (int i = 0; i < 1000; i++) { +- bpf_loop(nr_loops, empty_callback, NULL, 0); +- +- __sync_add_and_fetch(&hits, nr_loops); +- } ++ bpf_loop(1000, outer_loop, NULL, 0); + return 0; + }