diff options
author | 2023-12-13 13:26:12 -0500 | |
---|---|---|
committer | 2023-12-13 13:26:12 -0500 | |
commit | 4bd5ec3bbf30af9081aac6e8119bbb43ee6adb8f (patch) | |
tree | 9ad5b39f51e8436d92b726b8cda66044128cae28 | |
parent | Linux patch 6.6.6 (diff) | |
download | linux-patches-4bd5ec3bbf30af9081aac6e8119bbb43ee6adb8f.tar.gz linux-patches-4bd5ec3bbf30af9081aac6e8119bbb43ee6adb8f.tar.bz2 linux-patches-4bd5ec3bbf30af9081aac6e8119bbb43ee6adb8f.zip |
Linux patch 6.6.76.6-9
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1006_linux-6.6.7.patch | 10135 |
2 files changed, 10139 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 5f6d8661..caebb97e 100644 --- a/0000_README +++ b/0000_README @@ -67,6 +67,10 @@ Patch: 1005_linux-6.6.6.patch From: https://www.kernel.org Desc: Linux 6.6.6 +Patch: 1006_linux-6.6.7.patch +From: https://www.kernel.org +Desc: Linux 6.6.7 + Patch: 1510_fs-enable-link-security-restrictions-by-default.patch From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/ Desc: Enable link security restrictions by default. diff --git a/1006_linux-6.6.7.patch b/1006_linux-6.6.7.patch new file mode 100644 index 00000000..9507bb35 --- /dev/null +++ b/1006_linux-6.6.7.patch @@ -0,0 +1,10135 @@ +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 <uuid> + matches Trusted Application (TA) driver and corresponding TA in secure OS. Drivers + are free to create needed API under optee-ta-<uuid> directory. ++ ++What: /sys/bus/tee/devices/optee-ta-<uuid>/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 1eefa893f048b..707952172eceb 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 6 ++SUBLEVEL = 7 + EXTRAVERSION = + NAME = Hurr durr I'ma ninja sloth + +diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts b/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts +index 1ab8184302db4..5a2869a18bd55 100644 +--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts ++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts +@@ -36,9 +36,7 @@ + gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; + }; + +-&leds { +- /delete-node/ led_act; +-}; ++/delete-node/ &led_act; + + &pm { + /delete-property/ system-power-controller; +diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-skov-reve-mi1010ait-1cp1.dts b/arch/arm/boot/dts/nxp/imx/imx6q-skov-reve-mi1010ait-1cp1.dts +index a3f247c722b43..0342a79ccd5db 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx6q-skov-reve-mi1010ait-1cp1.dts ++++ b/arch/arm/boot/dts/nxp/imx/imx6q-skov-reve-mi1010ait-1cp1.dts +@@ -37,9 +37,9 @@ + + &clks { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, +- <&clks IMX6QDL_CLK_LDB_DI1_SEL>; ++ <&clks IMX6QDL_CLK_LDB_DI1_SEL>, <&clks IMX6QDL_CLK_ENET_REF_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, +- <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>; ++ <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, <&clk50m_phy>; + }; + + &hdmi { +diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-pico.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-pico.dtsi +index 4ffe99ed55ca2..07dcecbe485dc 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx6ul-pico.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/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/nxp/imx/imx7s.dtsi b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi +index e152d08f27d49..bc79163c49b51 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/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 = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; + 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 = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; + 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 = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; + 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 = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX7D_GPT4_ROOT_CLK>, +diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-xea.dts b/arch/arm/boot/dts/nxp/mxs/imx28-xea.dts +index a400c108f66a2..6c5e6856648af 100644 +--- a/arch/arm/boot/dts/nxp/mxs/imx28-xea.dts ++++ b/arch/arm/boot/dts/nxp/mxs/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/rockchip/rk3128.dtsi b/arch/arm/boot/dts/rockchip/rk3128.dtsi +index 88a4b0d6d928d..80d81af5fe0ef 100644 +--- a/arch/arm/boot/dts/rockchip/rk3128.dtsi ++++ b/arch/arm/boot/dts/rockchip/rk3128.dtsi +@@ -795,7 +795,7 @@ + }; + + sdmmc_pwren: sdmmc-pwren { +- rockchip,pins = <1 RK_PB6 1 &pcfg_pull_default>; ++ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_default>; + }; + + sdmmc_bus4: sdmmc-bus4 { +diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h +index e62832dcba760..a8287e7ab9d41 100644 +--- a/arch/arm/include/asm/kexec.h ++++ b/arch/arm/include/asm/kexec.h +@@ -2,8 +2,6 @@ + #ifndef _ARM_KEXEC_H + #define _ARM_KEXEC_H + +-#ifdef CONFIG_KEXEC +- + /* Maximum physical address we can use pages from */ + #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) + /* Maximum address we can reach in physical address mode */ +@@ -82,6 +80,4 @@ static inline struct page *boot_pfn_to_page(unsigned long boot_pfn) + + #endif /* __ASSEMBLY__ */ + +-#endif /* CONFIG_KEXEC */ +- + #endif /* _ARM_KEXEC_H */ +diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile +index d53f56d6f8408..771264d4726a7 100644 +--- a/arch/arm/kernel/Makefile ++++ b/arch/arm/kernel/Makefile +@@ -59,7 +59,7 @@ obj-$(CONFIG_FUNCTION_TRACER) += entry-ftrace.o + obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o patch.o + obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o patch.o + obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o +-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o ++obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o + # Main staffs in KPROBES are in arch/arm/probes/ . + obj-$(CONFIG_KPROBES) += patch.o insn.o + obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o +diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c +index 2157493b78a9b..df69af9323754 100644 +--- a/arch/arm/mach-imx/mmdc.c ++++ b/arch/arm/mach-imx/mmdc.c +@@ -501,6 +501,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; +@@ -523,9 +527,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/imx8-apalis-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi +index 9b1b522517f8e..0878a15acc1ba 100644 +--- a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi +@@ -82,12 +82,9 @@ + pinctrl-0 = <&pinctrl_wifi_pdn>; + gpio = <&lsio_gpio1 28 GPIO_ACTIVE_HIGH>; + enable-active-high; ++ regulator-always-on; + regulator-name = "wifi_pwrdn_fake_regulator"; + regulator-settling-time-us = <100>; +- +- regulator-state-mem { +- regulator-off-in-suspend; +- }; + }; + + reg_pcie_switch: regulator-pcie-switch { +diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi +index ea8c93757521b..133f2b1ce1d2e 100644 +--- a/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi +@@ -36,7 +36,8 @@ lsio_subsys: bus@5d000000 { + <&pwm0_lpcg 1>; + assigned-clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>; + assigned-clock-rates = <24000000>; +- #pwm-cells = <2>; ++ #pwm-cells = <3>; ++ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + +@@ -48,7 +49,8 @@ lsio_subsys: bus@5d000000 { + <&pwm1_lpcg 1>; + assigned-clocks = <&clk IMX_SC_R_PWM_1 IMX_SC_PM_CLK_PER>; + assigned-clock-rates = <24000000>; +- #pwm-cells = <2>; ++ #pwm-cells = <3>; ++ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + +@@ -60,7 +62,8 @@ lsio_subsys: bus@5d000000 { + <&pwm2_lpcg 1>; + assigned-clocks = <&clk IMX_SC_R_PWM_2 IMX_SC_PM_CLK_PER>; + assigned-clock-rates = <24000000>; +- #pwm-cells = <2>; ++ #pwm-cells = <3>; ++ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + +@@ -72,7 +75,8 @@ lsio_subsys: bus@5d000000 { + <&pwm3_lpcg 1>; + assigned-clocks = <&clk IMX_SC_R_PWM_3 IMX_SC_PM_CLK_PER>; + assigned-clock-rates = <24000000>; +- #pwm-cells = <2>; ++ #pwm-cells = <3>; ++ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +index 83d907294fbc7..4b50920ac2049 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +@@ -2030,6 +2030,7 @@ + phys = <&usb3_phy0>, <&usb3_phy0>; + phy-names = "usb2-phy", "usb3-phy"; + snps,gfladj-refclk-lpm-sel-quirk; ++ snps,parkmode-disable-ss-quirk; + }; + + }; +@@ -2072,6 +2073,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 35f07dfb4ca8d..052ba9baa400f 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi +@@ -1649,6 +1649,7 @@ + phys = <&usb3_phy0>, <&usb3_phy0>; + phy-names = "usb2-phy", "usb3-phy"; + power-domains = <&pgc_otg1>; ++ snps,parkmode-disable-ss-quirk; + status = "disabled"; + }; + +@@ -1680,6 +1681,7 @@ + phys = <&usb3_phy1>, <&usb3_phy1>; + phy-names = "usb2-phy", "usb3-phy"; + power-domains = <&pgc_otg2>; ++ snps,parkmode-disable-ss-quirk; + status = "disabled"; + }; + +diff --git a/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts b/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts +index f06139bdff97e..3c5c67ebee5d3 100644 +--- a/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts ++++ b/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts +@@ -577,7 +577,7 @@ + fsl,pins = < + MX93_PAD_UART2_TXD__LPUART2_TX 0x31e + MX93_PAD_UART2_RXD__LPUART2_RX 0x31e +- MX93_PAD_SAI1_TXD0__LPUART2_RTS_B 0x31e ++ MX93_PAD_SAI1_TXD0__LPUART2_RTS_B 0x51e + >; + }; + +diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi +index dcf6e4846ac9d..943b7e6655634 100644 +--- a/arch/arm64/boot/dts/freescale/imx93.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx93.dtsi +@@ -373,7 +373,7 @@ + compatible = "fsl,imx93-src-slice"; + reg = <0x44462400 0x400>, <0x44465800 0x400>; + #power-domain-cells = <0>; +- clocks = <&clk IMX93_CLK_MEDIA_AXI>, ++ clocks = <&clk IMX93_CLK_NIC_MEDIA_GATE>, + <&clk IMX93_CLK_MEDIA_APB>; + }; + }; +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 86cedb0bf1a90..94e1cc9fbea33 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -73,7 +73,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 dad8e683aac5b..c435984ca7674 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +@@ -55,7 +55,7 @@ + }; + }; + +- memory { ++ memory@40000000 { + reg = <0 0x40000000 0 0x20000000>; + }; + +diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts +index af4a4309bda4b..b876e501216be 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts +@@ -126,6 +126,7 @@ + compatible = "sff,sfp"; + i2c-bus = <&i2c_sfp1>; + los-gpios = <&pio 46 GPIO_ACTIVE_HIGH>; ++ maximum-power-milliwatt = <3000>; + mod-def0-gpios = <&pio 49 GPIO_ACTIVE_LOW>; + tx-disable-gpios = <&pio 20 GPIO_ACTIVE_HIGH>; + tx-fault-gpios = <&pio 7 GPIO_ACTIVE_HIGH>; +@@ -137,6 +138,7 @@ + i2c-bus = <&i2c_sfp2>; + los-gpios = <&pio 31 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&pio 47 GPIO_ACTIVE_LOW>; ++ maximum-power-milliwatt = <3000>; + tx-disable-gpios = <&pio 15 GPIO_ACTIVE_HIGH>; + tx-fault-gpios = <&pio 48 GPIO_ACTIVE_HIGH>; + }; +@@ -150,16 +152,16 @@ + trip = <&cpu_trip_active_high>; + }; + +- cpu-active-low { ++ cpu-active-med { + /* active: set fan to cooling level 1 */ + cooling-device = <&fan 1 1>; +- trip = <&cpu_trip_active_low>; ++ trip = <&cpu_trip_active_med>; + }; + +- cpu-passive { +- /* passive: set fan to cooling level 0 */ ++ cpu-active-low { ++ /* active: set fan to cooling level 0 */ + cooling-device = <&fan 0 0>; +- trip = <&cpu_trip_passive>; ++ trip = <&cpu_trip_active_low>; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +index 24eda00e320d3..fc751e049953c 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +@@ -374,6 +374,10 @@ + reg = <0 0x11230000 0 0x1000>, + <0 0x11c20000 0 0x1000>; + interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>; ++ assigned-clocks = <&topckgen CLK_TOP_EMMC_416M_SEL>, ++ <&topckgen CLK_TOP_EMMC_250M_SEL>; ++ assigned-clock-parents = <&apmixedsys CLK_APMIXED_MPLL>, ++ <&topckgen CLK_TOP_NET1PLL_D5_D2>; + clocks = <&topckgen CLK_TOP_EMMC_416M_SEL>, + <&infracfg CLK_INFRA_MSDC_HCK_CK>, + <&infracfg CLK_INFRA_MSDC_CK>, +@@ -610,22 +614,34 @@ + thermal-sensors = <&thermal 0>; + + trips { ++ cpu_trip_crit: crit { ++ temperature = <125000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu_trip_hot: hot { ++ temperature = <120000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ + cpu_trip_active_high: active-high { + temperature = <115000>; + hysteresis = <2000>; + type = "active"; + }; + +- cpu_trip_active_low: active-low { ++ cpu_trip_active_med: active-med { + temperature = <85000>; + hysteresis = <2000>; + type = "active"; + }; + +- cpu_trip_passive: passive { +- temperature = <40000>; ++ cpu_trip_active_low: active-low { ++ temperature = <60000>; + hysteresis = <2000>; +- type = "passive"; ++ type = "active"; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +index 5122963d8743a..d258c80213b26 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +@@ -44,7 +44,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>; +@@ -53,7 +53,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 d8bd518076832..77f9ab94c00bd 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts +@@ -31,14 +31,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>; +@@ -155,8 +155,8 @@ + }; + + &pio { +- i2c_pins_0: i2c0{ +- pins_i2c{ ++ i2c_pins_0: i2c0 { ++ pins_i2c { + pinmux = <PINMUX_GPIO82__FUNC_SDA0>, + <PINMUX_GPIO83__FUNC_SCL0>; + mediatek,pull-up-adv = <3>; +@@ -164,8 +164,8 @@ + }; + }; + +- i2c_pins_1: i2c1{ +- pins_i2c{ ++ i2c_pins_1: i2c1 { ++ pins_i2c { + pinmux = <PINMUX_GPIO81__FUNC_SDA1>, + <PINMUX_GPIO84__FUNC_SCL1>; + mediatek,pull-up-adv = <3>; +@@ -173,8 +173,8 @@ + }; + }; + +- i2c_pins_2: i2c2{ +- pins_i2c{ ++ i2c_pins_2: i2c2 { ++ pins_i2c { + pinmux = <PINMUX_GPIO103__FUNC_SCL2>, + <PINMUX_GPIO104__FUNC_SDA2>; + mediatek,pull-up-adv = <3>; +@@ -182,8 +182,8 @@ + }; + }; + +- i2c_pins_3: i2c3{ +- pins_i2c{ ++ i2c_pins_3: i2c3 { ++ pins_i2c { + pinmux = <PINMUX_GPIO50__FUNC_SCL3>, + <PINMUX_GPIO51__FUNC_SDA3>; + mediatek,pull-up-adv = <3>; +@@ -191,8 +191,8 @@ + }; + }; + +- i2c_pins_4: i2c4{ +- pins_i2c{ ++ i2c_pins_4: i2c4 { ++ pins_i2c { + pinmux = <PINMUX_GPIO105__FUNC_SCL4>, + <PINMUX_GPIO106__FUNC_SDA4>; + mediatek,pull-up-adv = <3>; +@@ -200,8 +200,8 @@ + }; + }; + +- i2c_pins_5: i2c5{ +- pins_i2c{ ++ i2c_pins_5: i2c5 { ++ pins_i2c { + pinmux = <PINMUX_GPIO48__FUNC_SCL5>, + <PINMUX_GPIO49__FUNC_SDA5>; + mediatek,pull-up-adv = <3>; +@@ -209,8 +209,8 @@ + }; + }; + +- spi_pins_0: spi0{ +- pins_spi{ ++ spi_pins_0: spi0 { ++ pins_spi { + pinmux = <PINMUX_GPIO85__FUNC_SPI0_MI>, + <PINMUX_GPIO86__FUNC_SPI0_CSB>, + <PINMUX_GPIO87__FUNC_SPI0_MO>, +@@ -324,8 +324,8 @@ + }; + }; + +- spi_pins_1: spi1{ +- pins_spi{ ++ spi_pins_1: spi1 { ++ pins_spi { + pinmux = <PINMUX_GPIO161__FUNC_SPI1_A_MI>, + <PINMUX_GPIO162__FUNC_SPI1_A_CSB>, + <PINMUX_GPIO163__FUNC_SPI1_A_MO>, +@@ -334,8 +334,8 @@ + }; + }; + +- spi_pins_2: spi2{ +- pins_spi{ ++ spi_pins_2: spi2 { ++ pins_spi { + pinmux = <PINMUX_GPIO0__FUNC_SPI2_CSB>, + <PINMUX_GPIO1__FUNC_SPI2_MO>, + <PINMUX_GPIO2__FUNC_SPI2_CLK>, +@@ -344,8 +344,8 @@ + }; + }; + +- spi_pins_3: spi3{ +- pins_spi{ ++ spi_pins_3: spi3 { ++ pins_spi { + pinmux = <PINMUX_GPIO21__FUNC_SPI3_MI>, + <PINMUX_GPIO22__FUNC_SPI3_CSB>, + <PINMUX_GPIO23__FUNC_SPI3_MO>, +@@ -354,8 +354,8 @@ + }; + }; + +- spi_pins_4: spi4{ +- pins_spi{ ++ spi_pins_4: spi4 { ++ pins_spi { + pinmux = <PINMUX_GPIO17__FUNC_SPI4_MI>, + <PINMUX_GPIO18__FUNC_SPI4_CSB>, + <PINMUX_GPIO19__FUNC_SPI4_MO>, +@@ -364,8 +364,8 @@ + }; + }; + +- spi_pins_5: spi5{ +- pins_spi{ ++ spi_pins_5: spi5 { ++ pins_spi { + pinmux = <PINMUX_GPIO13__FUNC_SPI5_MI>, + <PINMUX_GPIO14__FUNC_SPI5_CSB>, + <PINMUX_GPIO15__FUNC_SPI5_MO>, +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi +index bf97b60ae4d17..820260348de9b 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi +@@ -91,6 +91,8 @@ + + &dsi0 { + status = "okay"; ++ /delete-property/#size-cells; ++ /delete-property/#address-cells; + /delete-node/panel@0; + ports { + port { +@@ -441,20 +443,20 @@ + }; + + touchscreen_pins: touchscreen-pins { +- touch_int_odl { ++ touch-int-odl { + pinmux = <PINMUX_GPIO155__FUNC_GPIO155>; + input-enable; + bias-pull-up; + }; + +- touch_rst_l { ++ touch-rst-l { + pinmux = <PINMUX_GPIO156__FUNC_GPIO156>; + output-high; + }; + }; + + trackpad_pins: trackpad-pins { +- trackpad_int { ++ trackpad-int { + pinmux = <PINMUX_GPIO7__FUNC_GPIO7>; + 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 6ce16a265e053..6f333f5cbeb98 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; +@@ -432,7 +432,7 @@ + + &pio { + aud_pins_default: audiopins { +- pins_bus { ++ pins-bus { + pinmux = <PINMUX_GPIO97__FUNC_I2S2_MCK>, + <PINMUX_GPIO98__FUNC_I2S2_BCK>, + <PINMUX_GPIO101__FUNC_I2S2_LRCK>, +@@ -454,7 +454,7 @@ + }; + + aud_pins_tdm_out_on: audiotdmouton { +- pins_bus { ++ pins-bus { + pinmux = <PINMUX_GPIO169__FUNC_TDM_BCK_2ND>, + <PINMUX_GPIO170__FUNC_TDM_LRCK_2ND>, + <PINMUX_GPIO171__FUNC_TDM_DATA0_2ND>, +@@ -466,7 +466,7 @@ + }; + + aud_pins_tdm_out_off: audiotdmoutoff { +- pins_bus { ++ pins-bus { + pinmux = <PINMUX_GPIO169__FUNC_GPIO169>, + <PINMUX_GPIO170__FUNC_GPIO170>, + <PINMUX_GPIO171__FUNC_GPIO171>, +@@ -480,13 +480,13 @@ + }; + + bt_pins: bt-pins { +- pins_bt_en { ++ pins-bt-en { + pinmux = <PINMUX_GPIO120__FUNC_GPIO120>; + output-low; + }; + }; + +- ec_ap_int_odl: ec_ap_int_odl { ++ ec_ap_int_odl: ec-ap-int-odl { + pins1 { + pinmux = <PINMUX_GPIO151__FUNC_GPIO151>; + input-enable; +@@ -494,7 +494,7 @@ + }; + }; + +- h1_int_od_l: h1_int_od_l { ++ h1_int_od_l: h1-int-od-l { + pins1 { + pinmux = <PINMUX_GPIO153__FUNC_GPIO153>; + input-enable; +@@ -502,7 +502,7 @@ + }; + + i2c0_pins: i2c0 { +- pins_bus { ++ pins-bus { + pinmux = <PINMUX_GPIO82__FUNC_SDA0>, + <PINMUX_GPIO83__FUNC_SCL0>; + mediatek,pull-up-adv = <3>; +@@ -511,7 +511,7 @@ + }; + + i2c1_pins: i2c1 { +- pins_bus { ++ pins-bus { + pinmux = <PINMUX_GPIO81__FUNC_SDA1>, + <PINMUX_GPIO84__FUNC_SCL1>; + mediatek,pull-up-adv = <3>; +@@ -520,7 +520,7 @@ + }; + + i2c2_pins: i2c2 { +- pins_bus { ++ pins-bus { + pinmux = <PINMUX_GPIO103__FUNC_SCL2>, + <PINMUX_GPIO104__FUNC_SDA2>; + bias-disable; +@@ -529,7 +529,7 @@ + }; + + i2c3_pins: i2c3 { +- pins_bus { ++ pins-bus { + pinmux = <PINMUX_GPIO50__FUNC_SCL3>, + <PINMUX_GPIO51__FUNC_SDA3>; + mediatek,pull-up-adv = <3>; +@@ -538,7 +538,7 @@ + }; + + i2c4_pins: i2c4 { +- pins_bus { ++ pins-bus { + pinmux = <PINMUX_GPIO105__FUNC_SCL4>, + <PINMUX_GPIO106__FUNC_SDA4>; + bias-disable; +@@ -547,7 +547,7 @@ + }; + + i2c5_pins: i2c5 { +- pins_bus { ++ pins-bus { + pinmux = <PINMUX_GPIO48__FUNC_SCL5>, + <PINMUX_GPIO49__FUNC_SDA5>; + mediatek,pull-up-adv = <3>; +@@ -556,7 +556,7 @@ + }; + + i2c6_pins: i2c6 { +- pins_bus { ++ pins-bus { + pinmux = <PINMUX_GPIO11__FUNC_SCL6>, + <PINMUX_GPIO12__FUNC_SDA6>; + bias-disable; +@@ -564,7 +564,7 @@ + }; + + mmc0_pins_default: mmc0-pins-default { +- pins_cmd_dat { ++ pins-cmd-dat { + pinmux = <PINMUX_GPIO123__FUNC_MSDC0_DAT0>, + <PINMUX_GPIO128__FUNC_MSDC0_DAT1>, + <PINMUX_GPIO125__FUNC_MSDC0_DAT2>, +@@ -579,13 +579,13 @@ + mediatek,pull-up-adv = <01>; + }; + +- pins_clk { ++ pins-clk { + pinmux = <PINMUX_GPIO124__FUNC_MSDC0_CLK>; + drive-strength = <MTK_DRIVE_14mA>; + mediatek,pull-down-adv = <10>; + }; + +- pins_rst { ++ pins-rst { + pinmux = <PINMUX_GPIO133__FUNC_MSDC0_RSTB>; + drive-strength = <MTK_DRIVE_14mA>; + mediatek,pull-down-adv = <01>; +@@ -593,7 +593,7 @@ + }; + + mmc0_pins_uhs: mmc0-pins-uhs { +- pins_cmd_dat { ++ pins-cmd-dat { + pinmux = <PINMUX_GPIO123__FUNC_MSDC0_DAT0>, + <PINMUX_GPIO128__FUNC_MSDC0_DAT1>, + <PINMUX_GPIO125__FUNC_MSDC0_DAT2>, +@@ -608,19 +608,19 @@ + mediatek,pull-up-adv = <01>; + }; + +- pins_clk { ++ pins-clk { + pinmux = <PINMUX_GPIO124__FUNC_MSDC0_CLK>; + drive-strength = <MTK_DRIVE_14mA>; + mediatek,pull-down-adv = <10>; + }; + +- pins_ds { ++ pins-ds { + pinmux = <PINMUX_GPIO131__FUNC_MSDC0_DSL>; + drive-strength = <MTK_DRIVE_14mA>; + mediatek,pull-down-adv = <10>; + }; + +- pins_rst { ++ pins-rst { + pinmux = <PINMUX_GPIO133__FUNC_MSDC0_RSTB>; + drive-strength = <MTK_DRIVE_14mA>; + mediatek,pull-up-adv = <01>; +@@ -628,7 +628,7 @@ + }; + + mmc1_pins_default: mmc1-pins-default { +- pins_cmd_dat { ++ pins-cmd-dat { + pinmux = <PINMUX_GPIO31__FUNC_MSDC1_CMD>, + <PINMUX_GPIO32__FUNC_MSDC1_DAT0>, + <PINMUX_GPIO34__FUNC_MSDC1_DAT1>, +@@ -638,7 +638,7 @@ + mediatek,pull-up-adv = <10>; + }; + +- pins_clk { ++ pins-clk { + pinmux = <PINMUX_GPIO29__FUNC_MSDC1_CLK>; + input-enable; + mediatek,pull-down-adv = <10>; +@@ -646,7 +646,7 @@ + }; + + mmc1_pins_uhs: mmc1-pins-uhs { +- pins_cmd_dat { ++ pins-cmd-dat { + pinmux = <PINMUX_GPIO31__FUNC_MSDC1_CMD>, + <PINMUX_GPIO32__FUNC_MSDC1_DAT0>, + <PINMUX_GPIO34__FUNC_MSDC1_DAT1>, +@@ -657,7 +657,7 @@ + mediatek,pull-up-adv = <10>; + }; + +- pins_clk { ++ pins-clk { + pinmux = <PINMUX_GPIO29__FUNC_MSDC1_CLK>; + drive-strength = <MTK_DRIVE_8mA>; + mediatek,pull-down-adv = <10>; +@@ -665,15 +665,15 @@ + }; + }; + +- panel_pins_default: panel_pins_default { +- panel_reset { ++ panel_pins_default: panel-pins-default { ++ panel-reset { + pinmux = <PINMUX_GPIO45__FUNC_GPIO45>; + output-low; + bias-pull-up; + }; + }; + +- pwm0_pin_default: pwm0_pin_default { ++ pwm0_pin_default: pwm0-pin-default { + pins1 { + pinmux = <PINMUX_GPIO176__FUNC_GPIO176>; + output-high; +@@ -685,14 +685,14 @@ + }; + + scp_pins: scp { +- pins_scp_uart { ++ pins-scp-uart { + pinmux = <PINMUX_GPIO110__FUNC_TP_URXD1_AO>, + <PINMUX_GPIO112__FUNC_TP_UTXD1_AO>; + }; + }; + + spi0_pins: spi0 { +- pins_spi{ ++ pins-spi { + pinmux = <PINMUX_GPIO85__FUNC_SPI0_MI>, + <PINMUX_GPIO86__FUNC_GPIO86>, + <PINMUX_GPIO87__FUNC_SPI0_MO>, +@@ -702,7 +702,7 @@ + }; + + spi1_pins: spi1 { +- pins_spi{ ++ pins-spi { + pinmux = <PINMUX_GPIO161__FUNC_SPI1_A_MI>, + <PINMUX_GPIO162__FUNC_SPI1_A_CSB>, + <PINMUX_GPIO163__FUNC_SPI1_A_MO>, +@@ -712,20 +712,20 @@ + }; + + spi2_pins: spi2 { +- pins_spi{ ++ pins-spi { + pinmux = <PINMUX_GPIO0__FUNC_SPI2_CSB>, + <PINMUX_GPIO1__FUNC_SPI2_MO>, + <PINMUX_GPIO2__FUNC_SPI2_CLK>; + bias-disable; + }; +- pins_spi_mi { ++ pins-spi-mi { + pinmux = <PINMUX_GPIO94__FUNC_SPI2_MI>; + mediatek,pull-down-adv = <00>; + }; + }; + + spi3_pins: spi3 { +- pins_spi{ ++ pins-spi { + pinmux = <PINMUX_GPIO21__FUNC_SPI3_MI>, + <PINMUX_GPIO22__FUNC_SPI3_CSB>, + <PINMUX_GPIO23__FUNC_SPI3_MO>, +@@ -735,7 +735,7 @@ + }; + + spi4_pins: spi4 { +- pins_spi{ ++ pins-spi { + pinmux = <PINMUX_GPIO17__FUNC_SPI4_MI>, + <PINMUX_GPIO18__FUNC_SPI4_CSB>, + <PINMUX_GPIO19__FUNC_SPI4_MO>, +@@ -745,7 +745,7 @@ + }; + + spi5_pins: spi5 { +- pins_spi{ ++ pins-spi { + pinmux = <PINMUX_GPIO13__FUNC_SPI5_MI>, + <PINMUX_GPIO14__FUNC_SPI5_CSB>, + <PINMUX_GPIO15__FUNC_SPI5_MO>, +@@ -755,63 +755,63 @@ + }; + + uart0_pins_default: uart0-pins-default { +- pins_rx { ++ pins-rx { + pinmux = <PINMUX_GPIO95__FUNC_URXD0>; + input-enable; + bias-pull-up; + }; +- pins_tx { ++ pins-tx { + pinmux = <PINMUX_GPIO96__FUNC_UTXD0>; + }; + }; + + uart1_pins_default: uart1-pins-default { +- pins_rx { ++ pins-rx { + pinmux = <PINMUX_GPIO121__FUNC_URXD1>; + input-enable; + bias-pull-up; + }; +- pins_tx { ++ pins-tx { + pinmux = <PINMUX_GPIO115__FUNC_UTXD1>; + }; +- pins_rts { ++ pins-rts { + pinmux = <PINMUX_GPIO47__FUNC_URTS1>; + output-enable; + }; +- pins_cts { ++ pins-cts { + pinmux = <PINMUX_GPIO46__FUNC_UCTS1>; + input-enable; + }; + }; + + uart1_pins_sleep: uart1-pins-sleep { +- pins_rx { ++ pins-rx { + pinmux = <PINMUX_GPIO121__FUNC_GPIO121>; + input-enable; + bias-pull-up; + }; +- pins_tx { ++ pins-tx { + pinmux = <PINMUX_GPIO115__FUNC_UTXD1>; + }; +- pins_rts { ++ pins-rts { + pinmux = <PINMUX_GPIO47__FUNC_URTS1>; + output-enable; + }; +- pins_cts { ++ pins-cts { + pinmux = <PINMUX_GPIO46__FUNC_UCTS1>; + input-enable; + }; + }; + + wifi_pins_pwrseq: wifi-pins-pwrseq { +- pins_wifi_enable { ++ pins-wifi-enable { + pinmux = <PINMUX_GPIO119__FUNC_GPIO119>; + output-low; + }; + }; + + wifi_pins_wakeup: wifi-pins-wakeup { +- pins_wifi_wakeup { ++ pins-wifi-wakeup { + pinmux = <PINMUX_GPIO113__FUNC_GPIO113>; + input-enable; + }; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts +index 526bcae7a3f8f..b5784a60c315d 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts +@@ -193,7 +193,7 @@ + + &pio { + i2c_pins_0: i2c0 { +- pins_i2c{ ++ pins_i2c { + pinmux = <PINMUX_GPIO82__FUNC_SDA0>, + <PINMUX_GPIO83__FUNC_SCL0>; + mediatek,pull-up-adv = <3>; +@@ -202,7 +202,7 @@ + }; + + i2c_pins_1: i2c1 { +- pins_i2c{ ++ pins_i2c { + pinmux = <PINMUX_GPIO81__FUNC_SDA1>, + <PINMUX_GPIO84__FUNC_SCL1>; + mediatek,pull-up-adv = <3>; +@@ -211,7 +211,7 @@ + }; + + i2c_pins_2: i2c2 { +- pins_i2c{ ++ pins_i2c { + pinmux = <PINMUX_GPIO103__FUNC_SCL2>, + <PINMUX_GPIO104__FUNC_SDA2>; + mediatek,pull-up-adv = <3>; +@@ -220,7 +220,7 @@ + }; + + i2c_pins_3: i2c3 { +- pins_i2c{ ++ pins_i2c { + pinmux = <PINMUX_GPIO50__FUNC_SCL3>, + <PINMUX_GPIO51__FUNC_SDA3>; + mediatek,pull-up-adv = <3>; +@@ -229,7 +229,7 @@ + }; + + i2c_pins_4: i2c4 { +- pins_i2c{ ++ pins_i2c { + pinmux = <PINMUX_GPIO105__FUNC_SCL4>, + <PINMUX_GPIO106__FUNC_SDA4>; + mediatek,pull-up-adv = <3>; +@@ -238,7 +238,7 @@ + }; + + i2c_pins_5: i2c5 { +- pins_i2c{ ++ pins_i2c { + pinmux = <PINMUX_GPIO48__FUNC_SCL5>, + <PINMUX_GPIO49__FUNC_SDA5>; + mediatek,pull-up-adv = <3>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +index 5169779d01dfb..976dc968b3ca1 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +@@ -1210,127 +1210,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>; +@@ -2105,4 +1984,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/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi +index f04ae70c470aa..df0c04f2ba1da 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8186.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi +@@ -924,7 +924,8 @@ + reg = <MT8186_POWER_DOMAIN_CSIRX_TOP>; + clocks = <&topckgen CLK_TOP_SENINF>, + <&topckgen CLK_TOP_SENINF1>; +- clock-names = "csirx_top0", "csirx_top1"; ++ clock-names = "subsys-csirx-top0", ++ "subsys-csirx-top1"; + #power-domain-cells = <0>; + }; + +@@ -942,7 +943,8 @@ + reg = <MT8186_POWER_DOMAIN_ADSP_AO>; + clocks = <&topckgen CLK_TOP_AUDIODSP>, + <&topckgen CLK_TOP_ADSP_BUS>; +- clock-names = "audioadsp", "adsp_bus"; ++ clock-names = "audioadsp", ++ "subsys-adsp-bus"; + #address-cells = <1>; + #size-cells = <0>; + #power-domain-cells = <1>; +@@ -975,8 +977,11 @@ + <&mmsys CLK_MM_SMI_COMMON>, + <&mmsys CLK_MM_SMI_GALS>, + <&mmsys CLK_MM_SMI_IOMMU>; +- clock-names = "disp", "mdp", "smi_infra", "smi_common", +- "smi_gals", "smi_iommu"; ++ clock-names = "disp", "mdp", ++ "subsys-smi-infra", ++ "subsys-smi-common", ++ "subsys-smi-gals", ++ "subsys-smi-iommu"; + mediatek,infracfg = <&infracfg_ao>; + #address-cells = <1>; + #size-cells = <0>; +@@ -993,15 +998,17 @@ + + power-domain@MT8186_POWER_DOMAIN_CAM { + reg = <MT8186_POWER_DOMAIN_CAM>; +- clocks = <&topckgen CLK_TOP_CAM>, +- <&topckgen CLK_TOP_SENINF>, ++ clocks = <&topckgen CLK_TOP_SENINF>, + <&topckgen CLK_TOP_SENINF1>, + <&topckgen CLK_TOP_SENINF2>, + <&topckgen CLK_TOP_SENINF3>, ++ <&camsys CLK_CAM2MM_GALS>, + <&topckgen CLK_TOP_CAMTM>, +- <&camsys CLK_CAM2MM_GALS>; +- clock-names = "cam-top", "cam0", "cam1", "cam2", +- "cam3", "cam-tm", "gals"; ++ <&topckgen CLK_TOP_CAM>; ++ clock-names = "cam0", "cam1", "cam2", ++ "cam3", "gals", ++ "subsys-cam-tm", ++ "subsys-cam-top"; + mediatek,infracfg = <&infracfg_ao>; + #address-cells = <1>; + #size-cells = <0>; +@@ -1020,9 +1027,9 @@ + + power-domain@MT8186_POWER_DOMAIN_IMG { + reg = <MT8186_POWER_DOMAIN_IMG>; +- clocks = <&topckgen CLK_TOP_IMG1>, +- <&imgsys1 CLK_IMG1_GALS_IMG1>; +- clock-names = "img-top", "gals"; ++ clocks = <&imgsys1 CLK_IMG1_GALS_IMG1>, ++ <&topckgen CLK_TOP_IMG1>; ++ clock-names = "gals", "subsys-img-top"; + mediatek,infracfg = <&infracfg_ao>; + #address-cells = <1>; + #size-cells = <0>; +@@ -1041,8 +1048,11 @@ + <&ipesys CLK_IPE_LARB20>, + <&ipesys CLK_IPE_SMI_SUBCOM>, + <&ipesys CLK_IPE_GALS_IPE>; +- clock-names = "ipe-top", "ipe-larb0", "ipe-larb1", +- "ipe-smi", "ipe-gals"; ++ clock-names = "subsys-ipe-top", ++ "subsys-ipe-larb0", ++ "subsys-ipe-larb1", ++ "subsys-ipe-smi", ++ "subsys-ipe-gals"; + mediatek,infracfg = <&infracfg_ao>; + #power-domain-cells = <0>; + }; +@@ -1061,7 +1071,9 @@ + clocks = <&topckgen CLK_TOP_WPE>, + <&wpesys CLK_WPE_SMI_LARB8_CK_EN>, + <&wpesys CLK_WPE_SMI_LARB8_PCLK_EN>; +- clock-names = "wpe0", "larb-ck", "larb-pclk"; ++ clock-names = "wpe0", ++ "subsys-larb-ck", ++ "subsys-larb-pclk"; + mediatek,infracfg = <&infracfg_ao>; + #power-domain-cells = <0>; + }; +@@ -1656,7 +1668,7 @@ + #address-cells = <1>; + #size-cells = <1>; + +- gpu_speedbin: gpu-speed-bin@59c { ++ gpu_speedbin: gpu-speedbin@59c { + reg = <0x59c 0x4>; + bits = <0 3>; + }; +diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi +index 37a3e9de90ff7..3f508e5c18434 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi +@@ -362,7 +362,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 54c674c45b49a..e0ac2e9f5b720 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +@@ -627,6 +627,8 @@ + + power-domain@MT8195_POWER_DOMAIN_VENC_CORE1 { + reg = <MT8195_POWER_DOMAIN_VENC_CORE1>; ++ clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>; ++ clock-names = "venc1-larb"; + mediatek,infracfg = <&infracfg_ao>; + #power-domain-cells = <0>; + }; +@@ -689,6 +691,8 @@ + + power-domain@MT8195_POWER_DOMAIN_VENC { + reg = <MT8195_POWER_DOMAIN_VENC>; ++ clocks = <&vencsys CLK_VENC_LARB>; ++ clock-names = "venc0-larb"; + mediatek,infracfg = <&infracfg_ao>; + #power-domain-cells = <0>; + }; +@@ -2665,7 +2669,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 e729e7a22b23a..cc8209795c3e5 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -668,7 +668,7 @@ + + vdec: video-codec@ff360000 { + compatible = "rockchip,rk3328-vdec", "rockchip,rk3399-vdec"; +- reg = <0x0 0xff360000 0x0 0x400>; ++ reg = <0x0 0xff360000 0x0 0x480>; + interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; + 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 5bc2d4faeea6d..4a3d0af5ecfe2 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -1109,7 +1109,9 @@ + power-domain@RK3399_PD_VDU { + reg = <RK3399_PD_VDU>; + 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>; +@@ -1385,7 +1387,7 @@ + + vdec: video-codec@ff660000 { + compatible = "rockchip,rk3399-vdec"; +- reg = <0x0 0xff660000 0x0 0x400>; ++ reg = <0x0 0xff660000 0x0 0x480>; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>, + <&cru SCLK_VDU_CA>, <&cru SCLK_VDU_CORE>; +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi +index 48181671eacb0..0933652bafc30 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi +@@ -369,7 +369,7 @@ + emmc_data_strobe: emmc-data-strobe { + rockchip,pins = + /* emmc_data_strobe */ +- <2 RK_PA2 1 &pcfg_pull_none>; ++ <2 RK_PA2 1 &pcfg_pull_down>; + }; + }; + +diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c +index db9342b2d0e66..00915fb3cb82c 100644 +--- a/arch/loongarch/net/bpf_jit.c ++++ b/arch/loongarch/net/bpf_jit.c +@@ -855,8 +855,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; + +@@ -907,14 +905,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; + } + +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index bc8421859006f..91c3a502156b3 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -482,6 +482,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 +@@ -1273,6 +1274,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 5387ed0a51862..b630604c577f9 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 <linux/dma-map-ops.h> + #include <linux/export.h> + #include <linux/pci_ids.h> + #include <asm/bootinfo.h> +@@ -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 68cbe666510a3..8c45b98dfe0e4 100644 +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -113,9 +113,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/powerpc/kernel/trace/ftrace_entry.S b/arch/powerpc/kernel/trace/ftrace_entry.S +index 90701885762cf..40677416d7b26 100644 +--- a/arch/powerpc/kernel/trace/ftrace_entry.S ++++ b/arch/powerpc/kernel/trace/ftrace_entry.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/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs +index 6833d01e2e707..30fd6a5128285 100644 +--- a/arch/riscv/Kconfig.socs ++++ b/arch/riscv/Kconfig.socs +@@ -29,6 +29,7 @@ config SOC_STARFIVE + bool "StarFive SoCs" + select PINCTRL + select RESET_CONTROLLER ++ select ARM_AMBA + help + This enables support for StarFive SoC platform hardware. + +diff --git a/arch/riscv/errata/andes/errata.c b/arch/riscv/errata/andes/errata.c +index 197db68cc8daf..17a9048697246 100644 +--- a/arch/riscv/errata/andes/errata.c ++++ b/arch/riscv/errata/andes/errata.c +@@ -38,29 +38,35 @@ static long ax45mp_iocp_sw_workaround(void) + return ret.error ? 0 : ret.value; + } + +-static bool errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigned long impid) ++static void errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigned long impid) + { ++ static bool done; ++ + if (!IS_ENABLED(CONFIG_ERRATA_ANDES_CMO)) +- return false; ++ return; ++ ++ if (done) ++ return; ++ ++ done = true; + + if (arch_id != ANDESTECH_AX45MP_MARCHID || impid != ANDESTECH_AX45MP_MIMPID) +- return false; ++ return; + + if (!ax45mp_iocp_sw_workaround()) +- return false; ++ return; + + /* Set this just to make core cbo code happy */ + riscv_cbom_block_size = 1; + riscv_noncoherent_supported(); +- +- return true; + } + + void __init_or_module andes_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, + unsigned long archid, unsigned long impid, + unsigned int stage) + { +- errata_probe_iocp(stage, archid, impid); ++ if (stage == RISCV_ALTERNATIVES_BOOT) ++ errata_probe_iocp(stage, archid, impid); + + /* we have nothing to patch here ATM so just return back */ + } +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 3bd2ab2a9a344..5cb92941540b3 100644 +--- a/arch/s390/mm/pgtable.c ++++ b/arch/s390/mm/pgtable.c +@@ -756,7 +756,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 1d6b863c42b00..f3c75809fed26 100644 +--- a/arch/x86/coco/tdx/tdx.c ++++ b/arch/x86/coco/tdx/tdx.c +@@ -10,6 +10,7 @@ + #include <asm/coco.h> + #include <asm/tdx.h> + #include <asm/vmx.h> ++#include <asm/ia32.h> + #include <asm/insn.h> + #include <asm/insn-eval.h> + #include <asm/pgtable.h> +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 <xen/events.h> + #endif + ++#include <asm/apic.h> + #include <asm/desc.h> + #include <asm/traps.h> + #include <asm/vdso.h> +@@ -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 70150298f8bdf..4e88f84387061 100644 +--- a/arch/x86/entry/entry_64_compat.S ++++ b/arch/x86/entry/entry_64_compat.S +@@ -276,80 +276,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(pcpu_hot + X86_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 05fd175cec7d5..13639e57e1f8a 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 ece2b5b7b0fe4..6e4f23f314ac5 100644 +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -1315,6 +1315,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 b786d48f5a0fa..fc77a96040b7e 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 6395bfd87b68b..d87c6ff1f5136 100644 +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -1234,10 +1234,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(). +@@ -1254,6 +1250,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 beea99c8e8e05..77f1eeefcd34b 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -1873,15 +1873,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 6faea41e99b6b..45ff95264a097 100644 +--- a/arch/x86/mm/mem_encrypt_amd.c ++++ b/arch/x86/mm/mem_encrypt_amd.c +@@ -34,6 +34,7 @@ + #include <asm/msr.h> + #include <asm/cmdline.h> + #include <asm/sev.h> ++#include <asm/ia32.h> + + #include "mm_internal.h" + +@@ -517,6 +518,16 @@ void __init sme_early_init(void) + */ + if (sev_status & MSR_AMD64_SEV_ES_ENABLED) + x86_cpuinit.parallel_bringup = false; ++ ++ /* ++ * 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 bbbfdd495ebd3..aeb33e0a3f763 100644 +--- a/arch/x86/xen/enlighten_pv.c ++++ b/arch/x86/xen/enlighten_pv.c +@@ -704,7 +704,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 9e5e680087853..1a9cd18dfbd31 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/base/cpu.c b/drivers/base/cpu.c +index 9ea22e165acd6..548491de818ef 100644 +--- a/drivers/base/cpu.c ++++ b/drivers/base/cpu.c +@@ -144,7 +144,7 @@ static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store); + #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ + #endif /* CONFIG_HOTPLUG_CPU */ + +-#ifdef CONFIG_KEXEC ++#ifdef CONFIG_KEXEC_CORE + #include <linux/kexec.h> + + static ssize_t crash_notes_show(struct device *dev, +@@ -189,14 +189,14 @@ static const struct attribute_group crash_note_cpu_attr_group = { + #endif + + static const struct attribute_group *common_cpu_attr_groups[] = { +-#ifdef CONFIG_KEXEC ++#ifdef CONFIG_KEXEC_CORE + &crash_note_cpu_attr_group, + #endif + NULL + }; + + static const struct attribute_group *hotplugable_cpu_attr_groups[] = { +-#ifdef CONFIG_KEXEC ++#ifdef CONFIG_KEXEC_CORE + &crash_note_cpu_attr_group, + #endif + NULL +diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c +index 91536ee05f144..7e2d1f0d903a6 100644 +--- a/drivers/base/devcoredump.c ++++ b/drivers/base/devcoredump.c +@@ -362,6 +362,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; + +@@ -376,6 +377,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/memory.c b/drivers/base/memory.c +index f3b9a4d0fa3bb..8a13babd826ce 100644 +--- a/drivers/base/memory.c ++++ b/drivers/base/memory.c +@@ -180,6 +180,9 @@ static inline unsigned long memblk_nr_poison(struct memory_block *mem) + } + #endif + ++/* ++ * Must acquire mem_hotplug_lock in write mode. ++ */ + static int memory_block_online(struct memory_block *mem) + { + unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); +@@ -204,10 +207,11 @@ static int memory_block_online(struct memory_block *mem) + if (mem->altmap) + nr_vmemmap_pages = mem->altmap->free; + ++ mem_hotplug_begin(); + if (nr_vmemmap_pages) { + ret = mhp_init_memmap_on_memory(start_pfn, nr_vmemmap_pages, zone); + if (ret) +- return ret; ++ goto out; + } + + ret = online_pages(start_pfn + nr_vmemmap_pages, +@@ -215,7 +219,7 @@ static int memory_block_online(struct memory_block *mem) + if (ret) { + if (nr_vmemmap_pages) + mhp_deinit_memmap_on_memory(start_pfn, nr_vmemmap_pages); +- return ret; ++ goto out; + } + + /* +@@ -227,9 +231,14 @@ static int memory_block_online(struct memory_block *mem) + nr_vmemmap_pages); + + mem->zone = zone; ++out: ++ mem_hotplug_done(); + return ret; + } + ++/* ++ * Must acquire mem_hotplug_lock in write mode. ++ */ + static int memory_block_offline(struct memory_block *mem) + { + unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); +@@ -247,6 +256,7 @@ static int memory_block_offline(struct memory_block *mem) + if (mem->altmap) + nr_vmemmap_pages = mem->altmap->free; + ++ mem_hotplug_begin(); + if (nr_vmemmap_pages) + adjust_present_page_count(pfn_to_page(start_pfn), mem->group, + -nr_vmemmap_pages); +@@ -258,13 +268,15 @@ static int memory_block_offline(struct memory_block *mem) + if (nr_vmemmap_pages) + adjust_present_page_count(pfn_to_page(start_pfn), + mem->group, nr_vmemmap_pages); +- return ret; ++ goto out; + } + + if (nr_vmemmap_pages) + mhp_deinit_memmap_on_memory(start_pfn, nr_vmemmap_pages); + + mem->zone = NULL; ++out: ++ mem_hotplug_done(); + return ret; + } + +diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c +index 92592f944a3df..ac63a73ccdaaa 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/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c +index 30dedd6ebfde6..e887fd1690434 100644 +--- a/drivers/firmware/arm_scmi/perf.c ++++ b/drivers/firmware/arm_scmi/perf.c +@@ -145,7 +145,6 @@ struct scmi_msg_resp_perf_describe_levels_v4 { + struct perf_dom_info { + u32 id; + bool set_limits; +- bool set_perf; + bool perf_limit_notify; + bool perf_level_notify; + bool perf_fastchannels; +@@ -153,8 +152,8 @@ struct perf_dom_info { + u32 opp_count; + u32 sustained_freq_khz; + u32 sustained_perf_level; +- u32 mult_factor; +- char name[SCMI_MAX_STR_SIZE]; ++ unsigned long mult_factor; ++ struct scmi_perf_domain_info info; + struct scmi_opp opp[MAX_OPPS]; + struct scmi_fc_info *fc_info; + struct xarray opps_by_idx; +@@ -257,7 +256,7 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph, + flags = le32_to_cpu(attr->flags); + + dom_info->set_limits = SUPPORTS_SET_LIMITS(flags); +- dom_info->set_perf = SUPPORTS_SET_PERF_LVL(flags); ++ dom_info->info.set_perf = SUPPORTS_SET_PERF_LVL(flags); + dom_info->perf_limit_notify = SUPPORTS_PERF_LIMIT_NOTIFY(flags); + dom_info->perf_level_notify = SUPPORTS_PERF_LEVEL_NOTIFY(flags); + dom_info->perf_fastchannels = SUPPORTS_PERF_FASTCHANNELS(flags); +@@ -269,14 +268,16 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph, + dom_info->sustained_perf_level = + le32_to_cpu(attr->sustained_perf_level); + if (!dom_info->sustained_freq_khz || +- !dom_info->sustained_perf_level) ++ !dom_info->sustained_perf_level || ++ dom_info->level_indexing_mode) + /* CPUFreq converts to kHz, hence default 1000 */ + dom_info->mult_factor = 1000; + else + dom_info->mult_factor = +- (dom_info->sustained_freq_khz * 1000) / +- dom_info->sustained_perf_level; +- strscpy(dom_info->name, attr->name, SCMI_SHORT_NAME_MAX_SIZE); ++ (dom_info->sustained_freq_khz * 1000UL) ++ / dom_info->sustained_perf_level; ++ strscpy(dom_info->info.name, attr->name, ++ SCMI_SHORT_NAME_MAX_SIZE); + } + + ph->xops->xfer_put(ph, t); +@@ -288,7 +289,7 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph, + if (!ret && PROTOCOL_REV_MAJOR(version) >= 0x3 && + SUPPORTS_EXTENDED_NAMES(flags)) + ph->hops->extended_name_get(ph, PERF_DOMAIN_NAME_GET, +- dom_info->id, dom_info->name, ++ dom_info->id, dom_info->info.name, + SCMI_MAX_STR_SIZE); + + if (dom_info->level_indexing_mode) { +@@ -423,6 +424,36 @@ scmi_perf_describe_levels_get(const struct scmi_protocol_handle *ph, + return ret; + } + ++static int scmi_perf_num_domains_get(const struct scmi_protocol_handle *ph) ++{ ++ struct scmi_perf_info *pi = ph->get_priv(ph); ++ ++ return pi->num_domains; ++} ++ ++static inline struct perf_dom_info * ++scmi_perf_domain_lookup(const struct scmi_protocol_handle *ph, u32 domain) ++{ ++ struct scmi_perf_info *pi = ph->get_priv(ph); ++ ++ if (domain >= pi->num_domains) ++ return ERR_PTR(-EINVAL); ++ ++ return pi->dom_info + domain; ++} ++ ++static const struct scmi_perf_domain_info * ++scmi_perf_info_get(const struct scmi_protocol_handle *ph, u32 domain) ++{ ++ struct perf_dom_info *dom; ++ ++ dom = scmi_perf_domain_lookup(ph, domain); ++ if (IS_ERR(dom)) ++ return ERR_PTR(-EINVAL); ++ ++ return &dom->info; ++} ++ + static int scmi_perf_msg_limits_set(const struct scmi_protocol_handle *ph, + u32 domain, u32 max_perf, u32 min_perf) + { +@@ -446,17 +477,6 @@ static int scmi_perf_msg_limits_set(const struct scmi_protocol_handle *ph, + return ret; + } + +-static inline struct perf_dom_info * +-scmi_perf_domain_lookup(const struct scmi_protocol_handle *ph, u32 domain) +-{ +- struct scmi_perf_info *pi = ph->get_priv(ph); +- +- if (domain >= pi->num_domains) +- return ERR_PTR(-EINVAL); +- +- return pi->dom_info + domain; +-} +- + static int __scmi_perf_limits_set(const struct scmi_protocol_handle *ph, + struct perf_dom_info *dom, u32 max_perf, + u32 min_perf) +@@ -780,7 +800,6 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph, + { + int idx, ret, domain; + unsigned long freq; +- struct scmi_opp *opp; + struct perf_dom_info *dom; + + domain = scmi_dev_domain_id(dev); +@@ -791,28 +810,21 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph, + if (IS_ERR(dom)) + return PTR_ERR(dom); + +- for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) { ++ for (idx = 0; idx < dom->opp_count; idx++) { + if (!dom->level_indexing_mode) +- freq = opp->perf * dom->mult_factor; ++ freq = dom->opp[idx].perf * dom->mult_factor; + else +- freq = opp->indicative_freq * 1000; ++ freq = dom->opp[idx].indicative_freq * dom->mult_factor; + + ret = dev_pm_opp_add(dev, freq, 0); + if (ret) { + dev_warn(dev, "failed to add opp %luHz\n", freq); +- +- while (idx-- > 0) { +- if (!dom->level_indexing_mode) +- freq = (--opp)->perf * dom->mult_factor; +- else +- freq = (--opp)->indicative_freq * 1000; +- dev_pm_opp_remove(dev, freq); +- } ++ dev_pm_opp_remove_all_dynamic(dev); + return ret; + } + + dev_dbg(dev, "[%d][%s]:: Registered OPP[%d] %lu\n", +- domain, dom->name, idx, freq); ++ domain, dom->info.name, idx, freq); + } + return 0; + } +@@ -851,7 +863,8 @@ static int scmi_dvfs_freq_set(const struct scmi_protocol_handle *ph, u32 domain, + } else { + struct scmi_opp *opp; + +- opp = LOOKUP_BY_FREQ(dom->opps_by_freq, freq / 1000); ++ opp = LOOKUP_BY_FREQ(dom->opps_by_freq, ++ freq / dom->mult_factor); + if (!opp) + return -EIO; + +@@ -885,7 +898,7 @@ static int scmi_dvfs_freq_get(const struct scmi_protocol_handle *ph, u32 domain, + if (!opp) + return -EIO; + +- *freq = opp->indicative_freq * 1000; ++ *freq = opp->indicative_freq * dom->mult_factor; + } + + return ret; +@@ -908,7 +921,7 @@ static int scmi_dvfs_est_power_get(const struct scmi_protocol_handle *ph, + if (!dom->level_indexing_mode) + opp_freq = opp->perf * dom->mult_factor; + else +- opp_freq = opp->indicative_freq * 1000; ++ opp_freq = opp->indicative_freq * dom->mult_factor; + + if (opp_freq < *freq) + continue; +@@ -948,6 +961,8 @@ scmi_power_scale_get(const struct scmi_protocol_handle *ph) + } + + static const struct scmi_perf_proto_ops perf_proto_ops = { ++ .num_domains_get = scmi_perf_num_domains_get, ++ .info_get = scmi_perf_info_get, + .limits_set = scmi_perf_limits_set, + .limits_get = scmi_perf_limits_get, + .level_set = scmi_perf_level_set, +diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c +index 50503a4525eb0..c7c5c19ebc66f 100644 +--- a/drivers/gpio/gpiolib-sysfs.c ++++ b/drivers/gpio/gpiolib-sysfs.c +@@ -474,14 +474,17 @@ static ssize_t export_store(const 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 f4fd0d5bd9b68..c0a3afe81bb1a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -207,7 +207,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_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index a164857bdb9f4..94e91516952c4 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -3478,10 +3478,6 @@ static void amdgpu_device_set_mcbp(struct amdgpu_device *adev) + adev->gfx.mcbp = true; + else if (amdgpu_mcbp == 0) + adev->gfx.mcbp = false; +- else if ((adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 0, 0)) && +- (adev->ip_versions[GC_HWIP][0] < IP_VERSION(10, 0, 0)) && +- adev->gfx.num_gfx_rings) +- adev->gfx.mcbp = true; + + if (amdgpu_sriov_vf(adev)) + adev->gfx.mcbp = true; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h +index 09f6727e7c73a..4a8b33f55f6bc 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h +@@ -357,8 +357,9 @@ int amdgpu_doorbell_init(struct amdgpu_device *adev); + void amdgpu_doorbell_fini(struct amdgpu_device *adev); + int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev); + uint32_t amdgpu_doorbell_index_on_bar(struct amdgpu_device *adev, +- struct amdgpu_bo *db_bo, +- uint32_t doorbell_index); ++ struct amdgpu_bo *db_bo, ++ uint32_t doorbell_index, ++ uint32_t db_size); + + #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index)) + #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v)) +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c +index 8eee5d783a92b..3f3662e8b8710 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c +@@ -113,20 +113,25 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v) + * + * @adev: amdgpu_device pointer + * @db_bo: doorbell object's bo +- * @db_index: doorbell relative index in this doorbell object ++ * @doorbell_index: doorbell relative index in this doorbell object ++ * @db_size: doorbell size is in byte + * + * returns doorbell's absolute index in BAR + */ + uint32_t amdgpu_doorbell_index_on_bar(struct amdgpu_device *adev, +- struct amdgpu_bo *db_bo, +- uint32_t doorbell_index) ++ struct amdgpu_bo *db_bo, ++ uint32_t doorbell_index, ++ uint32_t db_size) + { + int db_bo_offset; + + db_bo_offset = amdgpu_bo_gpu_offset_no_check(db_bo); + +- /* doorbell index is 32 bit but doorbell's size is 64-bit, so *2 */ +- return db_bo_offset / sizeof(u32) + doorbell_index * 2; ++ /* doorbell index is 32 bit but doorbell's size can be 32 bit ++ * or 64 bit, so *db_size(in byte)/4 for alignment. ++ */ ++ return db_bo_offset / sizeof(u32) + doorbell_index * ++ DIV_ROUND_UP(db_size, 4); + } + + /** +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +index f9a5a2c0573e4..89550d3df68d8 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +@@ -2220,8 +2220,6 @@ static int gmc_v9_0_sw_fini(void *handle) + + if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 3)) + amdgpu_gmc_sysfs_fini(adev); +- adev->gmc.num_mem_partitions = 0; +- kfree(adev->gmc.mem_partitions); + + amdgpu_gmc_ras_fini(adev); + amdgpu_gem_force_release(adev); +@@ -2235,6 +2233,9 @@ static int gmc_v9_0_sw_fini(void *handle) + amdgpu_bo_free_kernel(&adev->gmc.pdb0_bo, NULL, &adev->gmc.ptr_pdb0); + amdgpu_bo_fini(adev); + ++ adev->gmc.num_mem_partitions = 0; ++ kfree(adev->gmc.mem_partitions); ++ + return 0; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c +index 784c4e0774707..3d8e579d5c4e8 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c ++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c +@@ -130,6 +130,9 @@ static void mmhub_v1_8_init_system_aperture_regs(struct amdgpu_device *adev) + uint64_t value; + int i; + ++ if (amdgpu_sriov_vf(adev)) ++ return; ++ + inst_mask = adev->aid_mask; + for_each_inst(i, inst_mask) { + /* Program the AGP BAR */ +@@ -139,9 +142,6 @@ static void mmhub_v1_8_init_system_aperture_regs(struct amdgpu_device *adev) + WREG32_SOC15(MMHUB, i, regMC_VM_AGP_TOP, + adev->gmc.agp_end >> 24); + +- if (amdgpu_sriov_vf(adev)) +- return; +- + /* Program the system aperture low logical page number. */ + WREG32_SOC15(MMHUB, i, regMC_VM_SYSTEM_APERTURE_LOW_ADDR, + min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); +diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +index 52d80f286b3dd..fe1995ed13be7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +@@ -60,7 +60,7 @@ MODULE_FIRMWARE("amdgpu/psp_14_0_0_ta.bin"); + #define GFX_CMD_USB_PD_USE_LFB 0x480 + + /* Retry times for vmbx ready wait */ +-#define PSP_VMBX_POLLING_LIMIT 20000 ++#define PSP_VMBX_POLLING_LIMIT 3000 + + /* VBIOS gfl defines */ + #define MBOX_READY_MASK 0x80000000 +@@ -161,14 +161,18 @@ static int psp_v13_0_wait_for_vmbx_ready(struct psp_context *psp) + static int psp_v13_0_wait_for_bootloader(struct psp_context *psp) + { + struct amdgpu_device *adev = psp->adev; +- int retry_loop, ret; ++ int retry_loop, retry_cnt, ret; + ++ retry_cnt = ++ (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(13, 0, 6)) ? ++ PSP_VMBX_POLLING_LIMIT : ++ 10; + /* Wait for bootloader to signify that it is ready having bit 31 of + * C2PMSG_35 set to 1. All other bits are expected to be cleared. + * If there is an error in processing command, bits[7:0] will be set. + * This is applicable for PSP v13.0.6 and newer. + */ +- for (retry_loop = 0; retry_loop < 10; retry_loop++) { ++ for (retry_loop = 0; retry_loop < retry_cnt; retry_loop++) { + ret = psp_wait_for( + psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), + 0x80000000, 0xffffffff, false); +diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c +index f5be40d7ba367..28094cd7d9c21 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc15.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c +@@ -325,7 +325,8 @@ static u32 soc15_get_xclk(struct amdgpu_device *adev) + u32 reference_clock = adev->clock.spll.reference_freq; + + if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0) || +- adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1)) ++ adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1) || ++ adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 6)) + return 10000; + if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 0) || + adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 1)) +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +index 0d3d538b64ebc..e07652e724965 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +@@ -407,7 +407,8 @@ static int allocate_doorbell(struct qcm_process_device *qpd, + + q->properties.doorbell_off = amdgpu_doorbell_index_on_bar(dev->adev, + qpd->proc_doorbells, +- q->doorbell_id); ++ q->doorbell_id, ++ dev->kfd->device_info.doorbell_size); + return 0; + } + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c +index 7b38537c7c99b..05c74887fd6fd 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c +@@ -161,7 +161,10 @@ void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd, + if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) + return NULL; + +- *doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev, kfd->doorbells, inx); ++ *doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev, ++ kfd->doorbells, ++ inx, ++ kfd->device_info.doorbell_size); + inx *= 2; + + pr_debug("Get kernel queue doorbell\n" +@@ -240,7 +243,10 @@ phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd) + return 0; + } + +- first_db_index = amdgpu_doorbell_index_on_bar(adev, pdd->qpd.proc_doorbells, 0); ++ first_db_index = amdgpu_doorbell_index_on_bar(adev, ++ pdd->qpd.proc_doorbells, ++ 0, ++ pdd->dev->kfd->device_info.doorbell_size); + return adev->doorbell.base + first_db_index * sizeof(uint32_t); + } + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +index adb5e4bdc0b20..77649392e2331 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +@@ -377,7 +377,8 @@ int pqm_create_queue(struct process_queue_manager *pqm, + */ + uint32_t first_db_index = amdgpu_doorbell_index_on_bar(pdd->dev->adev, + pdd->qpd.proc_doorbells, +- 0); ++ 0, ++ pdd->dev->kfd->device_info.doorbell_size); + + *p_doorbell_offset_in_process = (q->properties.doorbell_off + - first_db_index) * sizeof(uint32_t); +diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig +index ba82a1142adf7..3e6a4e2044c0e 100644 +--- a/drivers/gpu/drm/bridge/Kconfig ++++ b/drivers/gpu/drm/bridge/Kconfig +@@ -313,6 +313,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/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c +index 60794fcde1d50..554d4468aa7c0 100644 +--- a/drivers/gpu/drm/drm_atomic_helper.c ++++ b/drivers/gpu/drm/drm_atomic_helper.c +@@ -2012,7 +2012,7 @@ int drm_atomic_helper_commit(struct drm_device *dev, + return ret; + + drm_atomic_helper_async_commit(dev, state); +- drm_atomic_helper_cleanup_planes(dev, state); ++ drm_atomic_helper_unprepare_planes(dev, state); + + return 0; + } +@@ -2072,7 +2072,7 @@ int drm_atomic_helper_commit(struct drm_device *dev, + return 0; + + err: +- drm_atomic_helper_cleanup_planes(dev, state); ++ drm_atomic_helper_unprepare_planes(dev, state); + return ret; + } + EXPORT_SYMBOL(drm_atomic_helper_commit); +@@ -2650,6 +2650,39 @@ fail_prepare_fb: + } + EXPORT_SYMBOL(drm_atomic_helper_prepare_planes); + ++/** ++ * drm_atomic_helper_unprepare_planes - release plane resources on aborts ++ * @dev: DRM device ++ * @state: atomic state object with old state structures ++ * ++ * This function cleans up plane state, specifically framebuffers, from the ++ * atomic state. It undoes the effects of drm_atomic_helper_prepare_planes() ++ * when aborting an atomic commit. For cleaning up after a successful commit ++ * use drm_atomic_helper_cleanup_planes(). ++ */ ++void drm_atomic_helper_unprepare_planes(struct drm_device *dev, ++ struct drm_atomic_state *state) ++{ ++ struct drm_plane *plane; ++ struct drm_plane_state *new_plane_state; ++ int i; ++ ++ for_each_new_plane_in_state(state, plane, new_plane_state, i) { ++ const struct drm_plane_helper_funcs *funcs = plane->helper_private; ++ ++ if (funcs->end_fb_access) ++ funcs->end_fb_access(plane, new_plane_state); ++ } ++ ++ for_each_new_plane_in_state(state, plane, new_plane_state, i) { ++ const struct drm_plane_helper_funcs *funcs = plane->helper_private; ++ ++ if (funcs->cleanup_fb) ++ funcs->cleanup_fb(plane, new_plane_state); ++ } ++} ++EXPORT_SYMBOL(drm_atomic_helper_unprepare_planes); ++ + static bool plane_crtc_active(const struct drm_plane_state *state) + { + return state->crtc && state->crtc->state->active; +@@ -2784,6 +2817,17 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, + + funcs->atomic_flush(crtc, old_state); + } ++ ++ /* ++ * Signal end of framebuffer access here before hw_done. After hw_done, ++ * a later commit might have already released the plane state. ++ */ ++ for_each_old_plane_in_state(old_state, plane, old_plane_state, i) { ++ const struct drm_plane_helper_funcs *funcs = plane->helper_private; ++ ++ if (funcs->end_fb_access) ++ funcs->end_fb_access(plane, old_plane_state); ++ } + } + EXPORT_SYMBOL(drm_atomic_helper_commit_planes); + +@@ -2911,40 +2955,22 @@ EXPORT_SYMBOL(drm_atomic_helper_disable_planes_on_crtc); + * configuration. Hence the old configuration must be perserved in @old_state to + * be able to call this function. + * +- * This function must also be called on the new state when the atomic update +- * fails at any point after calling drm_atomic_helper_prepare_planes(). ++ * This function may not be called on the new state when the atomic update ++ * fails at any point after calling drm_atomic_helper_prepare_planes(). Use ++ * drm_atomic_helper_unprepare_planes() in this case. + */ + void drm_atomic_helper_cleanup_planes(struct drm_device *dev, + struct drm_atomic_state *old_state) + { + struct drm_plane *plane; +- struct drm_plane_state *old_plane_state, *new_plane_state; ++ struct drm_plane_state *old_plane_state; + int i; + +- for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) { ++ for_each_old_plane_in_state(old_state, plane, old_plane_state, i) { + const struct drm_plane_helper_funcs *funcs = plane->helper_private; + +- if (funcs->end_fb_access) +- funcs->end_fb_access(plane, new_plane_state); +- } +- +- for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) { +- const struct drm_plane_helper_funcs *funcs; +- struct drm_plane_state *plane_state; +- +- /* +- * This might be called before swapping when commit is aborted, +- * in which case we have to cleanup the new state. +- */ +- if (old_plane_state == plane->state) +- plane_state = new_plane_state; +- else +- plane_state = old_plane_state; +- +- funcs = plane->helper_private; +- + if (funcs->cleanup_fb) +- funcs->cleanup_fb(plane, plane_state); ++ funcs->cleanup_fb(plane, old_plane_state); + } + } + EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes); +diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c +index ad6488e9c2b2b..5b8efe8e735a9 100644 +--- a/drivers/gpu/drm/i915/display/icl_dsi.c ++++ b/drivers/gpu/drm/i915/display/icl_dsi.c +@@ -1440,6 +1440,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 8090747586877..d23020eb87f46 100644 +--- a/drivers/gpu/drm/i915/display/intel_crt.c ++++ b/drivers/gpu/drm/i915/display/intel_crt.c +@@ -348,8 +348,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 763ab569d8f32..1e2b09ae09b9c 100644 +--- a/drivers/gpu/drm/i915/display/intel_display.c ++++ b/drivers/gpu/drm/i915/display/intel_display.c +@@ -7279,7 +7279,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) + intel_color_cleanup_commit(new_crtc_state); + +- drm_atomic_helper_cleanup_planes(dev, &state->base); ++ drm_atomic_helper_unprepare_planes(dev, &state->base); + intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); + return ret; + } +@@ -7660,6 +7660,16 @@ enum drm_mode_status 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 49ac8473b988b..13b0904d42e3d 100644 +--- a/drivers/gpu/drm/i915/display/intel_display.h ++++ b/drivers/gpu/drm/i915/display/intel_display.h +@@ -405,6 +405,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 is_trans_port_sync_master(const struct intel_crtc_state *state); +diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c +index 119a4de7fe6f7..66e35f8443e1a 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -1127,6 +1127,10 @@ intel_dp_mode_valid(struct drm_connector *_connector, + enum drm_mode_status status; + bool dsc = false, bigjoiner = false; + ++ 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 e3f176a093d2f..77bd1313c808f 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c +@@ -921,6 +921,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; +@@ -955,6 +959,10 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, + if (intel_dp_need_bigjoiner(intel_dp, mode->hdisplay, target_clock)) { + bigjoiner = true; + max_dotclk *= 2; ++ ++ /* TODO: add support for bigjoiner */ ++ *status = MODE_CLOCK_HIGH; ++ return 0; + } + + if (DISPLAY_VER(dev_priv) >= 10 && +@@ -988,11 +996,15 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, + * Big joiner configuration needs DSC for TGL which is not true for + * XE_LPD where uncompressed joiner is supported. + */ +- if (DISPLAY_VER(dev_priv) < 13 && bigjoiner && !dsc) +- return MODE_CLOCK_HIGH; ++ if (DISPLAY_VER(dev_priv) < 13 && bigjoiner && !dsc) { ++ *status = MODE_CLOCK_HIGH; ++ return 0; ++ } + +- if (mode_rate > max_rate && !dsc) +- return MODE_CLOCK_HIGH; ++ if (mode_rate > max_rate && !dsc) { ++ *status = MODE_CLOCK_HIGH; ++ return 0; ++ } + + *status = intel_mode_valid_max_plane_size(dev_priv, mode, false); + return 0; +diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c +index b386894c3a6db..d1cfa966d48da 100644 +--- a/drivers/gpu/drm/i915/display/intel_dvo.c ++++ b/drivers/gpu/drm/i915/display/intel_dvo.c +@@ -217,11 +217,17 @@ intel_dvo_mode_valid(struct drm_connector *_connector, + struct drm_display_mode *mode) + { + struct intel_connector *connector = to_intel_connector(_connector); ++ struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_dvo *intel_dvo = intel_attached_dvo(connector); + const struct drm_display_mode *fixed_mode = + intel_panel_fixed_mode(connector, mode); + int max_dotclk = to_i915(connector->base.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 94a7e1537f427..bc975918e0eb4 100644 +--- a/drivers/gpu/drm/i915/display/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/display/intel_hdmi.c +@@ -1986,6 +1986,10 @@ intel_hdmi_mode_valid(struct drm_connector *connector, + bool ycbcr_420_only; + enum intel_output_format sink_format; + ++ 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 3ace56979b70e..dcb07d9a739d9 100644 +--- a/drivers/gpu/drm/i915/display/intel_lvds.c ++++ b/drivers/gpu/drm/i915/display/intel_lvds.c +@@ -389,11 +389,16 @@ intel_lvds_mode_valid(struct drm_connector *_connector, + struct drm_display_mode *mode) + { + struct intel_connector *connector = to_intel_connector(_connector); ++ struct drm_i915_private *i915 = to_i915(connector->base.dev); + const struct drm_display_mode *fixed_mode = + intel_panel_fixed_mode(connector, mode); + int max_pixclk = to_i915(connector->base.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 7d25a64698e2f..0ce935efe5dfd 100644 +--- a/drivers/gpu/drm/i915/display/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/display/intel_sdvo.c +@@ -1906,13 +1906,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, 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; + +diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c +index 36b479b46b600..d84a79491da23 100644 +--- a/drivers/gpu/drm/i915/display/intel_tv.c ++++ b/drivers/gpu/drm/i915/display/intel_tv.c +@@ -958,8 +958,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 a96e7d028c5c6..d778b88413b77 100644 +--- a/drivers/gpu/drm/i915/display/vlv_dsi.c ++++ b/drivers/gpu/drm/i915/display/vlv_dsi.c +@@ -1540,9 +1540,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/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c +index 4e7c9c353c511..617162aac060f 100644 +--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c ++++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c +@@ -2310,7 +2310,7 @@ nv50_disp_atomic_commit(struct drm_device *dev, + + err_cleanup: + if (ret) +- drm_atomic_helper_cleanup_planes(dev, state); ++ drm_atomic_helper_unprepare_planes(dev, state); + done: + pm_runtime_put_autosuspend(dev->dev); + return ret; +diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/event.h b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h +index 82b267c111470..460459af272d6 100644 +--- a/drivers/gpu/drm/nouveau/include/nvkm/core/event.h ++++ b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h +@@ -14,7 +14,7 @@ struct nvkm_event { + int index_nr; + + spinlock_t refs_lock; +- spinlock_t list_lock; ++ rwlock_t list_lock; + int *refs; + + struct list_head ntfy; +@@ -38,7 +38,7 @@ nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *subdev, + int types_nr, int index_nr, struct nvkm_event *event) + { + spin_lock_init(&event->refs_lock); +- spin_lock_init(&event->list_lock); ++ rwlock_init(&event->list_lock); + return __nvkm_event_init(func, subdev, types_nr, index_nr, event); + } + +diff --git a/drivers/gpu/drm/nouveau/nvkm/core/event.c b/drivers/gpu/drm/nouveau/nvkm/core/event.c +index a6c877135598f..61fed7792e415 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/core/event.c ++++ b/drivers/gpu/drm/nouveau/nvkm/core/event.c +@@ -81,17 +81,17 @@ nvkm_event_ntfy_state(struct nvkm_event_ntfy *ntfy) + static void + nvkm_event_ntfy_remove(struct nvkm_event_ntfy *ntfy) + { +- spin_lock_irq(&ntfy->event->list_lock); ++ write_lock_irq(&ntfy->event->list_lock); + list_del_init(&ntfy->head); +- spin_unlock_irq(&ntfy->event->list_lock); ++ write_unlock_irq(&ntfy->event->list_lock); + } + + static void + nvkm_event_ntfy_insert(struct nvkm_event_ntfy *ntfy) + { +- spin_lock_irq(&ntfy->event->list_lock); ++ write_lock_irq(&ntfy->event->list_lock); + list_add_tail(&ntfy->head, &ntfy->event->ntfy); +- spin_unlock_irq(&ntfy->event->list_lock); ++ write_unlock_irq(&ntfy->event->list_lock); + } + + static void +@@ -176,7 +176,7 @@ nvkm_event_ntfy(struct nvkm_event *event, int id, u32 bits) + return; + + nvkm_trace(event->subdev, "event: ntfy %08x on %d\n", bits, id); +- spin_lock_irqsave(&event->list_lock, flags); ++ read_lock_irqsave(&event->list_lock, flags); + + list_for_each_entry_safe(ntfy, ntmp, &event->ntfy, head) { + if (ntfy->id == id && ntfy->bits & bits) { +@@ -185,7 +185,7 @@ nvkm_event_ntfy(struct nvkm_event *event, int id, u32 bits) + } + } + +- spin_unlock_irqrestore(&event->list_lock, flags); ++ read_unlock_irqrestore(&event->list_lock, flags); + } + + void +diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c +index fa28d447f0dfb..b772c076a5aed 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 428c77b5fce5a..7caf387eb1449 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-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c +index 5ca6278baff4f..89e8ed214ea49 100644 +--- a/drivers/hwtracing/coresight/coresight-etm-perf.c ++++ b/drivers/hwtracing/coresight/coresight-etm-perf.c +@@ -493,7 +493,7 @@ static void etm_event_start(struct perf_event *event, int flags) + goto fail_end_stop; + + /* Finally enable the tracer */ +- if (coresight_enable_source(csdev, CS_MODE_PERF, event)) ++ if (source_ops(csdev)->enable(csdev, event, CS_MODE_PERF)) + goto fail_disable_path; + + /* +@@ -587,7 +587,7 @@ static void etm_event_stop(struct perf_event *event, int mode) + return; + + /* stop tracer */ +- coresight_disable_source(csdev, event); ++ source_ops(csdev)->disable(csdev, event); + + /* tell the core */ + event->hw.state = PERF_HES_STOPPED; +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 77b0271ce6eb9..34aee59dd1473 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -2224,7 +2224,7 @@ static void clear_etmdrvdata(void *info) + per_cpu(delayed_probe, cpu) = NULL; + } + +-static void __exit etm4_remove_dev(struct etmv4_drvdata *drvdata) ++static void etm4_remove_dev(struct etmv4_drvdata *drvdata) + { + bool had_delayed_probe; + /* +@@ -2253,7 +2253,7 @@ static void __exit etm4_remove_dev(struct etmv4_drvdata *drvdata) + } + } + +-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); + +@@ -2261,7 +2261,7 @@ 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) + { + struct etmv4_drvdata *drvdata = dev_get_drvdata(&pdev->dev); + +diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c +index e9a32a97fbee6..6e32d31a95fe0 100644 +--- a/drivers/hwtracing/coresight/ultrasoc-smb.c ++++ b/drivers/hwtracing/coresight/ultrasoc-smb.c +@@ -99,7 +99,7 @@ static int smb_open(struct inode *inode, struct file *file) + struct smb_drv_data, miscdev); + int ret = 0; + +- mutex_lock(&drvdata->mutex); ++ spin_lock(&drvdata->spinlock); + + if (drvdata->reading) { + ret = -EBUSY; +@@ -115,7 +115,7 @@ static int smb_open(struct inode *inode, struct file *file) + + drvdata->reading = true; + out: +- mutex_unlock(&drvdata->mutex); ++ spin_unlock(&drvdata->spinlock); + + return ret; + } +@@ -132,10 +132,8 @@ static ssize_t smb_read(struct file *file, char __user *data, size_t len, + if (!len) + return 0; + +- mutex_lock(&drvdata->mutex); +- + if (!sdb->data_size) +- goto out; ++ return 0; + + to_copy = min(sdb->data_size, len); + +@@ -145,20 +143,15 @@ static ssize_t smb_read(struct file *file, char __user *data, size_t len, + + if (copy_to_user(data, sdb->buf_base + sdb->buf_rdptr, to_copy)) { + dev_dbg(dev, "Failed to copy data to user\n"); +- to_copy = -EFAULT; +- goto out; ++ return -EFAULT; + } + + *ppos += to_copy; +- + smb_update_read_ptr(drvdata, to_copy); +- +- dev_dbg(dev, "%zu bytes copied\n", to_copy); +-out: + if (!sdb->data_size) + smb_reset_buffer(drvdata); +- mutex_unlock(&drvdata->mutex); + ++ dev_dbg(dev, "%zu bytes copied\n", to_copy); + return to_copy; + } + +@@ -167,9 +160,9 @@ static int smb_release(struct inode *inode, struct file *file) + struct smb_drv_data *drvdata = container_of(file->private_data, + struct smb_drv_data, miscdev); + +- mutex_lock(&drvdata->mutex); ++ spin_lock(&drvdata->spinlock); + drvdata->reading = false; +- mutex_unlock(&drvdata->mutex); ++ spin_unlock(&drvdata->spinlock); + + return 0; + } +@@ -262,7 +255,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode, + struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent); + int ret = 0; + +- mutex_lock(&drvdata->mutex); ++ spin_lock(&drvdata->spinlock); + + /* Do nothing, the trace data is reading by other interface now */ + if (drvdata->reading) { +@@ -294,7 +287,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode, + + dev_dbg(&csdev->dev, "Ultrasoc SMB enabled\n"); + out: +- mutex_unlock(&drvdata->mutex); ++ spin_unlock(&drvdata->spinlock); + + return ret; + } +@@ -304,7 +297,7 @@ static int smb_disable(struct coresight_device *csdev) + struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent); + int ret = 0; + +- mutex_lock(&drvdata->mutex); ++ spin_lock(&drvdata->spinlock); + + if (drvdata->reading) { + ret = -EBUSY; +@@ -327,7 +320,7 @@ static int smb_disable(struct coresight_device *csdev) + + dev_dbg(&csdev->dev, "Ultrasoc SMB disabled\n"); + out: +- mutex_unlock(&drvdata->mutex); ++ spin_unlock(&drvdata->spinlock); + + return ret; + } +@@ -408,7 +401,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev, + if (!buf) + return 0; + +- mutex_lock(&drvdata->mutex); ++ spin_lock(&drvdata->spinlock); + + /* Don't do anything if another tracer is using this sink. */ + if (atomic_read(&csdev->refcnt) != 1) +@@ -432,7 +425,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev, + if (!buf->snapshot && lost) + perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + out: +- mutex_unlock(&drvdata->mutex); ++ spin_unlock(&drvdata->spinlock); + + return data_size; + } +@@ -484,7 +477,6 @@ static int smb_init_data_buffer(struct platform_device *pdev, + static void smb_init_hw(struct smb_drv_data *drvdata) + { + smb_disable_hw(drvdata); +- smb_reset_buffer(drvdata); + + writel(SMB_LB_CFG_LO_DEFAULT, drvdata->base + SMB_LB_CFG_LO_REG); + writel(SMB_LB_CFG_HI_DEFAULT, drvdata->base + SMB_LB_CFG_HI_REG); +@@ -590,37 +582,33 @@ static int smb_probe(struct platform_device *pdev) + return ret; + } + +- mutex_init(&drvdata->mutex); ++ ret = smb_config_inport(dev, true); ++ if (ret) ++ return ret; ++ ++ smb_reset_buffer(drvdata); ++ platform_set_drvdata(pdev, drvdata); ++ spin_lock_init(&drvdata->spinlock); + drvdata->pid = -1; + + ret = smb_register_sink(pdev, drvdata); + if (ret) { ++ smb_config_inport(&pdev->dev, false); + dev_err(dev, "Failed to register SMB sink\n"); + return ret; + } + +- ret = smb_config_inport(dev, true); +- if (ret) { +- smb_unregister_sink(drvdata); +- return ret; +- } +- +- platform_set_drvdata(pdev, drvdata); +- + return 0; + } + + static int smb_remove(struct platform_device *pdev) + { + struct smb_drv_data *drvdata = platform_get_drvdata(pdev); +- int ret; +- +- ret = smb_config_inport(&pdev->dev, false); +- if (ret) +- return ret; + + smb_unregister_sink(drvdata); + ++ smb_config_inport(&pdev->dev, false); ++ + return 0; + } + +diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.h b/drivers/hwtracing/coresight/ultrasoc-smb.h +index d2e14e8d2c8a8..82a44c14a8829 100644 +--- a/drivers/hwtracing/coresight/ultrasoc-smb.h ++++ b/drivers/hwtracing/coresight/ultrasoc-smb.h +@@ -8,7 +8,7 @@ + #define _ULTRASOC_SMB_H + + #include <linux/miscdevice.h> +-#include <linux/mutex.h> ++#include <linux/spinlock.h> + + /* Offset of SMB global registers */ + #define SMB_GLB_CFG_REG 0x00 +@@ -105,7 +105,7 @@ struct smb_data_buffer { + * @csdev: Component vitals needed by the framework. + * @sdb: Data buffer for SMB. + * @miscdev: Specifics to handle "/dev/xyz.smb" entry. +- * @mutex: Control data access to one at a time. ++ * @spinlock: Control data access to one at a time. + * @reading: Synchronise user space access to SMB buffer. + * @pid: Process ID of the process being monitored by the + * session that is using this component. +@@ -116,7 +116,7 @@ struct smb_drv_data { + struct coresight_device *csdev; + struct smb_data_buffer sdb; + struct miscdevice miscdev; +- struct mutex mutex; ++ spinlock_t spinlock; + bool reading; + pid_t pid; + enum cs_mode mode; +diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c +index 49ea1b0f74890..3045d1894b81b 100644 +--- a/drivers/hwtracing/ptt/hisi_ptt.c ++++ b/drivers/hwtracing/ptt/hisi_ptt.c +@@ -1178,6 +1178,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); +@@ -1221,6 +1225,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 affcfb243f0f5..35f762872b8a5 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/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c +index 041a76f71a49c..e106af83cef4d 100644 +--- a/drivers/i2c/busses/i2c-ocores.c ++++ b/drivers/i2c/busses/i2c-ocores.c +@@ -771,8 +771,8 @@ static int ocores_i2c_resume(struct device *dev) + return ocores_init(dev, i2c); + } + +-static DEFINE_SIMPLE_DEV_PM_OPS(ocores_i2c_pm, +- ocores_i2c_suspend, ocores_i2c_resume); ++static DEFINE_NOIRQ_DEV_PM_OPS(ocores_i2c_pm, ++ ocores_i2c_suspend, ocores_i2c_resume); + + static struct platform_driver ocores_i2c_driver = { + .probe = ocores_i2c_probe, +diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c +index f9ab671c8eda5..07c571c7b6999 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/core/verbs.c b/drivers/infiniband/core/verbs.c +index 41ff5595c8606..186ed3c22ec9e 100644 +--- a/drivers/infiniband/core/verbs.c ++++ b/drivers/infiniband/core/verbs.c +@@ -1968,7 +1968,7 @@ int ib_get_eth_speed(struct ib_device *dev, u32 port_num, u16 *speed, u8 *width) + int rc; + u32 netdev_speed; + struct net_device *netdev; +- struct ethtool_link_ksettings lksettings; ++ struct ethtool_link_ksettings lksettings = {}; + + if (rdma_port_get_link_layer(dev, port_num) != IB_LINK_LAYER_ETHERNET) + return -EINVAL; +diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c +index c9066aade4125..039801d93ed8a 100644 +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -71,7 +71,7 @@ static char version[] = + BNXT_RE_DESC "\n"; + + MODULE_AUTHOR("Eddie Wai <eddie.wai@broadcom.com>"); +-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 58d14f1562b9a..486d635b6e3ab 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -4755,10 +4755,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 7cbdd5433dba5..564c9188e1f84 100644 +--- a/drivers/infiniband/hw/irdma/hw.c ++++ b/drivers/infiniband/hw/irdma/hw.c +@@ -321,7 +321,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; +@@ -581,9 +585,6 @@ static void irdma_destroy_cqp(struct irdma_pci_f *rf) + struct irdma_cqp *cqp = &rf->cqp; + int status = 0; + +- if (rf->cqp_cmpl_wq) +- destroy_workqueue(rf->cqp_cmpl_wq); +- + status = irdma_sc_cqp_destroy(dev->cqp); + if (status) + ibdev_dbg(to_ibdev(dev), "ERR: Destroy CQP failed %d\n", status); +@@ -748,6 +749,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) +@@ -1180,7 +1184,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; +@@ -1201,14 +1204,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) { +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 82fc5f5b002c0..cbf0db72e1088 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 3eb7a7a3a975d..2f1bedd3a5201 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -1157,6 +1157,21 @@ exit: + return prio; + } + ++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 +@@ -1420,17 +1435,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) { +@@ -1467,6 +1476,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; +@@ -2889,7 +2903,7 @@ static struct irdma_mr *irdma_alloc_iwmr(struct ib_umem *region, + iwmr->type = reg_type; + + pgsz_bitmap = (reg_type == IRDMA_MEMREG_TYPE_MEM) ? +- iwdev->rf->sc_dev.hw_attrs.page_size_cap : PAGE_SIZE; ++ iwdev->rf->sc_dev.hw_attrs.page_size_cap : SZ_4K; + + iwmr->page_size = ib_umem_find_best_pgsz(region, pgsz_bitmap, virt); + if (unlikely(!iwmr->page_size)) { +@@ -2921,6 +2935,11 @@ static int irdma_reg_user_mr_type_qp(struct irdma_mem_reg_req req, + int err; + u8 lvl; + ++ /* iWarp: Catch page not starting on OS page boundary */ ++ if (!rdma_protocol_roce(&iwdev->ibdev, 1) && ++ ib_umem_offset(iwmr->region)) ++ return -EINVAL; ++ + total = req.sq_pages + req.rq_pages + 1; + if (total > iwmr->page_cnt) + return -EINVAL; +diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h +index 5d7b983f47a24..20297a14c9a61 100644 +--- a/drivers/infiniband/hw/irdma/verbs.h ++++ b/drivers/infiniband/hw/irdma/verbs.h +@@ -196,6 +196,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 b6ee801fd0ffb..1aee62aa1515d 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c +@@ -384,7 +384,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; +@@ -2345,8 +2345,6 @@ static int init_conns(struct rtrs_clt_path *clt_path) + if (err) + goto destroy; + +- rtrs_start_hb(&clt_path->s); +- + return 0; + + destroy: +@@ -2620,6 +2618,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 75e56604e4628..1d33efb8fb03b 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -65,8 +65,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: +@@ -87,7 +88,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; + } +@@ -550,7 +551,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); +@@ -709,20 +713,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) +@@ -851,7 +858,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); + + /* +@@ -860,7 +872,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, +@@ -1516,7 +1532,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++) { +@@ -1536,6 +1551,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/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c +index e358e77e4b38f..d76214fa9ad86 100644 +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -226,6 +226,11 @@ static int set_device_name(struct led_netdev_data *trigger_data, + + cancel_delayed_work_sync(&trigger_data->work); + ++ /* ++ * Take RTNL lock before trigger_data lock to prevent potential ++ * deadlock with netdev notifier registration. ++ */ ++ rtnl_lock(); + mutex_lock(&trigger_data->lock); + + if (trigger_data->net_dev) { +@@ -245,16 +250,14 @@ static int set_device_name(struct led_netdev_data *trigger_data, + trigger_data->carrier_link_up = false; + trigger_data->link_speed = SPEED_UNKNOWN; + trigger_data->duplex = DUPLEX_UNKNOWN; +- if (trigger_data->net_dev != NULL) { +- rtnl_lock(); ++ if (trigger_data->net_dev) + get_device_state(trigger_data); +- rtnl_unlock(); +- } + + trigger_data->last_activity = 0; + + set_baseline_state(trigger_data); + mutex_unlock(&trigger_data->lock); ++ rtnl_unlock(); + + return 0; + } +diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c +index cef9353370b20..17ffbf7fbe73e 100644 +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -1679,7 +1679,7 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned int size) + unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; + gfp_t gfp_mask = GFP_NOWAIT | __GFP_HIGHMEM; + unsigned int remaining_size; +- unsigned int order = MAX_ORDER - 1; ++ unsigned int order = MAX_ORDER; + + retry: + if (unlikely(gfp_mask & __GFP_DIRECT_RECLAIM)) +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 2748b0b424cfe..b2ef6af8376a5 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -6316,6 +6316,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); +@@ -6330,8 +6333,6 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) + */ + md_wakeup_thread_directly(mddev->sync_thread); + +- 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)); +@@ -6344,29 +6345,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 == MD_RDONLY) ++ if (mddev->ro == MD_RDONLY) { ++ err = -ENXIO; + goto out; ++ } ++ + 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; + } +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 284cd71bcc685..68d86dbecb4ac 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -5892,11 +5892,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 5c19097266fe0..32f2287823184 100644 +--- a/drivers/misc/mei/client.c ++++ b/drivers/misc/mei/client.c +@@ -2011,7 +2011,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, unsigned long time + + 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; + } +@@ -2032,7 +2032,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, unsigned long time + + 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/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c +index 42db7679c3606..286e20f340e5c 100644 +--- a/drivers/net/dsa/microchip/ksz_common.c ++++ b/drivers/net/dsa/microchip/ksz_common.c +@@ -2624,10 +2624,18 @@ static int ksz_connect_tag_protocol(struct dsa_switch *ds, + { + struct ksz_tagger_data *tagger_data; + +- tagger_data = ksz_tagger_data(ds); +- tagger_data->xmit_work_fn = ksz_port_deferred_xmit; +- +- return 0; ++ switch (proto) { ++ case DSA_TAG_PROTO_KSZ8795: ++ return 0; ++ case DSA_TAG_PROTO_KSZ9893: ++ case DSA_TAG_PROTO_KSZ9477: ++ case DSA_TAG_PROTO_LAN937X: ++ tagger_data = ksz_tagger_data(ds); ++ tagger_data->xmit_work_fn = ksz_port_deferred_xmit; ++ return 0; ++ default: ++ return -EPROTONOSUPPORT; ++ } + } + + static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, +diff --git a/drivers/net/dsa/mv88e6xxx/pcs-639x.c b/drivers/net/dsa/mv88e6xxx/pcs-639x.c +index ba373656bfe14..c31f0e54f1e64 100644 +--- a/drivers/net/dsa/mv88e6xxx/pcs-639x.c ++++ b/drivers/net/dsa/mv88e6xxx/pcs-639x.c +@@ -465,6 +465,7 @@ mv88e639x_pcs_select(struct mv88e6xxx_chip *chip, int port, + case PHY_INTERFACE_MODE_10GBASER: + case PHY_INTERFACE_MODE_XAUI: + case PHY_INTERFACE_MODE_RXAUI: ++ case PHY_INTERFACE_MODE_USXGMII: + return &mpcs->xg_pcs; + + default: +@@ -873,7 +874,8 @@ static int mv88e6393x_xg_pcs_post_config(struct phylink_pcs *pcs, + struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs); + int err; + +- if (interface == PHY_INTERFACE_MODE_10GBASER) { ++ if (interface == PHY_INTERFACE_MODE_10GBASER || ++ interface == PHY_INTERFACE_MODE_USXGMII) { + err = mv88e6393x_erratum_5_2(mpcs); + if (err) + return err; +@@ -886,12 +888,37 @@ static int mv88e6393x_xg_pcs_post_config(struct phylink_pcs *pcs, + return mv88e639x_xg_pcs_enable(mpcs); + } + ++static void mv88e6393x_xg_pcs_get_state(struct phylink_pcs *pcs, ++ struct phylink_link_state *state) ++{ ++ struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs); ++ u16 status, lp_status; ++ int err; ++ ++ if (state->interface != PHY_INTERFACE_MODE_USXGMII) ++ return mv88e639x_xg_pcs_get_state(pcs, state); ++ ++ state->link = false; ++ ++ err = mv88e639x_read(mpcs, MV88E6390_USXGMII_PHY_STATUS, &status); ++ err = err ? : mv88e639x_read(mpcs, MV88E6390_USXGMII_LP_STATUS, &lp_status); ++ if (err) { ++ dev_err(mpcs->mdio.dev.parent, ++ "can't read USXGMII status: %pe\n", ERR_PTR(err)); ++ return; ++ } ++ ++ state->link = !!(status & MDIO_USXGMII_LINK); ++ state->an_complete = state->link; ++ phylink_decode_usxgmii_word(state, lp_status); ++} ++ + static const struct phylink_pcs_ops mv88e6393x_xg_pcs_ops = { + .pcs_enable = mv88e6393x_xg_pcs_enable, + .pcs_disable = mv88e6393x_xg_pcs_disable, + .pcs_pre_config = mv88e6393x_xg_pcs_pre_config, + .pcs_post_config = mv88e6393x_xg_pcs_post_config, +- .pcs_get_state = mv88e639x_xg_pcs_get_state, ++ .pcs_get_state = mv88e6393x_xg_pcs_get_state, + .pcs_config = mv88e639x_xg_pcs_config, + }; + +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 4de22eed099a8..694daeaf3e615 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 38d89d80b4a9c..273c9ba48f09a 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 22b00912f7ac8..b7acd994a393b 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -6845,7 +6845,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; + } + +@@ -7874,8 +7874,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); +@@ -8146,7 +8148,7 @@ dma_error: + drop: + dev_kfree_skb_any(skb); + drop_nofree: +- tp->tx_dropped++; ++ tnapi->tx_dropped++; + return NETDEV_TX_OK; + } + +@@ -9325,7 +9327,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); + +@@ -9346,6 +9348,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; +@@ -11895,6 +11904,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) + +@@ -11941,8 +11953,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 00ca2b88165cb..a9f5a8a7d3f05 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -16195,7 +16195,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 90397293525f7..1b412754aa422 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/intel/ice/ice_vf_vsi_vlan_ops.c b/drivers/net/ethernet/intel/ice/ice_vf_vsi_vlan_ops.c +index d7b10dc67f035..80dc4bcdd3a41 100644 +--- a/drivers/net/ethernet/intel/ice/ice_vf_vsi_vlan_ops.c ++++ b/drivers/net/ethernet/intel/ice/ice_vf_vsi_vlan_ops.c +@@ -32,7 +32,6 @@ static void ice_port_vlan_on(struct ice_vsi *vsi) + /* setup outer VLAN ops */ + vlan_ops->set_port_vlan = ice_vsi_set_outer_port_vlan; + vlan_ops->clear_port_vlan = ice_vsi_clear_outer_port_vlan; +- vlan_ops->clear_port_vlan = ice_vsi_clear_outer_port_vlan; + + /* setup inner VLAN ops */ + vlan_ops = &vsi->inner_vlan_ops; +@@ -47,8 +46,13 @@ static void ice_port_vlan_on(struct ice_vsi *vsi) + + vlan_ops->set_port_vlan = ice_vsi_set_inner_port_vlan; + vlan_ops->clear_port_vlan = ice_vsi_clear_inner_port_vlan; +- vlan_ops->clear_port_vlan = ice_vsi_clear_inner_port_vlan; + } ++ ++ /* all Rx traffic should be in the domain of the assigned port VLAN, ++ * so prevent disabling Rx VLAN filtering ++ */ ++ vlan_ops->dis_rx_filtering = noop_vlan; ++ + vlan_ops->ena_rx_filtering = ice_vsi_ena_rx_vlan_filtering; + } + +@@ -77,6 +81,8 @@ static void ice_port_vlan_off(struct ice_vsi *vsi) + vlan_ops->del_vlan = ice_vsi_del_vlan; + } + ++ vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering; ++ + if (!test_bit(ICE_FLAG_VF_VLAN_PRUNING, pf->flags)) + vlan_ops->ena_rx_filtering = noop_vlan; + else +@@ -141,7 +147,6 @@ void ice_vf_vsi_init_vlan_ops(struct ice_vsi *vsi) + &vsi->outer_vlan_ops : &vsi->inner_vlan_ops; + + vlan_ops->add_vlan = ice_vsi_add_vlan; +- vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering; + vlan_ops->ena_tx_filtering = ice_vsi_ena_tx_vlan_filtering; + vlan_ops->dis_tx_filtering = ice_vsi_dis_tx_vlan_filtering; + } +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +index 6b5b06c2b4e99..31bd9aeb41e7e 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +@@ -1938,7 +1938,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 22c395c7d040b..731bb82b577c2 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +@@ -2631,6 +2631,9 @@ static void __rvu_flr_handler(struct rvu *rvu, u16 pcifunc) + rvu_npc_free_mcam_entries(rvu, pcifunc, -1); + rvu_mac_reset(rvu, pcifunc); + ++ 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 c4d999ef5ab4b..cce2806aaa50c 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +@@ -345,6 +345,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 41df5ac23f927..058f75dc4c8a5 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 c112c71ff576f..4227ebb4a758d 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" +@@ -4389,6 +4390,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. + */ +@@ -4412,6 +4419,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 b42e631e52d0f..18c1c9f361cc6 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h +@@ -437,6 +437,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 9efcec549834e..53f6258a973c2 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +@@ -334,9 +334,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 *) +@@ -344,6 +347,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 532e324bdcc8e..0c17ebdda1487 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +@@ -1688,6 +1688,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; +@@ -1703,6 +1711,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 6ee15f3c25ede..4d519ea833b2c 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +@@ -512,11 +512,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); + } + +@@ -558,16 +565,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); +- } + + if (unlikely(!filled_cnt)) { + struct refill_work *work; +diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +index 060a77f2265d9..e522845c7c211 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +@@ -160,6 +160,18 @@ struct nfp_tun_mac_addr_offload { + u8 addr[ETH_ALEN]; + }; + ++/** ++ * struct nfp_neigh_update_work - update neighbour information to nfp ++ * @work: Work queue for writing neigh to the nfp ++ * @n: neighbour entry ++ * @app: Back pointer to app ++ */ ++struct nfp_neigh_update_work { ++ struct work_struct work; ++ struct neighbour *n; ++ struct nfp_app *app; ++}; ++ + enum nfp_flower_mac_offload_cmd { + NFP_TUNNEL_MAC_OFFLOAD_ADD = 0, + NFP_TUNNEL_MAC_OFFLOAD_DEL = 1, +@@ -607,38 +619,30 @@ err: + nfp_flower_cmsg_warn(app, "Neighbour configuration failed.\n"); + } + +-static int +-nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event, +- void *ptr) ++static void ++nfp_tun_release_neigh_update_work(struct nfp_neigh_update_work *update_work) + { +- struct nfp_flower_priv *app_priv; +- struct netevent_redirect *redir; +- struct neighbour *n; ++ neigh_release(update_work->n); ++ kfree(update_work); ++} ++ ++static void nfp_tun_neigh_update(struct work_struct *work) ++{ ++ struct nfp_neigh_update_work *update_work; + struct nfp_app *app; ++ struct neighbour *n; + bool neigh_invalid; + int err; + +- switch (event) { +- case NETEVENT_REDIRECT: +- redir = (struct netevent_redirect *)ptr; +- n = redir->neigh; +- break; +- case NETEVENT_NEIGH_UPDATE: +- n = (struct neighbour *)ptr; +- break; +- default: +- return NOTIFY_DONE; +- } +- +- neigh_invalid = !(n->nud_state & NUD_VALID) || n->dead; +- +- app_priv = container_of(nb, struct nfp_flower_priv, tun.neigh_nb); +- app = app_priv->app; ++ update_work = container_of(work, struct nfp_neigh_update_work, work); ++ app = update_work->app; ++ n = update_work->n; + + if (!nfp_flower_get_port_id_from_netdev(app, n->dev)) +- return NOTIFY_DONE; ++ goto out; + + #if IS_ENABLED(CONFIG_INET) ++ neigh_invalid = !(n->nud_state & NUD_VALID) || n->dead; + if (n->tbl->family == AF_INET6) { + #if IS_ENABLED(CONFIG_IPV6) + struct flowi6 flow6 = {}; +@@ -655,13 +659,11 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event, + dst = ip6_dst_lookup_flow(dev_net(n->dev), NULL, + &flow6, NULL); + if (IS_ERR(dst)) +- return NOTIFY_DONE; ++ goto out; + + dst_release(dst); + } + nfp_tun_write_neigh(n->dev, app, &flow6, n, true, false); +-#else +- return NOTIFY_DONE; + #endif /* CONFIG_IPV6 */ + } else { + struct flowi4 flow4 = {}; +@@ -678,17 +680,71 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event, + rt = ip_route_output_key(dev_net(n->dev), &flow4); + err = PTR_ERR_OR_ZERO(rt); + if (err) +- return NOTIFY_DONE; ++ goto out; + + ip_rt_put(rt); + } + nfp_tun_write_neigh(n->dev, app, &flow4, n, false, false); + } +-#else +- return NOTIFY_DONE; + #endif /* CONFIG_INET */ ++out: ++ nfp_tun_release_neigh_update_work(update_work); ++} + +- return NOTIFY_OK; ++static struct nfp_neigh_update_work * ++nfp_tun_alloc_neigh_update_work(struct nfp_app *app, struct neighbour *n) ++{ ++ struct nfp_neigh_update_work *update_work; ++ ++ update_work = kzalloc(sizeof(*update_work), GFP_ATOMIC); ++ if (!update_work) ++ return NULL; ++ ++ INIT_WORK(&update_work->work, nfp_tun_neigh_update); ++ neigh_hold(n); ++ update_work->n = n; ++ update_work->app = app; ++ ++ return update_work; ++} ++ ++static int ++nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event, ++ void *ptr) ++{ ++ struct nfp_neigh_update_work *update_work; ++ struct nfp_flower_priv *app_priv; ++ struct netevent_redirect *redir; ++ struct neighbour *n; ++ struct nfp_app *app; ++ ++ switch (event) { ++ case NETEVENT_REDIRECT: ++ redir = (struct netevent_redirect *)ptr; ++ n = redir->neigh; ++ break; ++ case NETEVENT_NEIGH_UPDATE: ++ n = (struct neighbour *)ptr; ++ break; ++ default: ++ return NOTIFY_DONE; ++ } ++#if IS_ENABLED(CONFIG_IPV6) ++ if (n->tbl != ipv6_stub->nd_tbl && n->tbl != &arp_tbl) ++#else ++ if (n->tbl != &arp_tbl) ++#endif ++ return NOTIFY_DONE; ++ ++ app_priv = container_of(nb, struct nfp_flower_priv, tun.neigh_nb); ++ app = app_priv->app; ++ update_work = nfp_tun_alloc_neigh_update_work(app, n); ++ if (!update_work) ++ return NOTIFY_DONE; ++ ++ queue_work(system_highpri_wq, &update_work->work); ++ ++ return NOTIFY_DONE; + } + + void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb) +@@ -706,6 +762,7 @@ void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb) + netdev = nfp_app_dev_get(app, be32_to_cpu(payload->ingress_port), NULL); + if (!netdev) + goto fail_rcu_unlock; ++ dev_hold(netdev); + + flow.daddr = payload->ipv4_addr; + flow.flowi4_proto = IPPROTO_UDP; +@@ -725,13 +782,16 @@ void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb) + ip_rt_put(rt); + if (!n) + goto fail_rcu_unlock; ++ rcu_read_unlock(); ++ + nfp_tun_write_neigh(n->dev, app, &flow, n, false, true); + neigh_release(n); +- rcu_read_unlock(); ++ dev_put(netdev); + return; + + fail_rcu_unlock: + rcu_read_unlock(); ++ dev_put(netdev); + nfp_flower_cmsg_warn(app, "Requested route not found.\n"); + } + +@@ -749,6 +809,7 @@ void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb) + netdev = nfp_app_dev_get(app, be32_to_cpu(payload->ingress_port), NULL); + if (!netdev) + goto fail_rcu_unlock; ++ dev_hold(netdev); + + flow.daddr = payload->ipv6_addr; + flow.flowi6_proto = IPPROTO_UDP; +@@ -766,14 +827,16 @@ void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb) + dst_release(dst); + if (!n) + goto fail_rcu_unlock; ++ rcu_read_unlock(); + + nfp_tun_write_neigh(n->dev, app, &flow, n, true, true); + neigh_release(n); +- rcu_read_unlock(); ++ dev_put(netdev); + return; + + fail_rcu_unlock: + rcu_read_unlock(); ++ dev_put(netdev); + nfp_flower_cmsg_warn(app, "Requested IPv6 route not found.\n"); + } + +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h +index aae4131f146a8..bd2d4a26f5438 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h ++++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h +@@ -222,7 +222,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 2c3e36b2dd7f2..c9bd2c57a37d2 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c +@@ -49,24 +49,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 62cabeeb842a1..bb787a52bc754 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -196,6 +196,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) +@@ -2306,9 +2307,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 453e88b75be08..a74e71db79f94 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +@@ -1484,7 +1484,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 b95d3e1378136..68aa2d5ca6e56 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h ++++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h +@@ -412,9 +412,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 1fa4da96c8f50..69b9c71f0eded 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -964,7 +964,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; +@@ -5803,6 +5804,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); + } + +@@ -7227,6 +7229,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); +@@ -7245,6 +7248,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 */ +@@ -7259,6 +7263,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; +@@ -7719,6 +7724,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 ac41ef4cbd2f0..6ad3e0a119366 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +@@ -1079,6 +1079,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 be18d72cefcce..7611c406fdb96 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -2967,6 +2967,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); +@@ -3296,6 +3298,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; +@@ -3303,6 +3307,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); +@@ -5466,6 +5472,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; +@@ -5480,6 +5488,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); +@@ -5602,6 +5612,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); +@@ -5758,6 +5770,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; +@@ -8364,6 +8378,8 @@ static int rtl8152_pre_reset(struct usb_interface *intf) + struct r8152 *tp = usb_get_intfdata(intf); + struct net_device *netdev; + ++ rtnl_lock(); ++ + if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) + return 0; + +@@ -8395,20 +8411,17 @@ static int rtl8152_post_reset(struct usb_interface *intf) + struct sockaddr sa; + + if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) +- return 0; ++ goto exit; + + rtl_set_accessible(tp); + + /* reset the MAC address in case of policy change */ +- if (determine_ethernet_addr(tp, &sa) >= 0) { +- rtnl_lock(); ++ if (determine_ethernet_addr(tp, &sa) >= 0) + dev_set_mac_address (tp->netdev, &sa, NULL); +- rtnl_unlock(); +- } + + netdev = tp->netdev; + if (!netif_running(netdev)) +- return 0; ++ goto exit; + + set_bit(WORK_ENABLE, &tp->flags); + if (netif_carrier_ok(netdev)) { +@@ -8427,6 +8440,8 @@ static int rtl8152_post_reset(struct usb_interface *intf) + if (!list_empty(&tp->rx_done)) + napi_schedule(&tp->napi); + ++exit: ++ rtnl_unlock(); + return 0; + } + +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index f35647c470afa..74f74b459f5fa 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -156,6 +156,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 3f0c9ee09a12b..5c2a3af26d4de 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2903,6 +2903,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; +@@ -2933,7 +2945,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/nvmem/core.c b/drivers/nvmem/core.c +index eaf6a3fe8ca6d..5b3955ad40534 100644 +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -796,6 +796,12 @@ static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) + if (!layout_np) + return NULL; + ++ /* Fixed layouts don't have a matching driver */ ++ if (of_device_is_compatible(layout_np, "fixed-layout")) { ++ of_node_put(layout_np); ++ return NULL; ++ } ++ + /* + * In case the nvmem device was built-in while the layout was built as a + * module, we shall manually request the layout driver loading otherwise +diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c +index f63250c650caf..3bf27052832f3 100644 +--- a/drivers/of/dynamic.c ++++ b/drivers/of/dynamic.c +@@ -98,8 +98,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 1f236aaf7867a..f33b5d1ddfc16 100644 +--- a/drivers/parport/parport_pc.c ++++ b/drivers/parport/parport_pc.c +@@ -2658,6 +2658,8 @@ enum parport_pc_pci_cards { + asix_ax99100, + quatech_sppxp100, + wch_ch382l, ++ brainboxes_uc146, ++ brainboxes_px203, + }; + + +@@ -2737,6 +2739,8 @@ static struct parport_pc_pci { + /* asix_ax99100 */ { 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[] = { +@@ -2833,6 +2837,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 4ee7bb431b7c0..e278092f889b9 100644 +--- a/drivers/platform/mellanox/mlxbf-bootctl.c ++++ b/drivers/platform/mellanox/mlxbf-bootctl.c +@@ -20,6 +20,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 + +@@ -40,11 +41,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", + }; + + /* Log header format. */ +@@ -247,25 +255,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 2a10705433911..07eea525091b0 100644 +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -263,6 +263,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 +@@ -279,7 +280,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 19bfd30861aa8..9c6321c2fc3c5 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -4437,6 +4437,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); +@@ -4471,6 +4477,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 317c907304149..d75a0ae9cd0c5 100644 +--- a/drivers/platform/x86/wmi.c ++++ b/drivers/platform/x86/wmi.c +@@ -1285,6 +1285,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 e48f14ad6dfd8..06acb5ff609ee 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/scsi/sd.c b/drivers/scsi/sd.c +index e17509f0b3fa8..c2e8d9e27749b 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -1642,24 +1642,21 @@ out: + return disk_changed ? DISK_EVENT_MEDIA_CHANGE : 0; + } + +-static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr) ++static int sd_sync_cache(struct scsi_disk *sdkp) + { + int retries, res; + struct scsi_device *sdp = sdkp->device; + const int timeout = sdp->request_queue->rq_timeout + * SD_FLUSH_TIMEOUT_MULTIPLIER; +- struct scsi_sense_hdr my_sshdr; ++ struct scsi_sense_hdr sshdr; + const struct scsi_exec_args exec_args = { + .req_flags = BLK_MQ_REQ_PM, +- /* caller might not be interested in sense, but we need it */ +- .sshdr = sshdr ? : &my_sshdr, ++ .sshdr = &sshdr, + }; + + if (!scsi_device_online(sdp)) + return -ENODEV; + +- sshdr = exec_args.sshdr; +- + for (retries = 3; retries > 0; --retries) { + unsigned char cmd[16] = { 0 }; + +@@ -1684,15 +1681,23 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr) + return res; + + if (scsi_status_is_check_condition(res) && +- scsi_sense_valid(sshdr)) { +- sd_print_sense_hdr(sdkp, sshdr); ++ scsi_sense_valid(&sshdr)) { ++ sd_print_sense_hdr(sdkp, &sshdr); + + /* we need to evaluate the error return */ +- if (sshdr->asc == 0x3a || /* medium not present */ +- sshdr->asc == 0x20 || /* invalid command */ +- (sshdr->asc == 0x74 && sshdr->ascq == 0x71)) /* drive is password locked */ ++ if (sshdr.asc == 0x3a || /* medium not present */ ++ sshdr.asc == 0x20 || /* invalid command */ ++ (sshdr.asc == 0x74 && sshdr.ascq == 0x71)) /* drive is password locked */ + /* this is no error here */ + return 0; ++ /* ++ * This drive doesn't support sync and there's not much ++ * we can do because this is called during shutdown ++ * or suspend so just return success so those operations ++ * can proceed. ++ */ ++ if (sshdr.sense_key == ILLEGAL_REQUEST) ++ return 0; + } + + switch (host_byte(res)) { +@@ -3847,7 +3852,7 @@ static void sd_shutdown(struct device *dev) + + if (sdkp->WCE && sdkp->media_present) { + sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); +- sd_sync_cache(sdkp, NULL); ++ sd_sync_cache(sdkp); + } + + if ((system_state != SYSTEM_RESTART && +@@ -3868,7 +3873,6 @@ static inline bool sd_do_start_stop(struct scsi_device *sdev, bool runtime) + static int sd_suspend_common(struct device *dev, bool runtime) + { + struct scsi_disk *sdkp = dev_get_drvdata(dev); +- struct scsi_sense_hdr sshdr; + int ret = 0; + + if (!sdkp) /* E.g.: runtime suspend following sd_remove() */ +@@ -3877,24 +3881,13 @@ static int sd_suspend_common(struct device *dev, bool runtime) + if (sdkp->WCE && sdkp->media_present) { + if (!sdkp->device->silence_suspend) + sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); +- ret = sd_sync_cache(sdkp, &sshdr); +- +- if (ret) { +- /* ignore OFFLINE device */ +- if (ret == -ENODEV) +- return 0; +- +- if (!scsi_sense_valid(&sshdr) || +- sshdr.sense_key != ILLEGAL_REQUEST) +- return ret; ++ ret = sd_sync_cache(sdkp); ++ /* ignore OFFLINE device */ ++ if (ret == -ENODEV) ++ return 0; + +- /* +- * sshdr.sense_key == ILLEGAL_REQUEST means this drive +- * doesn't support sync. There's not much to do and +- * suspend shouldn't fail. +- */ +- ret = 0; +- } ++ if (ret) ++ return ret; + } + + if (sd_do_start_stop(sdkp->device, runtime)) { +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 f4cafca1a7dad..a1f2259cc9a98 100644 +--- a/drivers/tty/serial/8250/8250_dw.c ++++ b/drivers/tty/serial/8250/8250_dw.c +@@ -798,6 +798,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 9837a27739fdf..e3f482fd3de48 100644 +--- a/drivers/tty/serial/8250/8250_early.c ++++ b/drivers/tty/serial/8250/8250_early.c +@@ -189,5 +189,6 @@ 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 ca972fd377256..1122f37fe744e 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -914,7 +914,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); +@@ -1060,7 +1060,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); +@@ -1282,10 +1282,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 3dc9b0fcab1c6..cd3913b933c76 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; + }; +@@ -366,32 +368,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); + } + } + +@@ -552,8 +546,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; +@@ -639,18 +633,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/ma35d1_serial.c b/drivers/tty/serial/ma35d1_serial.c +index 465b1def9e119..69da24565b997 100644 +--- a/drivers/tty/serial/ma35d1_serial.c ++++ b/drivers/tty/serial/ma35d1_serial.c +@@ -552,11 +552,19 @@ static void ma35d1serial_console_putchar(struct uart_port *port, unsigned char c + */ + static void ma35d1serial_console_write(struct console *co, const char *s, u32 count) + { +- struct uart_ma35d1_port *up = &ma35d1serial_ports[co->index]; ++ struct uart_ma35d1_port *up; + unsigned long flags; + int locked = 1; + u32 ier; + ++ if ((co->index < 0) || (co->index >= MA35_UART_NR)) { ++ pr_warn("Failed to write on ononsole port %x, out of range\n", ++ co->index); ++ return; ++ } ++ ++ up = &ma35d1serial_ports[co->index]; ++ + if (up->port.sysrq) + locked = 0; + else if (oops_in_progress) +diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c +index f61d98e09dc39..6a0a3208d0900 100644 +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -767,6 +767,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 ea85e2c701a15..3c8a9dd585c09 100644 +--- a/drivers/usb/gadget/function/f_hid.c ++++ b/drivers/usb/gadget/function/f_hid.c +@@ -92,6 +92,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) { + ret = -ENOMEM; + goto err_put_device; +diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c +index 7166d1117742a..781c8338546fd 100644 +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -1635,8 +1635,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); +@@ -1656,6 +1654,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 95ed9404f6f85..d6fc08e5db8fb 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -535,8 +535,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 9c1dbf3c00e0a..6e80fab11788c 100644 +--- a/drivers/usb/typec/class.c ++++ b/drivers/usb/typec/class.c +@@ -266,7 +266,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); +@@ -496,7 +496,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 946488b8989f4..ca972af3c89a2 100644 +--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c ++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c +@@ -2795,13 +2795,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 ea3a7a668b45f..2131638f26d0b 100644 +--- a/fs/smb/client/cifsfs.c ++++ b/fs/smb/client/cifsfs.c +@@ -1196,32 +1196,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); + + /* +@@ -1234,20 +1305,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); +@@ -1263,10 +1377,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"); +@@ -1306,13 +1422,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 b2a60aa6564fd..386b62d5c1332 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/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h +index 536a0b0091c3a..006b5c977ad77 100644 +--- a/include/drm/drm_atomic_helper.h ++++ b/include/drm/drm_atomic_helper.h +@@ -97,6 +97,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, + + int drm_atomic_helper_prepare_planes(struct drm_device *dev, + struct drm_atomic_state *state); ++void drm_atomic_helper_unprepare_planes(struct drm_device *dev, ++ struct drm_atomic_state *state); + + #define DRM_PLANE_COMMIT_ACTIVE_ONLY BIT(0) + #define DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET BIT(1) +diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h +index 28c1d3d77b70f..624d4a38c358a 100644 +--- a/include/linux/cpuhotplug.h ++++ b/include/linux/cpuhotplug.h +@@ -194,6 +194,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/highmem.h b/include/linux/highmem.h +index 99c474de800dd..75607d4ba26cb 100644 +--- a/include/linux/highmem.h ++++ b/include/linux/highmem.h +@@ -454,7 +454,7 @@ static inline void memcpy_from_folio(char *to, struct folio *folio, + memcpy(to, from, chunk); + kunmap_local(from); + +- from += chunk; ++ to += chunk; + offset += chunk; + len -= chunk; + } while (len > 0); +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 47d25a5e1933d..31b2927ada73f 100644 +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -1265,10 +1265,7 @@ static inline bool __vma_shareable_lock(struct vm_area_struct *vma) + return (vma->vm_flags & VM_MAYSHARE) && vma->vm_private_data; + } + +-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); + + /* + * Safe version of huge_pte_offset() to check the locks. See comments +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 26b6f3c81a763..544e1bbfad284 100644 +--- a/include/linux/rethook.h ++++ b/include/linux/rethook.h +@@ -29,7 +29,12 @@ typedef void (*rethook_handler_t) (struct rethook_node *, void *, unsigned long, + */ + 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 *, unsigned long, struct pt_regs *); + struct freelist_head pool; + refcount_t ref; + struct rcu_head rcu; +diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h +index e6fe4f73ffe62..71923ae63b014 100644 +--- a/include/linux/scmi_protocol.h ++++ b/include/linux/scmi_protocol.h +@@ -97,10 +97,17 @@ struct scmi_clk_proto_ops { + u32 clk_id); + }; + ++struct scmi_perf_domain_info { ++ char name[SCMI_MAX_STR_SIZE]; ++ bool set_perf; ++}; ++ + /** + * struct scmi_perf_proto_ops - represents the various operations provided + * by SCMI Performance Protocol + * ++ * @num_domains_get: gets the number of supported performance domains ++ * @info_get: get the information of a performance domain + * @limits_set: sets limits on the performance level of a domain + * @limits_get: gets limits on the performance level of a domain + * @level_set: sets the performance level of a domain +@@ -120,6 +127,9 @@ struct scmi_clk_proto_ops { + * or in some other (abstract) scale + */ + struct scmi_perf_proto_ops { ++ int (*num_domains_get)(const struct scmi_protocol_handle *ph); ++ const struct scmi_perf_domain_info __must_check *(*info_get) ++ (const struct scmi_protocol_handle *ph, u32 domain); + int (*limits_set)(const struct scmi_protocol_handle *ph, u32 domain, + u32 max_perf, u32 min_perf); + int (*limits_get)(const struct scmi_protocol_handle *ph, u32 domain, +diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h +index ce89cc3e49135..e3f7ee169c086 100644 +--- a/include/linux/stmmac.h ++++ b/include/linux/stmmac.h +@@ -174,6 +174,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 e18a4c0d69eed..c53244f204370 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_split_ops; +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 0239e815edf71..a88bf8f6db235 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -1480,17 +1480,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 95896472a82bf..565a850445414 100644 +--- a/include/rdma/ib_umem.h ++++ b/include/rdma/ib_umem.h +@@ -77,6 +77,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--; + } + + /** +@@ -92,7 +99,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 533ab92684d81..62f9d126a71ad 100644 +--- a/include/rdma/ib_verbs.h ++++ b/include/rdma/ib_verbs.h +@@ -2846,6 +2846,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/io_uring/io_uring.c b/io_uring/io_uring.c +index f09e3ee11229c..bb8880d1e084c 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -269,6 +269,7 @@ static __cold void io_fallback_req_func(struct work_struct *work) + struct io_kiocb *req, *tmp; + struct io_tw_state ts = { .locked = true, }; + ++ percpu_ref_get(&ctx->refs); + mutex_lock(&ctx->uring_lock); + llist_for_each_entry_safe(req, tmp, node, io_task_work.node) + req->io_task_work.func(req, &ts); +@@ -276,6 +277,7 @@ static __cold void io_fallback_req_func(struct work_struct *work) + return; + io_submit_flush_completions(ctx); + mutex_unlock(&ctx->uring_lock); ++ percpu_ref_put(&ctx->refs); + } + + static int io_alloc_hash_table(struct io_hash_table *table, unsigned bits) +@@ -3138,12 +3140,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/kbuf.c b/io_uring/kbuf.c +index 012f622036049..e8516f3bbbaaa 100644 +--- a/io_uring/kbuf.c ++++ b/io_uring/kbuf.c +@@ -623,8 +623,8 @@ static int io_alloc_pbuf_ring(struct io_ring_ctx *ctx, + ibf = io_lookup_buf_free_entry(ctx, ring_size); + if (!ibf) { + ptr = io_mem_alloc(ring_size); +- if (!ptr) +- return -ENOMEM; ++ if (IS_ERR(ptr)) ++ return PTR_ERR(ptr); + + /* Allocate and store deferred free entry */ + ibf = kmalloc(sizeof(*ibf), GFP_KERNEL_ACCOUNT); +@@ -743,6 +743,8 @@ void *io_pbuf_get_address(struct io_ring_ctx *ctx, unsigned long bgid) + + bl = __io_buffer_get_list(ctx, smp_load_acquire(&ctx->io_bl), bgid); + ++ if (!bl || !bl->is_mmap) ++ return NULL; + /* + * Ensure the list is fully setup. Only strictly needed for RCU lookup + * via mmap, and in that case only for the array indexed groups. For +@@ -750,8 +752,6 @@ void *io_pbuf_get_address(struct io_ring_ctx *ctx, unsigned long bgid) + */ + if (!smp_load_acquire(&bl->is_ready)) + return NULL; +- if (!bl || !bl->is_mmap) +- return NULL; + + return bl->buf_ring; + } +diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h +index 8625181fb87ac..08ac0d8e07ef8 100644 +--- a/io_uring/rsrc.h ++++ b/io_uring/rsrc.h +@@ -77,17 +77,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/Kconfig.kexec b/kernel/Kconfig.kexec +index 9bfe68fe96762..143f4d8eab7c0 100644 +--- a/kernel/Kconfig.kexec ++++ b/kernel/Kconfig.kexec +@@ -97,7 +97,6 @@ config CRASH_DUMP + depends on ARCH_SUPPORTS_KEXEC + select CRASH_CORE + select KEXEC_CORE +- select KEXEC + help + Generate crash dump after being started by kexec. + This should be normally only set in special crash dump kernels +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index 64fcd81ad3da4..5d1efe5200ba3 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -371,14 +371,18 @@ static int bpf_adj_delta_to_imm(struct bpf_insn *insn, u32 pos, s32 end_old, + static int bpf_adj_delta_to_off(struct bpf_insn *insn, u32 pos, s32 end_old, + s32 end_new, s32 curr, const bool probe_pass) + { +- const s32 off_min = S16_MIN, off_max = S16_MAX; ++ s64 off_min, off_max, off; + s32 delta = end_new - end_old; +- s32 off; + +- if (insn->code == (BPF_JMP32 | BPF_JA)) ++ if (insn->code == (BPF_JMP32 | BPF_JA)) { + off = insn->imm; +- else ++ off_min = S32_MIN; ++ off_max = S32_MAX; ++ } else { + off = insn->off; ++ off_min = S16_MIN; ++ off_max = S16_MAX; ++ } + + if (curr < pos && curr + off + 1 >= end_old) + off += delta; +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 303cb0591b4b1..72e0f5380bf68 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -2109,7 +2109,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", +@@ -2201,6 +2201,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 6dbb03c532375..252387b6ac8d6 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -1814,31 +1814,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) +@@ -1888,8 +1891,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); + } + +@@ -1920,24 +1924,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 0c6185aefaef5..b486504766fb1 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(struct_size(inst, data, rp->data_size), GFP_KERNEL); + if (inst == NULL) { +@@ -2313,7 +2313,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 238262e4aba7e..760793998cdd7 100644 +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -2219,29 +2219,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], +@@ -2252,15 +2245,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 5eb9b598f4e9c..3cebcbaf35a44 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, + correct_ret_addr, regs); +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index 515cafdb18d98..f1ef4329343bf 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -644,8 +644,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 */ +@@ -3030,22 +3030,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 false; + +- /* +- * 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 a40d6baf101f0..b656cab67f67e 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -2359,13 +2359,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; +@@ -2373,119 +2367,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) +@@ -2769,8 +2727,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)); +@@ -2784,10 +2745,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) +@@ -2822,11 +2779,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(); +@@ -2835,17 +2790,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; +@@ -6395,13 +6352,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); +@@ -6426,7 +6385,7 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, + WARN_ON(1); + tracing_disabled = 1; + } +- return ret; ++ goto out_start; + } + + update_buffer_entries(&tr->max_buffer, cpu); +@@ -6435,7 +6394,8 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, + #endif /* CONFIG_TRACER_MAX_TRACE */ + + update_buffer_entries(&tr->array_buffer, cpu); +- ++ out_start: ++ tracing_start_tr(tr); + return ret; + } + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 0f682da96e1c5..e6a95bb74e228 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -1684,9 +1684,6 @@ static int wq_select_unbound_cpu(int cpu) + pr_warn_once("workqueue: round-robin CPU selection forced, expect performance impact\n"); + } + +- if (cpumask_empty(wq_unbound_cpumask)) +- return cpu; +- + new_cpu = __this_cpu_read(wq_rr_cpu_last); + new_cpu = cpumask_next_and(new_cpu, wq_unbound_cpumask, cpu_online_mask); + if (unlikely(new_cpu >= nr_cpu_ids)) { +@@ -6515,6 +6512,17 @@ static inline void wq_watchdog_init(void) { } + + #endif /* CONFIG_WQ_WATCHDOG */ + ++static void __init restrict_unbound_cpumask(const char *name, const struct cpumask *mask) ++{ ++ if (!cpumask_intersects(wq_unbound_cpumask, mask)) { ++ pr_warn("workqueue: Restricting unbound_cpumask (%*pb) with %s (%*pb) leaves no CPU, ignoring\n", ++ cpumask_pr_args(wq_unbound_cpumask), name, cpumask_pr_args(mask)); ++ return; ++ } ++ ++ cpumask_and(wq_unbound_cpumask, wq_unbound_cpumask, mask); ++} ++ + /** + * workqueue_init_early - early init for workqueue subsystem + * +@@ -6534,11 +6542,11 @@ void __init workqueue_init_early(void) + BUILD_BUG_ON(__alignof__(struct pool_workqueue) < __alignof__(long long)); + + BUG_ON(!alloc_cpumask_var(&wq_unbound_cpumask, GFP_KERNEL)); +- cpumask_copy(wq_unbound_cpumask, housekeeping_cpumask(HK_TYPE_WQ)); +- cpumask_and(wq_unbound_cpumask, wq_unbound_cpumask, housekeeping_cpumask(HK_TYPE_DOMAIN)); +- ++ cpumask_copy(wq_unbound_cpumask, cpu_possible_mask); ++ restrict_unbound_cpumask("HK_TYPE_WQ", housekeeping_cpumask(HK_TYPE_WQ)); ++ restrict_unbound_cpumask("HK_TYPE_DOMAIN", housekeeping_cpumask(HK_TYPE_DOMAIN)); + if (!cpumask_empty(&wq_cmdline_cpumask)) +- cpumask_and(wq_unbound_cpumask, wq_unbound_cpumask, &wq_cmdline_cpumask); ++ restrict_unbound_cpumask("workqueue.unbound_cpus", &wq_cmdline_cpumask); + + pwq_cache = KMEM_CACHE(pool_workqueue, SLAB_PANIC); + +diff --git a/lib/group_cpus.c b/lib/group_cpus.c +index aa3f6815bb124..ee272c4cefcc1 100644 +--- a/lib/group_cpus.c ++++ b/lib/group_cpus.c +@@ -366,13 +366,25 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps) + if (!masks) + goto fail_node_to_cpumask; + +- /* Stabilize the cpumasks */ +- cpus_read_lock(); + build_node_to_cpumask(node_to_cpumask); + ++ /* ++ * Make a local cache of 'cpu_present_mask', so the two stages ++ * spread can observe consistent 'cpu_present_mask' without holding ++ * cpu hotplug lock, then we can reduce deadlock risk with cpu ++ * hotplug code. ++ * ++ * Here CPU hotplug may happen when reading `cpu_present_mask`, and ++ * we can live with the case because it only affects that hotplug ++ * CPU is handled in the 1st or 2nd stage, and either way is correct ++ * from API user viewpoint since 2-stage spread is sort of ++ * optimization. ++ */ ++ cpumask_copy(npresmsk, data_race(cpu_present_mask)); ++ + /* grouping present CPUs first */ + ret = __group_cpus_evenly(curgrp, numgrps, node_to_cpumask, +- cpu_present_mask, nmsk, masks); ++ npresmsk, nmsk, masks); + if (ret < 0) + goto fail_build_affinity; + nr_present = ret; +@@ -387,15 +399,13 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps) + curgrp = 0; + else + curgrp = nr_present; +- cpumask_andnot(npresmsk, cpu_possible_mask, cpu_present_mask); ++ cpumask_andnot(npresmsk, cpu_possible_mask, npresmsk); + ret = __group_cpus_evenly(curgrp, numgrps, node_to_cpumask, + npresmsk, nmsk, masks); + if (ret >= 0) + nr_others = ret; + + fail_build_affinity: +- cpus_read_unlock(); +- + if (ret >= 0) + WARN_ON(nr_present + nr_others < numgrps); + +diff --git a/lib/zstd/common/fse_decompress.c b/lib/zstd/common/fse_decompress.c +index a0d06095be83d..8dcb8ca39767c 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 faaef5098e264..b317f51dcc987 100644 +--- a/mm/damon/sysfs.c ++++ b/mm/damon/sysfs.c +@@ -1172,7 +1172,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 f0a15ce1bd1ba..d40a20c9d59f1 100644 +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -3422,7 +3422,7 @@ static bool filemap_map_pmd(struct vm_fault *vmf, struct folio *folio, + } + } + +- if (pmd_none(*vmf->pmd)) ++ if (pmd_none(*vmf->pmd) && vmf->prealloc_pte) + pmd_install(mm, vmf->pmd, &vmf->prealloc_pte); + + return false; +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 5f0adffeceb1d..5e6c4d367d33a 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/mm/memory_hotplug.c b/mm/memory_hotplug.c +index 3b301c4023ffc..144758820e3a3 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1129,6 +1129,9 @@ void mhp_deinit_memmap_on_memory(unsigned long pfn, unsigned long nr_pages) + kasan_remove_zero_shadow(__va(PFN_PHYS(pfn)), PFN_PHYS(nr_pages)); + } + ++/* ++ * Must be called with mem_hotplug_lock in write mode. ++ */ + int __ref online_pages(unsigned long pfn, unsigned long nr_pages, + struct zone *zone, struct memory_group *group) + { +@@ -1149,7 +1152,6 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, + !IS_ALIGNED(pfn + nr_pages, PAGES_PER_SECTION))) + return -EINVAL; + +- mem_hotplug_begin(); + + /* associate pfn range with the zone */ + move_pfn_range_to_zone(zone, pfn, nr_pages, NULL, MIGRATE_ISOLATE); +@@ -1208,7 +1210,6 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, + writeback_set_ratelimit(); + + memory_notify(MEM_ONLINE, &arg); +- mem_hotplug_done(); + return 0; + + failed_addition: +@@ -1217,7 +1218,6 @@ failed_addition: + (((unsigned long long) pfn + nr_pages) << PAGE_SHIFT) - 1); + memory_notify(MEM_CANCEL_ONLINE, &arg); + remove_pfn_range_from_zone(zone, pfn, nr_pages); +- mem_hotplug_done(); + return ret; + } + +@@ -1458,7 +1458,7 @@ int __ref add_memory_resource(int nid, struct resource *res, mhp_t mhp_flags) + /* create memory block devices after memory was added */ + ret = create_memory_block_devices(start, size, params.altmap, group); + if (ret) { +- arch_remove_memory(start, size, NULL); ++ arch_remove_memory(start, size, params.altmap); + goto error_free; + } + +@@ -1863,6 +1863,9 @@ static int count_system_ram_pages_cb(unsigned long start_pfn, + return 0; + } + ++/* ++ * Must be called with mem_hotplug_lock in write mode. ++ */ + int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages, + struct zone *zone, struct memory_group *group) + { +@@ -1885,8 +1888,6 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages, + !IS_ALIGNED(start_pfn + nr_pages, PAGES_PER_SECTION))) + return -EINVAL; + +- mem_hotplug_begin(); +- + /* + * Don't allow to offline memory blocks that contain holes. + * Consequently, memory blocks with holes can never get onlined +@@ -2027,7 +2028,6 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages, + + memory_notify(MEM_OFFLINE, &arg); + remove_pfn_range_from_zone(zone, start_pfn, nr_pages); +- mem_hotplug_done(); + return 0; + + failed_removal_isolated: +@@ -2042,7 +2042,6 @@ failed_removal: + (unsigned long long) start_pfn << PAGE_SHIFT, + ((unsigned long long) end_pfn << PAGE_SHIFT) - 1, + reason); +- mem_hotplug_done(); + return ret; + } + +diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c +index aff31cd944c29..b240d9aae4a64 100644 +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -183,7 +183,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) +@@ -1619,11 +1619,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 b149a165c405c..90fe3e7543833 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2591,6 +2591,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, +@@ -2710,6 +2726,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; +@@ -2846,6 +2863,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; + } +@@ -3014,6 +3032,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 880027ecf5165..7dc47c17d8638 100644 +--- a/net/core/scm.c ++++ b/net/core/scm.c +@@ -26,6 +26,7 @@ + #include <linux/nsproxy.h> + #include <linux/slab.h> + #include <linux/errqueue.h> ++#include <linux/io_uring.h> + + #include <linux/uaccess.h> + +@@ -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 22a26d1d29a09..5169c3c72cffe 100644 +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -635,15 +635,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 3d3a24f795734..ec46d74c20938 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3368,9 +3368,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 1f9d1d445fb3b..e6c4929549428 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -3809,8 +3809,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 28b01a068412a..7772f42ff2b94 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1511,13 +1511,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 35d2f9c9ada02..4c133e06be1de 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 +@@ -1397,6 +1394,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_bpf_link.c b/net/netfilter/nf_bpf_link.c +index e502ec00b2fe1..0e4beae421f83 100644 +--- a/net/netfilter/nf_bpf_link.c ++++ b/net/netfilter/nf_bpf_link.c +@@ -31,7 +31,7 @@ struct bpf_nf_link { + #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) || IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) + static const struct nf_defrag_hook * + get_proto_defrag_hook(struct bpf_nf_link *link, +- const struct nf_defrag_hook __rcu *global_hook, ++ const struct nf_defrag_hook __rcu **ptr_global_hook, + const char *mod) + { + const struct nf_defrag_hook *hook; +@@ -39,7 +39,7 @@ get_proto_defrag_hook(struct bpf_nf_link *link, + + /* RCU protects us from races against module unloading */ + rcu_read_lock(); +- hook = rcu_dereference(global_hook); ++ hook = rcu_dereference(*ptr_global_hook); + if (!hook) { + rcu_read_unlock(); + err = request_module(mod); +@@ -47,7 +47,7 @@ get_proto_defrag_hook(struct bpf_nf_link *link, + return ERR_PTR(err < 0 ? err : -EINVAL); + + rcu_read_lock(); +- hook = rcu_dereference(global_hook); ++ hook = rcu_dereference(*ptr_global_hook); + } + + if (hook && try_module_get(hook->owner)) { +@@ -78,7 +78,7 @@ static int bpf_nf_enable_defrag(struct bpf_nf_link *link) + switch (link->hook_ops.pf) { + #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) + case NFPROTO_IPV4: +- hook = get_proto_defrag_hook(link, nf_defrag_v4_hook, "nf_defrag_ipv4"); ++ hook = get_proto_defrag_hook(link, &nf_defrag_v4_hook, "nf_defrag_ipv4"); + if (IS_ERR(hook)) + return PTR_ERR(hook); + +@@ -87,7 +87,7 @@ static int bpf_nf_enable_defrag(struct bpf_nf_link *link) + #endif + #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) + case NFPROTO_IPV6: +- hook = get_proto_defrag_hook(link, nf_defrag_v6_hook, "nf_defrag_ipv6"); ++ hook = get_proto_defrag_hook(link, &nf_defrag_v6_hook, "nf_defrag_ipv6"); + if (IS_ERR(hook)) + return PTR_ERR(hook); + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 4a450f6d12a59..fb5c62aa8d9ce 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) +@@ -1546,7 +1547,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 5c5cc01c73c5a..629a91a8c6141 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 3fbaa7bf41f9c..6eb571d0c3fdf 100644 +--- a/net/netfilter/nft_exthdr.c ++++ b/net/netfilter/nft_exthdr.c +@@ -214,7 +214,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; +@@ -461,7 +461,7 @@ static void nft_exthdr_dccp_eval(const struct nft_expr *expr, + type = bufp[0]; + + if (type == priv->type) { +- *dest = 1; ++ nft_reg_store8(dest, 1); + return; + } + +diff --git a/net/netfilter/nft_fib.c b/net/netfilter/nft_fib.c +index 04b51f2853321..ca905aa8227e5 100644 +--- a/net/netfilter/nft_fib.c ++++ b/net/netfilter/nft_fib.c +@@ -145,11 +145,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 + strscpy_pad(reg, dev ? dev->name : "", IFNAMSIZ); + break; +diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c +index c0dcc40de358f..3ff31043f7148 100644 +--- a/net/netfilter/nft_set_pipapo.c ++++ b/net/netfilter/nft_set_pipapo.c +@@ -2041,6 +2041,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 8315d31b53db4..d41c4a936ad0c 100644 +--- a/net/netlink/genetlink.c ++++ b/net/netlink/genetlink.c +@@ -1690,6 +1690,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 a84e00b5904be..7adf48549a3b7 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -4300,7 +4300,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) +@@ -4310,7 +4310,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 = { +@@ -4405,7 +4405,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; +@@ -4508,7 +4508,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); +@@ -4526,9 +4526,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); + +@@ -4606,7 +4606,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 63f4865202c13..11ba8a78676ab 100644 +--- a/net/packet/internal.h ++++ b/net/packet/internal.h +@@ -122,7 +122,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/smc/af_smc.c b/net/smc/af_smc.c +index 741339ac94833..ef5b5d498ef3e 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -723,7 +723,7 @@ static void smcd_conn_save_peer_info(struct smc_sock *smc, + int bufsize = smc_uncompress_bufsize(clc->d0.dmbe_size); + + smc->conn.peer_rmbe_idx = clc->d0.dmbe_idx; +- smc->conn.peer_token = clc->d0.token; ++ smc->conn.peer_token = ntohll(clc->d0.token); + /* msg header takes up space in the buffer */ + smc->conn.peer_rmbe_size = bufsize - sizeof(struct smcd_cdc_msg); + atomic_set(&smc->conn.peer_rmbe_space, smc->conn.peer_rmbe_size); +@@ -1415,7 +1415,7 @@ static int smc_connect_ism(struct smc_sock *smc, + if (rc) + return rc; + } +- ini->ism_peer_gid[ini->ism_selected] = aclc->d0.gid; ++ ini->ism_peer_gid[ini->ism_selected] = ntohll(aclc->d0.gid); + + /* there is only one lgr role for SMC-D; use server lock */ + mutex_lock(&smc_server_lgr_pending); +diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c +index 8deb46c28f1d5..72f4d81a3f41f 100644 +--- a/net/smc/smc_clc.c ++++ b/net/smc/smc_clc.c +@@ -1004,6 +1004,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc, + { + struct smc_connection *conn = &smc->conn; + struct smc_clc_first_contact_ext_v2x fce; ++ struct smcd_dev *smcd = conn->lgr->smcd; + struct smc_clc_msg_accept_confirm *clc; + struct smc_clc_fce_gid_ext gle; + struct smc_clc_msg_trail trl; +@@ -1021,17 +1022,15 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc, + memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER, + sizeof(SMCD_EYECATCHER)); + clc->hdr.typev1 = SMC_TYPE_D; +- clc->d0.gid = +- conn->lgr->smcd->ops->get_local_gid(conn->lgr->smcd); +- clc->d0.token = conn->rmb_desc->token; ++ clc->d0.gid = htonll(smcd->ops->get_local_gid(smcd)); ++ clc->d0.token = htonll(conn->rmb_desc->token); + clc->d0.dmbe_size = conn->rmbe_size_comp; + clc->d0.dmbe_idx = 0; + memcpy(&clc->d0.linkid, conn->lgr->id, SMC_LGR_ID_SIZE); + if (version == SMC_V1) { + clc->hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN); + } else { +- clc_v2->d1.chid = +- htons(smc_ism_get_chid(conn->lgr->smcd)); ++ clc_v2->d1.chid = htons(smc_ism_get_chid(smcd)); + if (eid && eid[0]) + memcpy(clc_v2->d1.eid, eid, SMC_MAX_EID_LEN); + len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2; +diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h +index c5c8e7db775a7..08155a96a02a1 100644 +--- a/net/smc/smc_clc.h ++++ b/net/smc/smc_clc.h +@@ -204,8 +204,8 @@ struct smcr_clc_msg_accept_confirm { /* SMCR accept/confirm */ + } __packed; + + struct smcd_clc_msg_accept_confirm_common { /* SMCD accept/confirm */ +- u64 gid; /* Sender GID */ +- u64 token; /* DMB token */ ++ __be64 gid; /* Sender GID */ ++ __be64 token; /* DMB token */ + u8 dmbe_idx; /* DMBE index */ + #if defined(__BIG_ENDIAN_BITFIELD) + u8 dmbe_size : 4, /* buf size (compressed) */ +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index 779815b885e94..27cc0f0a90e1f 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -952,6 +952,8 @@ static int tls_sw_sendmsg_splice(struct sock *sk, struct msghdr *msg, + } + + sk_msg_page_add(msg_pl, page, part, off); ++ msg_pl->sg.copybreak = 0; ++ msg_pl->sg.curr = msg_pl->sg.end; + sk_mem_charge(sk, part); + *copied += part; + try_to_copy -= part; +diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c +index 55f8b9b0e06d1..3515e19852d88 100644 +--- a/net/xdp/xsk.c ++++ b/net/xdp/xsk.c +@@ -919,7 +919,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; + +@@ -931,12 +931,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 84f5fb7f1cecc..ac74f8629ceac 100755 +--- a/scripts/checkstack.pl ++++ b/scripts/checkstack.pl +@@ -139,15 +139,11 @@ $total_size = 0; + while (my $line = <STDIN>) { + 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 9df9f1face832..2f9d0eb59f5b7 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/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c +index 910bd21d08f48..746ff2d272f25 100644 +--- a/scripts/gcc-plugins/randomize_layout_plugin.c ++++ b/scripts/gcc-plugins/randomize_layout_plugin.c +@@ -339,8 +339,7 @@ static int relayout_struct(tree type) + + /* + * enforce that we don't randomize the layout of the last +- * element of a struct if it's a 0 or 1-length array +- * or a proper flexible array ++ * element of a struct if it's a proper flexible array + */ + if (is_flexible_array(newtree[num_fields - 1])) { + has_flexarray = true; +diff --git a/scripts/gdb/linux/device.py b/scripts/gdb/linux/device.py +index 16376c5cfec64..0eabc5f4f8ca2 100644 +--- a/scripts/gdb/linux/device.py ++++ b/scripts/gdb/linux/device.py +@@ -36,26 +36,26 @@ def for_each_bus(): + for kobj in kset_for_each_object(gdb.parse_and_eval('bus_kset')): + subsys = container_of(kobj, kset_type.get_type().pointer(), 'kobj') + subsys_priv = container_of(subsys, subsys_private_type.get_type().pointer(), 'subsys') +- yield subsys_priv['bus'] ++ yield subsys_priv + + + def for_each_class(): + for kobj in kset_for_each_object(gdb.parse_and_eval('class_kset')): + subsys = container_of(kobj, kset_type.get_type().pointer(), 'kobj') + subsys_priv = container_of(subsys, subsys_private_type.get_type().pointer(), 'subsys') +- yield subsys_priv['class'] ++ yield subsys_priv + + + def get_bus_by_name(name): + for item in for_each_bus(): +- if item['name'].string() == name: ++ if item['bus']['name'].string() == name: + return item + raise gdb.GdbError("Can't find bus type {!r}".format(name)) + + + def get_class_by_name(name): + for item in for_each_class(): +- if item['name'].string() == name: ++ if item['class']['name'].string() == name: + return item + raise gdb.GdbError("Can't find device class {!r}".format(name)) + +@@ -70,13 +70,13 @@ def klist_for_each(klist): + + + def bus_for_each_device(bus): +- for kn in klist_for_each(bus['p']['klist_devices']): ++ for kn in klist_for_each(bus['klist_devices']): + dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_bus') + yield dp['device'] + + + def class_for_each_device(cls): +- for kn in klist_for_each(cls['p']['klist_devices']): ++ for kn in klist_for_each(cls['klist_devices']): + dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_class') + yield dp['device'] + +@@ -103,7 +103,7 @@ class LxDeviceListBus(gdb.Command): + def invoke(self, arg, from_tty): + if not arg: + for bus in for_each_bus(): +- gdb.write('bus {}:\t{}\n'.format(bus['name'].string(), bus)) ++ gdb.write('bus {}:\t{}\n'.format(bus['bus']['name'].string(), bus)) + for dev in bus_for_each_device(bus): + _show_device(dev, level=1) + else: +@@ -123,7 +123,7 @@ class LxDeviceListClass(gdb.Command): + def invoke(self, arg, from_tty): + if not arg: + for cls in for_each_class(): +- gdb.write("class {}:\t{}\n".format(cls['name'].string(), cls)) ++ gdb.write("class {}:\t{}\n".format(cls['class']['name'].string(), cls)) + for dev in class_for_each_device(cls): + _show_device(dev, level=1) + else: +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/scripts/mod/modpost.c b/scripts/mod/modpost.c +index b3dee80497cb2..ac4ef3e206bbd 100644 +--- a/scripts/mod/modpost.c ++++ b/scripts/mod/modpost.c +@@ -1496,13 +1496,15 @@ static void section_rela(struct module *mod, struct elf_info *elf, + return; + + for (rela = start; rela < stop; rela++) { ++ Elf_Sym *tsym; + Elf_Addr taddr, r_offset; + unsigned int r_type, r_sym; + + r_offset = TO_NATIVE(rela->r_offset); + get_rel_type_and_sym(elf, rela->r_info, &r_type, &r_sym); + +- taddr = TO_NATIVE(rela->r_addend); ++ tsym = elf->symtab_start + r_sym; ++ taddr = tsym->st_value + TO_NATIVE(rela->r_addend); + + switch (elf->hdr->e_machine) { + case EM_RISCV: +@@ -1517,7 +1519,7 @@ static void section_rela(struct module *mod, struct elf_info *elf, + break; + } + +- check_section_mismatch(mod, elf, elf->symtab_start + r_sym, ++ check_section_mismatch(mod, elf, tsym, + fsecndx, fromsec, r_offset, taddr); + } + } +diff --git a/sound/core/pcm.c b/sound/core/pcm.c +index 20bb2d7c8d4bf..6d0c9c37796c2 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 758abe9dffd6d..5c609c1150c42 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9615,6 +9615,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK), + SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS), + SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS), ++ SND_PCI_QUIRK(0x1028, 0x0beb, "Dell XPS 15 9530 (2023)", ALC289_FIXUP_DELL_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1028, 0x0c03, "Dell Precision 5340", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS), + SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS), +@@ -9873,6 +9874,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x17f3, "ROG Ally RC71L_RC71L", ALC294_FIXUP_ASUS_ALLY), + SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS), + SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS UM3504DA", ALC294_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE), + SND_PCI_QUIRK(0x1043, 0x1970, "ASUS UX550VE", ALC289_FIXUP_ASUS_GA401), +@@ -10114,6 +10116,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x17aa, 0x3881, "YB9 dual power mode2 YC", ALC287_FIXUP_TAS2781_I2C), ++ SND_PCI_QUIRK(0x17aa, 0x3882, "Lenovo Yoga Pro 7 14APH8", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), + SND_PCI_QUIRK(0x17aa, 0x3884, "Y780 YG DUAL", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C), +@@ -10180,6 +10183,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. +@@ -12105,6 +12110,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 15a864dcd7bd3..3babb17a56bb5 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 3e33418898e82..ebddfa74ce0a0 100644 +--- a/sound/soc/codecs/lpass-tx-macro.c ++++ b/sound/soc/codecs/lpass-tx-macro.c +@@ -2021,6 +2021,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 d1b9238d391e8..cb654f1b09f10 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -1451,12 +1451,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; + +@@ -1467,6 +1467,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 8a9a30dd31e20..3252eefc4bc0e 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/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c +index 14d9fea33d16a..c61cad0180c87 100644 +--- a/sound/soc/qcom/sc8280xp.c ++++ b/sound/soc/qcom/sc8280xp.c +@@ -27,6 +27,23 @@ struct sc8280xp_snd_data { + static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd) + { + struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card); ++ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); ++ struct snd_soc_card *card = rtd->card; ++ ++ switch (cpu_dai->id) { ++ case WSA_CODEC_DMA_RX_0: ++ case WSA_CODEC_DMA_RX_1: ++ /* ++ * set limit of 0dB on Digital Volume for Speakers, ++ * this can prevent damage of speakers to some extent without ++ * active speaker protection ++ */ ++ snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 84); ++ snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 84); ++ break; ++ default: ++ break; ++ } + + return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup); + } +diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c +index 55b009d3c6815..2d25748ca7066 100644 +--- a/sound/soc/soc-ops.c ++++ b/sound/soc/soc-ops.c +@@ -661,7 +661,7 @@ int snd_soc_limit_volume(struct snd_soc_card *card, + kctl = snd_soc_card_get_kcontrol(card, name); + if (kctl) { + struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; +- if (max <= mc->max) { ++ if (max <= mc->max - mc->min) { + mc->platform_max = max; + ret = 0; + } +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/tools/perf/builtin-list.c b/tools/perf/builtin-list.c +index a343823c8ddfc..61c2c96cc0701 100644 +--- a/tools/perf/builtin-list.c ++++ b/tools/perf/builtin-list.c +@@ -434,6 +434,11 @@ static void json_print_metric(void *ps __maybe_unused, const char *group, + strbuf_release(&buf); + } + ++static bool json_skip_duplicate_pmus(void *ps __maybe_unused) ++{ ++ return false; ++} ++ + static bool default_skip_duplicate_pmus(void *ps) + { + struct print_state *print_state = ps; +@@ -503,6 +508,7 @@ int cmd_list(int argc, const char **argv) + .print_end = json_print_end, + .print_event = json_print_event, + .print_metric = json_print_metric, ++ .skip_duplicate_pmus = json_skip_duplicate_pmus, + }; + ps = &json_ps; + } else { +diff --git a/tools/perf/pmu-events/arch/arm64/ampere/ampereone/metrics.json b/tools/perf/pmu-events/arch/arm64/ampere/ampereone/metrics.json +index e2848a9d48487..afcdad58ef89c 100644 +--- a/tools/perf/pmu-events/arch/arm64/ampere/ampereone/metrics.json ++++ b/tools/perf/pmu-events/arch/arm64/ampere/ampereone/metrics.json +@@ -231,6 +231,7 @@ + "MetricName": "slots_lost_misspeculation_fraction", + "MetricExpr": "100 * ((OP_SPEC - OP_RETIRED) / (CPU_CYCLES * #slots))", + "BriefDescription": "Fraction of slots lost due to misspeculation", ++ "DefaultMetricgroupName": "TopdownL1", + "MetricGroup": "Default;TopdownL1", + "ScaleUnit": "1percent of slots" + }, +@@ -238,6 +239,7 @@ + "MetricName": "retired_fraction", + "MetricExpr": "100 * (OP_RETIRED / (CPU_CYCLES * #slots))", + "BriefDescription": "Fraction of slots retiring, useful work", ++ "DefaultMetricgroupName": "TopdownL1", + "MetricGroup": "Default;TopdownL1", + "ScaleUnit": "1percent of slots" + }, +diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c +index 6231044a491e2..bb5faaa25d510 100644 +--- a/tools/perf/util/metricgroup.c ++++ b/tools/perf/util/metricgroup.c +@@ -225,7 +225,7 @@ static struct metric *metric__new(const struct pmu_metric *pm, + + m->pmu = pm->pmu ?: "cpu"; + m->metric_name = pm->metric_name; +- m->default_metricgroup_name = pm->default_metricgroup_name; ++ m->default_metricgroup_name = pm->default_metricgroup_name ?: ""; + m->modifier = NULL; + if (modifier) { + m->modifier = strdup(modifier); |